mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2025-07-23 12:51:40 +02:00
Merge branch 'master' into 97_107_mark_and_show_shared
This commit is contained in:
712
web/frontend/package-lock.json
generated
Normal file
712
web/frontend/package-lock.json
generated
Normal file
@@ -0,0 +1,712 @@
|
||||
{
|
||||
"name": "cc-frontend",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "cc-frontend",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rollup/plugin-replace": "^5.0.2",
|
||||
"@urql/svelte": "^4.0.1",
|
||||
"graphql": "^16.6.0",
|
||||
"sveltestrap": "^5.10.0",
|
||||
"uplot": "^1.6.24",
|
||||
"wonka": "^6.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^24.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.0.2",
|
||||
"@rollup/plugin-terser": "^0.4.1",
|
||||
"rollup": "^3.21.0",
|
||||
"rollup-plugin-css-only": "^4.3.0",
|
||||
"rollup-plugin-svelte": "^7.1.4",
|
||||
"svelte": "^3.58.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@0no-co/graphql.web": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.0.1.tgz",
|
||||
"integrity": "sha512-6Yaxyv6rOwRkLIvFaL0NrLDgfNqC/Ng9QOPmTmlqW4mORXMEKmh5NYGkIvvt5Yw8fZesnMAqkj8cIqTj8f40cQ==",
|
||||
"peerDependencies": {
|
||||
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"graphql": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/gen-mapping": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
|
||||
"integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/set-array": "^1.0.1",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10",
|
||||
"@jridgewell/trace-mapping": "^0.3.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/resolve-uri": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
|
||||
"integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/set-array": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
|
||||
"integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/source-map": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
|
||||
"integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/gen-mapping": "^0.3.0",
|
||||
"@jridgewell/trace-mapping": "^0.3.9"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.4.14",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
|
||||
"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.14",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz",
|
||||
"integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.0.3",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@popperjs/core": {
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.0.tgz",
|
||||
"integrity": "sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ==",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/popperjs"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-commonjs": {
|
||||
"version": "24.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.1.0.tgz",
|
||||
"integrity": "sha512-eSL45hjhCWI0jCCXcNtLVqM5N1JlBGvlFfY0m6oOYnLCJ6N0qEXoZql4sY2MOUArzhH4SA/qBpTxvvZp2Sc+DQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "^5.0.1",
|
||||
"commondir": "^1.0.1",
|
||||
"estree-walker": "^2.0.2",
|
||||
"glob": "^8.0.3",
|
||||
"is-reference": "1.2.1",
|
||||
"magic-string": "^0.27.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^2.68.0||^3.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-node-resolve": {
|
||||
"version": "15.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.2.tgz",
|
||||
"integrity": "sha512-Y35fRGUjC3FaurG722uhUuG8YHOJRJQbI6/CkbRkdPotSpDj9NtIN85z1zrcyDcCQIW4qp5mgG72U+gJ0TAFEg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "^5.0.1",
|
||||
"@types/resolve": "1.20.2",
|
||||
"deepmerge": "^4.2.2",
|
||||
"is-builtin-module": "^3.2.1",
|
||||
"is-module": "^1.0.0",
|
||||
"resolve": "^1.22.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^2.78.0||^3.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-replace": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.2.tgz",
|
||||
"integrity": "sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==",
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "^5.0.1",
|
||||
"magic-string": "^0.27.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^1.20.0||^2.0.0||^3.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-terser": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.1.tgz",
|
||||
"integrity": "sha512-aKS32sw5a7hy+fEXVy+5T95aDIwjpGHCTv833HXVtyKMDoVS7pBr5K3L9hEQoNqbJFjfANPrNpIXlTQ7is00eA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"serialize-javascript": "^6.0.0",
|
||||
"smob": "^0.0.6",
|
||||
"terser": "^5.15.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^2.x || ^3.x"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-terser/node_modules/serialize-javascript": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz",
|
||||
"integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"randombytes": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/pluginutils": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz",
|
||||
"integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==",
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"picomatch": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^1.20.0||^2.0.0||^3.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
|
||||
"integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA=="
|
||||
},
|
||||
"node_modules/@types/resolve": {
|
||||
"version": "1.20.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
|
||||
"integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@urql/core": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@urql/core/-/core-4.0.7.tgz",
|
||||
"integrity": "sha512-UtZ9oSbSFODXzFydgLCXpAQz26KGT1d6uEfcylKphiRWNXSWZi8k7vhJXNceNm/Dn0MiZ+kaaJHKcnGY1jvHRQ==",
|
||||
"dependencies": {
|
||||
"@0no-co/graphql.web": "^1.0.1",
|
||||
"wonka": "^6.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@urql/svelte": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@urql/svelte/-/svelte-4.0.1.tgz",
|
||||
"integrity": "sha512-WbsVjuK7IUNlJlvXAgevjQunoso0T+AngFlb0zafDvay6HN47Zc3CSVbAlP8KjETjERUMJLuiqknmPFFm2GEFQ==",
|
||||
"dependencies": {
|
||||
"@urql/core": "^4.0.0",
|
||||
"wonka": "^6.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"svelte": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.8.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
|
||||
"integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/builtin-modules": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
|
||||
"integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/commondir": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
|
||||
"integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/deepmerge": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
|
||||
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
|
||||
"integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^5.0.1",
|
||||
"once": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/graphql": {
|
||||
"version": "16.6.0",
|
||||
"resolved": "https://registry.npmjs.org/graphql/-/graphql-16.6.0.tgz",
|
||||
"integrity": "sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw==",
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/has": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/is-builtin-module": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz",
|
||||
"integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"builtin-modules": "^3.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-core-module": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz",
|
||||
"integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has": "^1.0.3"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-module": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
|
||||
"integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE= sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/is-reference": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
|
||||
"integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/estree": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/magic-string": {
|
||||
"version": "0.27.0",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz",
|
||||
"integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==",
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.4.13"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
|
||||
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/path-parse": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/randombytes": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.2",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
|
||||
"integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-core-module": "^2.11.0",
|
||||
"path-parse": "^1.0.7",
|
||||
"supports-preserve-symlinks-flag": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"resolve": "bin/resolve"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve.exports": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz",
|
||||
"integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "3.21.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.21.0.tgz",
|
||||
"integrity": "sha512-ANPhVcyeHvYdQMUyCbczy33nbLzI7RzrBje4uvNiTDJGIMtlKoOStmympwr9OtS1LZxiDmE2wvxHyVhoLtf1KQ==",
|
||||
"devOptional": true,
|
||||
"bin": {
|
||||
"rollup": "dist/bin/rollup"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.18.0",
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup-plugin-css-only": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup-plugin-css-only/-/rollup-plugin-css-only-4.3.0.tgz",
|
||||
"integrity": "sha512-BsiCqJJQzZh2lQiHY5irejRoJ3I1EUFHEi5PjVqsr+EmOh54YrWVwd3YZEXnQJ2+fzlhif0YM/Kf0GuH90GAdQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "<4"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup-plugin-svelte": {
|
||||
"version": "7.1.4",
|
||||
"resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-7.1.4.tgz",
|
||||
"integrity": "sha512-Jm0FCydR7k8bBGe7wimXAes8x2zEK10Ew3f3lEZwYor/Zya3X0AZVeSAPRH7yiXB9hWQVzJu597EUeNwGDTdjQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "^4.1.0",
|
||||
"resolve.exports": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": ">=2.0.0",
|
||||
"svelte": ">=3.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup-plugin-svelte/node_modules/@rollup/pluginutils": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz",
|
||||
"integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"estree-walker": "^2.0.1",
|
||||
"picomatch": "^2.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/smob": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/smob/-/smob-0.0.6.tgz",
|
||||
"integrity": "sha512-V21+XeNni+tTyiST1MHsa84AQhT1aFZipzPpOFAVB8DkHzwJyjjAmt9bgwnuZiZWnIbMo2duE29wybxv/7HWUw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-support": {
|
||||
"version": "0.5.21",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
|
||||
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-preserve-symlinks-flag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte": {
|
||||
"version": "3.58.0",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.58.0.tgz",
|
||||
"integrity": "sha512-brIBNNB76mXFmU/Kerm4wFnkskBbluBDCjx/8TcpYRb298Yh2dztS2kQ6bhtjMcvUhd5ynClfwpz5h2gnzdQ1A==",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/sveltestrap": {
|
||||
"version": "5.10.0",
|
||||
"resolved": "https://registry.npmjs.org/sveltestrap/-/sveltestrap-5.10.0.tgz",
|
||||
"integrity": "sha512-k6Ob+6G2AMYvBidXHBKM9W28fJqFHbmosqCe/NC8pv6TV7K+v47Yw+zmnLWkjqCzzmjkSLkL48SrHZrlWc9mYQ==",
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.9.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"svelte": "^3.29.0"
|
||||
}
|
||||
},
|
||||
"node_modules/terser": {
|
||||
"version": "5.17.1",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz",
|
||||
"integrity": "sha512-hVl35zClmpisy6oaoKALOpS0rDYLxRFLHhRuDlEGTKey9qHjS1w9GMORjuwIMt70Wan4lwsLYyWDVnWgF+KUEw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/source-map": "^0.3.2",
|
||||
"acorn": "^8.5.0",
|
||||
"commander": "^2.20.0",
|
||||
"source-map-support": "~0.5.20"
|
||||
},
|
||||
"bin": {
|
||||
"terser": "bin/terser"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/uplot": {
|
||||
"version": "1.6.24",
|
||||
"resolved": "https://registry.npmjs.org/uplot/-/uplot-1.6.24.tgz",
|
||||
"integrity": "sha512-WpH2BsrFrqxkMu+4XBvc0eCDsRBhzoq9crttYeSI0bfxpzR5YoSVzZXOKFVWcVC7sp/aDXrdDPbDZGCtck2PVg=="
|
||||
},
|
||||
"node_modules/wonka": {
|
||||
"version": "6.3.2",
|
||||
"resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.2.tgz",
|
||||
"integrity": "sha512-2xXbQ1LnwNS7egVm1HPhW2FyKrekolzhpM3mCwXdQr55gO+tAiY76rhb32OL9kKsW8taj++iP7C6hxlVzbnvrw=="
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
@@ -7,20 +7,20 @@
|
||||
"dev": "rollup -c -w"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^17.0.0",
|
||||
"@rollup/plugin-node-resolve": "^11.0.0",
|
||||
"rollup": "^2.3.4",
|
||||
"rollup-plugin-css-only": "^3.1.0",
|
||||
"rollup-plugin-svelte": "^7.0.0",
|
||||
"rollup-plugin-terser": "^7.0.0",
|
||||
"svelte": "^3.49.0"
|
||||
"@rollup/plugin-commonjs": "^24.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.0.2",
|
||||
"@rollup/plugin-terser": "^0.4.1",
|
||||
"rollup": "^3.21.0",
|
||||
"rollup-plugin-css-only": "^4.3.0",
|
||||
"rollup-plugin-svelte": "^7.1.4",
|
||||
"svelte": "^3.58.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@rollup/plugin-replace": "^2.4.1",
|
||||
"@urql/svelte": "^1.3.0",
|
||||
"graphql": "^15.6.0",
|
||||
"sveltestrap": "^5.6.1",
|
||||
"uplot": "^1.6.7",
|
||||
"wonka": "^4.0.15"
|
||||
"@rollup/plugin-replace": "^5.0.2",
|
||||
"@urql/svelte": "^4.0.1",
|
||||
"graphql": "^16.6.0",
|
||||
"sveltestrap": "^5.10.0",
|
||||
"uplot": "^1.6.24",
|
||||
"wonka": "^6.3.2"
|
||||
}
|
||||
}
|
||||
|
@@ -1,71 +0,0 @@
|
||||
import svelte from 'rollup-plugin-svelte';
|
||||
import replace from "@rollup/plugin-replace";
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import resolve from '@rollup/plugin-node-resolve';
|
||||
import { terser } from 'rollup-plugin-terser';
|
||||
import css from 'rollup-plugin-css-only';
|
||||
|
||||
// const production = !process.env.ROLLUP_WATCH;
|
||||
const production = true
|
||||
|
||||
const plugins = [
|
||||
svelte({
|
||||
compilerOptions: {
|
||||
// enable run-time checks when not in production
|
||||
dev: !production
|
||||
}
|
||||
}),
|
||||
|
||||
// If you have external dependencies installed from
|
||||
// npm, you'll most likely need these plugins. In
|
||||
// some cases you'll need additional configuration -
|
||||
// consult the documentation for details:
|
||||
// https://github.com/rollup/plugins/tree/master/packages/commonjs
|
||||
resolve({
|
||||
browser: true,
|
||||
dedupe: ['svelte']
|
||||
}),
|
||||
commonjs(),
|
||||
|
||||
// If we're building for production (npm run build
|
||||
// instead of npm run dev), minify
|
||||
production && terser(),
|
||||
|
||||
replace({
|
||||
"process.env.NODE_ENV": JSON.stringify("development"),
|
||||
preventAssignment: true
|
||||
})
|
||||
];
|
||||
|
||||
const entrypoint = (name, path) => ({
|
||||
input: path,
|
||||
output: {
|
||||
sourcemap: false,
|
||||
format: 'iife',
|
||||
name: 'app',
|
||||
file: `public/build/${name}.js`
|
||||
},
|
||||
plugins: [
|
||||
...plugins,
|
||||
|
||||
// we'll extract any component CSS out into
|
||||
// a separate file - better for performance
|
||||
css({ output: `${name}.css` }),
|
||||
],
|
||||
watch: {
|
||||
clearScreen: false
|
||||
}
|
||||
});
|
||||
|
||||
export default [
|
||||
entrypoint('header', 'src/header.entrypoint.js'),
|
||||
entrypoint('jobs', 'src/jobs.entrypoint.js'),
|
||||
entrypoint('user', 'src/user.entrypoint.js'),
|
||||
entrypoint('list', 'src/list.entrypoint.js'),
|
||||
entrypoint('job', 'src/job.entrypoint.js'),
|
||||
entrypoint('systems', 'src/systems.entrypoint.js'),
|
||||
entrypoint('node', 'src/node.entrypoint.js'),
|
||||
entrypoint('analysis', 'src/analysis.entrypoint.js'),
|
||||
entrypoint('status', 'src/status.entrypoint.js'),
|
||||
entrypoint('config', 'src/config.entrypoint.js')
|
||||
];
|
71
web/frontend/rollup.config.mjs
Normal file
71
web/frontend/rollup.config.mjs
Normal file
@@ -0,0 +1,71 @@
|
||||
import svelte from 'rollup-plugin-svelte';
|
||||
import replace from "@rollup/plugin-replace";
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import resolve from '@rollup/plugin-node-resolve';
|
||||
import terser from '@rollup/plugin-terser';
|
||||
import css from 'rollup-plugin-css-only';
|
||||
|
||||
const production = !process.env.ROLLUP_WATCH;
|
||||
// const production = false
|
||||
|
||||
const plugins = [
|
||||
svelte({
|
||||
compilerOptions: {
|
||||
// enable run-time checks when not in production
|
||||
dev: !production
|
||||
}
|
||||
}),
|
||||
|
||||
// If you have external dependencies installed from
|
||||
// npm, you'll most likely need these plugins. In
|
||||
// some cases you'll need additional configuration -
|
||||
// consult the documentation for details:
|
||||
// https://github.com/rollup/plugins/tree/master/packages/commonjs
|
||||
resolve({
|
||||
browser: true,
|
||||
dedupe: ['svelte']
|
||||
}),
|
||||
commonjs(),
|
||||
|
||||
// If we're building for production (npm run build
|
||||
// instead of npm run dev), minify
|
||||
production && terser(),
|
||||
|
||||
replace({
|
||||
"process.env.NODE_ENV": JSON.stringify("development"),
|
||||
preventAssignment: true
|
||||
})
|
||||
];
|
||||
|
||||
const entrypoint = (name, path) => ({
|
||||
input: path,
|
||||
output: {
|
||||
sourcemap: false,
|
||||
format: 'iife',
|
||||
name: 'app',
|
||||
file: `public/build/${name}.js`
|
||||
},
|
||||
plugins: [
|
||||
...plugins,
|
||||
|
||||
// we'll extract any component CSS out into
|
||||
// a separate file - better for performance
|
||||
css({ output: `${name}.css` }),
|
||||
],
|
||||
watch: {
|
||||
clearScreen: false
|
||||
}
|
||||
});
|
||||
|
||||
export default [
|
||||
entrypoint('header', 'src/header.entrypoint.js'),
|
||||
entrypoint('jobs', 'src/jobs.entrypoint.js'),
|
||||
entrypoint('user', 'src/user.entrypoint.js'),
|
||||
entrypoint('list', 'src/list.entrypoint.js'),
|
||||
entrypoint('job', 'src/job.entrypoint.js'),
|
||||
entrypoint('systems', 'src/systems.entrypoint.js'),
|
||||
entrypoint('node', 'src/node.entrypoint.js'),
|
||||
entrypoint('analysis', 'src/analysis.entrypoint.js'),
|
||||
entrypoint('status', 'src/status.entrypoint.js'),
|
||||
entrypoint('config', 'src/config.entrypoint.js')
|
||||
];
|
@@ -1,7 +1,7 @@
|
||||
<script>
|
||||
import { init } from './utils.js'
|
||||
import { getContext, onMount } from 'svelte'
|
||||
import { operationStore, query } from '@urql/svelte'
|
||||
import { queryStore, gql, getContextClient } from '@urql/svelte'
|
||||
import { Row, Col, Spinner, Card, Table } from 'sveltestrap'
|
||||
import Filters from './filters/Filters.svelte'
|
||||
import PlotSelection from './PlotSelection.svelte'
|
||||
@@ -30,6 +30,7 @@
|
||||
let rooflineMaxY
|
||||
let colWidth
|
||||
let numBins = 50
|
||||
let maxY = -1
|
||||
const ccconfig = getContext('cc-config')
|
||||
const metricConfig = getContext('metrics')
|
||||
|
||||
@@ -44,52 +45,55 @@
|
||||
console.assert(cluster != null, `This cluster could not be found: ${filterPresets.cluster}`)
|
||||
|
||||
rooflineMaxY = cluster.subClusters.reduce((max, part) => Math.max(max, part.flopRateSimd.value), 0)
|
||||
$rooflineQuery.variables.maxY = rooflineMaxY
|
||||
$rooflineQuery.context.pause = false
|
||||
$rooflineQuery.reexecute()
|
||||
maxY = rooflineMaxY
|
||||
}
|
||||
})
|
||||
|
||||
const statsQuery = operationStore(`
|
||||
query($filter: [JobFilter!]!) {
|
||||
stats: jobsStatistics(filter: $filter) {
|
||||
totalJobs
|
||||
shortJobs
|
||||
totalWalltime
|
||||
totalCoreHours
|
||||
histDuration { count, value }
|
||||
histNumNodes { count, value }
|
||||
const client = getContextClient();
|
||||
|
||||
$: statsQuery = queryStore({
|
||||
client: client,
|
||||
query: gql`
|
||||
query($filters: [JobFilter!]!) {
|
||||
stats: jobsStatistics(filter: $filters) {
|
||||
totalJobs
|
||||
shortJobs
|
||||
totalWalltime
|
||||
totalCoreHours
|
||||
histDuration { count, value }
|
||||
histNumNodes { count, value }
|
||||
}
|
||||
|
||||
topUsers: jobsCount(filter: $filters, groupBy: USER, weight: NODE_HOURS, limit: 5) { name, count }
|
||||
}
|
||||
`,
|
||||
variables: { filters }
|
||||
})
|
||||
|
||||
topUsers: jobsCount(filter: $filter, groupBy: USER, weight: NODE_HOURS, limit: 5) { name, count }
|
||||
}
|
||||
`, { filter: [] }, { pause: true })
|
||||
$: footprintsQuery = queryStore({
|
||||
client: client,
|
||||
query: gql`
|
||||
query($filters: [JobFilter!]!, $metrics: [String!]!) {
|
||||
footprints: jobsFootprints(filter: $filters, metrics: $metrics) {
|
||||
nodehours,
|
||||
metrics { metric, data }
|
||||
}
|
||||
}`,
|
||||
variables: { filters, metrics }
|
||||
})
|
||||
|
||||
const footprintsQuery = operationStore(`
|
||||
query($filter: [JobFilter!]!, $metrics: [String!]!) {
|
||||
footprints: jobsFootprints(filter: $filter, metrics: $metrics) {
|
||||
nodehours,
|
||||
metrics { metric, data }
|
||||
$: rooflineQuery = queryStore({
|
||||
client: client,
|
||||
query: gql`
|
||||
query($filters: [JobFilter!]!, $rows: Int!, $cols: Int!,
|
||||
$minX: Float!, $minY: Float!, $maxX: Float!, $maxY: Float!) {
|
||||
rooflineHeatmap(filter: $filters, rows: $rows, cols: $cols,
|
||||
minX: $minX, minY: $minY, maxX: $maxX, maxY: $maxY)
|
||||
}
|
||||
}
|
||||
`, { filter: [], metrics }, { pause: true })
|
||||
$: $footprintsQuery.variables = { ...$footprintsQuery.variables, metrics }
|
||||
`,
|
||||
variables: { filters, rows: 50, cols: 50, minX: 0.01, minY: 1., maxX: 1000., maxY }
|
||||
})
|
||||
|
||||
const rooflineQuery = operationStore(`
|
||||
query($filter: [JobFilter!]!, $rows: Int!, $cols: Int!,
|
||||
$minX: Float!, $minY: Float!, $maxX: Float!, $maxY: Float!) {
|
||||
rooflineHeatmap(filter: $filter, rows: $rows, cols: $cols,
|
||||
minX: $minX, minY: $minY, maxX: $maxX, maxY: $maxY)
|
||||
}
|
||||
`, {
|
||||
filter: [],
|
||||
rows: 50, cols: 50,
|
||||
minX: 0.01, minY: 1., maxX: 1000., maxY: -1.
|
||||
}, { pause: true });
|
||||
|
||||
query(statsQuery)
|
||||
query(footprintsQuery)
|
||||
query(rooflineQuery)
|
||||
onMount(() => filters.update())
|
||||
</script>
|
||||
|
||||
@@ -116,11 +120,7 @@
|
||||
disableClusterSelection={true}
|
||||
startTimeQuickSelect={true}
|
||||
on:update={({ detail }) => {
|
||||
$statsQuery.context.pause = false
|
||||
$statsQuery.variables = { filter: detail.filters }
|
||||
$footprintsQuery.context.pause = false
|
||||
$footprintsQuery.variables = { metrics, filter: detail.filters }
|
||||
$rooflineQuery.variables = { ...$rooflineQuery.variables, filter: detail.filters }
|
||||
filters = detail.filters;
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
|
@@ -134,8 +134,8 @@
|
||||
cluster={clusters
|
||||
.find(c => c.name == $initq.data.job.cluster).subClusters
|
||||
.find(sc => sc.name == $initq.data.job.subCluster)}
|
||||
flopsAny={$jobMetrics.data.jobMetrics.find(m => m.name == 'flops_any' && m.scope == 'node').metric}
|
||||
memBw={$jobMetrics.data.jobMetrics.find(m => m.name == 'mem_bw' && m.scope == 'node').metric} />
|
||||
flopsAny={$jobMetrics.data.jobMetrics.find(m => m.name == 'flops_any' && m.scope == 'node')}
|
||||
memBw={$jobMetrics.data.jobMetrics.find(m => m.name == 'mem_bw' && m.scope == 'node')} />
|
||||
</Col>
|
||||
{:else}
|
||||
<Col></Col>
|
||||
|
@@ -72,7 +72,7 @@
|
||||
<UserOrProject bind:authlevel={authlevel} bind:roles={roles} on:update={({ detail }) => filters.update(detail)}/>
|
||||
</Col>
|
||||
<Col xs="2">
|
||||
<Refresher on:reload={() => jobList.update()} />
|
||||
<Refresher on:reload={() => jobList.refresh()} />
|
||||
</Col>
|
||||
</Row>
|
||||
<br/>
|
||||
|
@@ -2,64 +2,78 @@
|
||||
@component List of users or projects
|
||||
-->
|
||||
<script>
|
||||
import { onMount } from 'svelte'
|
||||
import { init } from './utils.js'
|
||||
import { Row, Col, Button, Icon, Table, Card, Spinner,
|
||||
InputGroup, Input } from 'sveltestrap'
|
||||
import Filters from './filters/Filters.svelte'
|
||||
import { operationStore, query } from '@urql/svelte';
|
||||
import { scramble, scrambleNames } from './joblist/JobInfo.svelte'
|
||||
import { onMount } from "svelte";
|
||||
import { init } from "./utils.js";
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
Button,
|
||||
Icon,
|
||||
Table,
|
||||
Card,
|
||||
Spinner,
|
||||
InputGroup,
|
||||
Input,
|
||||
} from "sveltestrap";
|
||||
import Filters from "./filters/Filters.svelte";
|
||||
import { queryStore, gql, getContextClient } from "@urql/svelte";
|
||||
import { scramble, scrambleNames } from "./joblist/JobInfo.svelte";
|
||||
|
||||
const { } = init()
|
||||
const {} = init();
|
||||
|
||||
export let type
|
||||
export let filterPresets
|
||||
export let type;
|
||||
export let filterPresets;
|
||||
|
||||
console.assert(type == 'USER' || type == 'PROJECT', 'Invalid list type provided!')
|
||||
console.assert(
|
||||
type == "USER" || type == "PROJECT",
|
||||
"Invalid list type provided!"
|
||||
);
|
||||
|
||||
const stats = operationStore(`query($filter: [JobFilter!]!) {
|
||||
rows: jobsStatistics(filter: $filter, groupBy: ${type}) {
|
||||
id
|
||||
name
|
||||
totalJobs
|
||||
totalWalltime
|
||||
totalCoreHours
|
||||
}
|
||||
}`, {
|
||||
filter: []
|
||||
}, {
|
||||
pause: true
|
||||
})
|
||||
const client = getContextClient();
|
||||
$: stats = queryStore({
|
||||
client: client,
|
||||
query: gql`
|
||||
query($filters: [JobFilter!]!) {
|
||||
rows: jobsStatistics(filter: $filters, groupBy: ${type}) {
|
||||
id
|
||||
name
|
||||
totalJobs
|
||||
totalWalltime
|
||||
totalCoreHours
|
||||
}
|
||||
}`,
|
||||
variables: { filters }
|
||||
});
|
||||
|
||||
query(stats)
|
||||
|
||||
let filters
|
||||
let nameFilter = ''
|
||||
let sorting = { field: 'totalJobs', direction: 'down' }
|
||||
let filters;
|
||||
let nameFilter = "";
|
||||
let sorting = { field: "totalJobs", direction: "down" };
|
||||
|
||||
function changeSorting(event, field) {
|
||||
let target = event.target
|
||||
while (target.tagName != 'BUTTON')
|
||||
target = target.parentElement
|
||||
let target = event.target;
|
||||
while (target.tagName != "BUTTON") target = target.parentElement;
|
||||
|
||||
let direction = target.children[0].className.includes('up') ? 'down' : 'up'
|
||||
target.children[0].className = `bi-sort-numeric-${direction}`
|
||||
sorting = { field, direction }
|
||||
let direction = target.children[0].className.includes("up")
|
||||
? "down"
|
||||
: "up";
|
||||
target.children[0].className = `bi-sort-numeric-${direction}`;
|
||||
sorting = { field, direction };
|
||||
}
|
||||
|
||||
function sort(stats, sorting, nameFilter) {
|
||||
const cmp = sorting.field == 'id'
|
||||
? (sorting.direction == 'up'
|
||||
? (a, b) => a.id < b.id
|
||||
: (a, b) => a.id > b.id)
|
||||
: (sorting.direction == 'up'
|
||||
const cmp =
|
||||
sorting.field == "id"
|
||||
? sorting.direction == "up"
|
||||
? (a, b) => a.id < b.id
|
||||
: (a, b) => a.id > b.id
|
||||
: sorting.direction == "up"
|
||||
? (a, b) => a[sorting.field] - b[sorting.field]
|
||||
: (a, b) => b[sorting.field] - a[sorting.field])
|
||||
: (a, b) => b[sorting.field] - a[sorting.field];
|
||||
|
||||
return stats.filter(u => u.id.includes(nameFilter)).sort(cmp)
|
||||
return stats.filter((u) => u.id.includes(nameFilter)).sort(cmp);
|
||||
}
|
||||
|
||||
onMount(() => filters.update())
|
||||
onMount(() => filters.update());
|
||||
</script>
|
||||
|
||||
<Row>
|
||||
@@ -68,59 +82,86 @@
|
||||
<Button disabled outline>
|
||||
Search {type.toLowerCase()}s
|
||||
</Button>
|
||||
<Input bind:value={nameFilter} placeholder="Filter by {({ USER: 'username', PROJECT: 'project' })[type]}" />
|
||||
<Input
|
||||
bind:value={nameFilter}
|
||||
placeholder="Filter by {{
|
||||
USER: 'username',
|
||||
PROJECT: 'project',
|
||||
}[type]}"
|
||||
/>
|
||||
</InputGroup>
|
||||
</Col>
|
||||
<Col xs="auto">
|
||||
<Filters
|
||||
bind:this={filters}
|
||||
filterPresets={filterPresets}
|
||||
{filterPresets}
|
||||
startTimeQuickSelect={true}
|
||||
menuText="Only {type.toLowerCase()}s with jobs that match the filters will show up"
|
||||
on:update={({ detail }) => {
|
||||
$stats.variables = { filter: detail.filters }
|
||||
$stats.context.pause = false
|
||||
$stats.reexecute()
|
||||
}} />
|
||||
filters = detail.filters;
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">
|
||||
{({ USER: 'Username', PROJECT: 'Project Name' })[type]}
|
||||
<Button color="{sorting.field == 'id' ? 'primary' : 'light'}"
|
||||
size="sm" on:click={e => changeSorting(e, 'id')}>
|
||||
<!-- {({ -->
|
||||
<!-- USER: "Username", -->
|
||||
<!-- PROJECT: "Project Name", -->
|
||||
<!-- })[type]} -->
|
||||
<Button
|
||||
color={sorting.field == "id" ? "primary" : "light"}
|
||||
size="sm"
|
||||
on:click={(e) => changeSorting(e, "id")}
|
||||
>
|
||||
<Icon name="sort-numeric-down" />
|
||||
</Button>
|
||||
</th>
|
||||
{#if type == 'USER'}
|
||||
{#if type == "USER"}
|
||||
<th scope="col">
|
||||
Name
|
||||
<Button color="{sorting.field == 'name' ? 'primary' : 'light'}"
|
||||
size="sm" on:click={e => changeSorting(e, 'name')}>
|
||||
<Button
|
||||
color={sorting.field == "name" ? "primary" : "light"}
|
||||
size="sm"
|
||||
on:click={(e) => changeSorting(e, "name")}
|
||||
>
|
||||
<Icon name="sort-numeric-down" />
|
||||
</Button>
|
||||
</th>
|
||||
{/if}
|
||||
<th scope="col">
|
||||
Total Jobs
|
||||
<Button color="{sorting.field == 'totalJobs' ? 'primary' : 'light'}"
|
||||
size="sm" on:click={e => changeSorting(e, 'totalJobs')}>
|
||||
<Button
|
||||
color={sorting.field == "totalJobs" ? "primary" : "light"}
|
||||
size="sm"
|
||||
on:click={(e) => changeSorting(e, "totalJobs")}
|
||||
>
|
||||
<Icon name="sort-numeric-down" />
|
||||
</Button>
|
||||
</th>
|
||||
<th scope="col">
|
||||
Total Walltime
|
||||
<Button color="{sorting.field == 'totalWalltime' ? 'primary' : 'light'}"
|
||||
size="sm" on:click={e => changeSorting(e, 'totalWalltime')}>
|
||||
<Button
|
||||
color={sorting.field == "totalWalltime"
|
||||
? "primary"
|
||||
: "light"}
|
||||
size="sm"
|
||||
on:click={(e) => changeSorting(e, "totalWalltime")}
|
||||
>
|
||||
<Icon name="sort-numeric-down" />
|
||||
</Button>
|
||||
</th>
|
||||
<th scope="col">
|
||||
Total Core Hours
|
||||
<Button color="{sorting.field == 'totalCoreHours' ? 'primary' : 'light'}"
|
||||
size="sm" on:click={e => changeSorting(e, 'totalCoreHours')}>
|
||||
<Button
|
||||
color={sorting.field == "totalCoreHours"
|
||||
? "primary"
|
||||
: "light"}
|
||||
size="sm"
|
||||
on:click={(e) => changeSorting(e, "totalCoreHours")}
|
||||
>
|
||||
<Icon name="sort-numeric-down" />
|
||||
</Button>
|
||||
</th>
|
||||
@@ -129,26 +170,36 @@
|
||||
<tbody>
|
||||
{#if $stats.fetching}
|
||||
<tr>
|
||||
<td colspan="4" style="text-align: center;"><Spinner secondary/></td>
|
||||
<td colspan="4" style="text-align: center;"
|
||||
><Spinner secondary /></td
|
||||
>
|
||||
</tr>
|
||||
{:else if $stats.error}
|
||||
<tr>
|
||||
<td colspan="4"><Card body color="danger" class="mb-3">{$stats.error.message}</Card></td>
|
||||
<td colspan="4"
|
||||
><Card body color="danger" class="mb-3"
|
||||
>{$stats.error.message}</Card
|
||||
></td
|
||||
>
|
||||
</tr>
|
||||
{:else if $stats.data}
|
||||
{#each sort($stats.data.rows, sorting, nameFilter) as row (row.id)}
|
||||
<tr>
|
||||
<td>
|
||||
{#if type == 'USER'}
|
||||
<a href="/monitoring/user/{row.id}">{scrambleNames ? scramble(row.id) : row.id}</a>
|
||||
{:else if type == 'PROJECT'}
|
||||
<a href="/monitoring/jobs/?project={row.id}">{row.id}</a>
|
||||
{#if type == "USER"}
|
||||
<a href="/monitoring/user/{row.id}"
|
||||
>{scrambleNames ? scramble(row.id) : row.id}</a
|
||||
>
|
||||
{:else if type == "PROJECT"}
|
||||
<a href="/monitoring/jobs/?project={row.id}"
|
||||
>{row.id}</a
|
||||
>
|
||||
{:else}
|
||||
{row.id}
|
||||
{/if}
|
||||
</td>
|
||||
{#if type == 'USER'}
|
||||
<td>{row?.name ? row.name : ''}</td>
|
||||
{#if type == "USER"}
|
||||
<td>{row?.name ? row.name : ""}</td>
|
||||
{/if}
|
||||
<td>{row.totalJobs}</td>
|
||||
<td>{row.totalWalltime}</td>
|
||||
@@ -156,7 +207,9 @@
|
||||
</tr>
|
||||
{:else}
|
||||
<tr>
|
||||
<td colspan="4"><i>No {type.toLowerCase()}s/jobs found</i></td>
|
||||
<td colspan="4"
|
||||
><i>No {type.toLowerCase()}s/jobs found</i></td
|
||||
>
|
||||
</tr>
|
||||
{/each}
|
||||
{/if}
|
||||
|
@@ -10,7 +10,7 @@
|
||||
<script>
|
||||
import { Modal, ModalBody, ModalHeader, ModalFooter, Button, ListGroup } from 'sveltestrap'
|
||||
import { getContext } from 'svelte'
|
||||
import { mutation } from '@urql/svelte'
|
||||
import { gql, getContextClient , mutationStore } from '@urql/svelte'
|
||||
|
||||
export let metrics
|
||||
export let isOpen
|
||||
@@ -53,11 +53,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
const updateConfiguration = mutation({
|
||||
query: `mutation($name: String!, $value: String!) {
|
||||
updateConfiguration(name: $name, value: $value)
|
||||
}`
|
||||
})
|
||||
const client = getContextClient();
|
||||
const updateConfigurationMutation = ({ name, value }) => {
|
||||
return mutationStore({
|
||||
client: client,
|
||||
query: gql`
|
||||
mutation($name: String!, $value: String!) {
|
||||
updateConfiguration(name: $name, value: $value)
|
||||
}
|
||||
`,
|
||||
variables: { name, value }
|
||||
})}
|
||||
|
||||
let columnHovering = null
|
||||
|
||||
@@ -84,14 +90,15 @@
|
||||
metrics = newMetricsOrder.filter(m => unorderedMetrics.includes(m))
|
||||
isOpen = false
|
||||
|
||||
updateConfiguration({
|
||||
name: cluster == null ? configName : `${configName}:${cluster}`,
|
||||
value: JSON.stringify(metrics)
|
||||
})
|
||||
.then(res => {
|
||||
if (res.error)
|
||||
console.error(res.error)
|
||||
})
|
||||
updateConfigurationMutation({
|
||||
name: cluster == null ? configName : `${configName}:${cluster}`,
|
||||
value: JSON.stringify(metrics)
|
||||
}).subscribe(res => {
|
||||
if (res.fetching === false && res.error) {
|
||||
throw res.error
|
||||
// console.log('Error on subscription: ' + res.error)
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<script>
|
||||
import { init } from './utils.js'
|
||||
import { Row, Col, InputGroup, InputGroupText, Icon, Spinner, Card } from 'sveltestrap'
|
||||
import { operationStore, query } from '@urql/svelte'
|
||||
import { queryStore, gql, getContextClient } from '@urql/svelte'
|
||||
import TimeSelection from './filters/TimeSelection.svelte'
|
||||
import PlotTable from './PlotTable.svelte'
|
||||
import MetricPlot from './plots/MetricPlot.svelte'
|
||||
@@ -22,8 +22,8 @@
|
||||
|
||||
const ccconfig = getContext('cc-config')
|
||||
const clusters = getContext('clusters')
|
||||
|
||||
const nodesQuery = operationStore(`query($cluster: String!, $nodes: [String!], $from: Time!, $to: Time!) {
|
||||
const client = getContextClient();
|
||||
const query = gql`query($cluster: String!, $nodes: [String!], $from: Time!, $to: Time!) {
|
||||
nodeMetrics(cluster: $cluster, nodes: $nodes, from: $from, to: $to) {
|
||||
host
|
||||
subCluster
|
||||
@@ -40,14 +40,18 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}`, {
|
||||
cluster: cluster,
|
||||
nodes: [hostname],
|
||||
from: from.toISOString(),
|
||||
to: to.toISOString()
|
||||
})
|
||||
}`;
|
||||
|
||||
$: $nodesQuery.variables = { cluster, nodes: [hostname], from: from.toISOString(), to: to.toISOString() }
|
||||
$: nodesQuery = queryStore({
|
||||
client: client,
|
||||
query: query,
|
||||
variables: {
|
||||
cluster: cluster,
|
||||
nodes: [hostname],
|
||||
from: from.toISOString(),
|
||||
to: to.toISOString(),
|
||||
}
|
||||
});
|
||||
|
||||
let metricUnits = {}
|
||||
$: if ($nodesQuery.data) {
|
||||
@@ -59,9 +63,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query(nodesQuery)
|
||||
|
||||
// $: console.log($nodesQuery?.data?.nodeMetrics[0].metrics)
|
||||
</script>
|
||||
|
||||
|
@@ -1,17 +1,22 @@
|
||||
<script>
|
||||
import { Modal, ModalBody, ModalHeader, ModalFooter, InputGroup,
|
||||
Button, ListGroup, ListGroupItem, Icon } from 'sveltestrap'
|
||||
import { mutation } from '@urql/svelte'
|
||||
import { gql, getContextClient , mutationStore } from '@urql/svelte'
|
||||
|
||||
export let availableMetrics
|
||||
export let metricsInHistograms
|
||||
export let metricsInScatterplots
|
||||
|
||||
const updateConfigurationMutation = mutation({
|
||||
query: `mutation($name: String!, $value: String!) {
|
||||
updateConfiguration(name: $name, value: $value)
|
||||
}`
|
||||
})
|
||||
const client = getContextClient();
|
||||
const updateConfigurationMutation = ({ name, value }) => {
|
||||
return mutationStore({
|
||||
client: client,
|
||||
query: gql`mutation($name: String!, $value: String!) {
|
||||
updateConfiguration(name: $name, value: $value)
|
||||
}`,
|
||||
variables: { name, value }
|
||||
})
|
||||
}
|
||||
|
||||
let isHistogramConfigOpen = false, isScatterPlotConfigOpen = false
|
||||
let selectedMetric1 = null, selectedMetric2 = null
|
||||
@@ -20,11 +25,12 @@
|
||||
updateConfigurationMutation({
|
||||
name: data.name,
|
||||
value: JSON.stringify(data.value)
|
||||
})
|
||||
.then(res => {
|
||||
if (res.error)
|
||||
console.error(res.error)
|
||||
});
|
||||
}).subscribe(res => {
|
||||
if (res.fetching === false && res.error) {
|
||||
throw res.error
|
||||
// console.log('Error on subscription: ' + res.error)
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@@ -4,16 +4,19 @@
|
||||
import Histogram from './plots/Histogram.svelte'
|
||||
import { Row, Col, Spinner, Card, CardHeader, CardTitle, CardBody, Table, Progress, Icon } from 'sveltestrap'
|
||||
import { init } from './utils.js'
|
||||
import { operationStore, query } from '@urql/svelte'
|
||||
import { queryStore, gql, getContextClient } from '@urql/svelte'
|
||||
|
||||
const { query: initq } = init()
|
||||
|
||||
export let cluster
|
||||
|
||||
let plotWidths = [], colWidth1 = 0, colWidth2
|
||||
|
||||
let from = new Date(Date.now() - 5 * 60 * 1000), to = new Date(Date.now())
|
||||
const mainQuery = operationStore(`query($cluster: String!, $filter: [JobFilter!]!, $metrics: [String!], $from: Time!, $to: Time!) {
|
||||
|
||||
const client = getContextClient();
|
||||
$: mainQuery = queryStore({
|
||||
client: client,
|
||||
query: gql`query($cluster: String!, $filter: [JobFilter!]!, $metrics: [String!], $from: Time!, $to: Time!) {
|
||||
nodeMetrics(cluster: $cluster, metrics: $metrics, from: $from, to: $to) {
|
||||
host
|
||||
subCluster
|
||||
@@ -36,12 +39,11 @@
|
||||
allocatedNodes(cluster: $cluster) { name, count }
|
||||
topUsers: jobsCount(filter: $filter, groupBy: USER, weight: NODE_COUNT, limit: 10) { name, count }
|
||||
topProjects: jobsCount(filter: $filter, groupBy: PROJECT, weight: NODE_COUNT, limit: 10) { name, count }
|
||||
}`, {
|
||||
cluster: cluster,
|
||||
metrics: ['flops_any', 'mem_bw'],
|
||||
from: from.toISOString(),
|
||||
to: to.toISOString(),
|
||||
}`,
|
||||
variables: {
|
||||
cluster: cluster, metrics: ['flops_any', 'mem_bw'], from: from.toISOString(), to: to.toISOString(),
|
||||
filter: [{ state: ['running'] }, { cluster: { eq: cluster } }]
|
||||
}
|
||||
})
|
||||
|
||||
const sumUp = (data, subcluster, metric) => data.reduce((sum, node) => node.subCluster == subcluster
|
||||
@@ -60,7 +62,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
query(mainQuery)
|
||||
</script>
|
||||
|
||||
<!-- Loading indicator & Refresh -->
|
||||
@@ -80,13 +81,8 @@
|
||||
</Col>
|
||||
<Col xs="auto" style="margin-left: auto;">
|
||||
<Refresher initially={120} on:reload={() => {
|
||||
console.log('reload...')
|
||||
|
||||
from = new Date(Date.now() - 5 * 60 * 1000)
|
||||
to = new Date(Date.now())
|
||||
|
||||
$mainQuery.variables = { ...$mainQuery.variables, from: from, to: to }
|
||||
$mainQuery.reexecute({ requestPolicy: 'network-only' })
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<script>
|
||||
import { init } from './utils.js'
|
||||
import { Row, Col, Input, InputGroup, InputGroupText, Icon, Spinner, Card } from 'sveltestrap'
|
||||
import { operationStore, query } from '@urql/svelte'
|
||||
import { queryStore, gql, getContextClient } from '@urql/svelte'
|
||||
import TimeSelection from './filters/TimeSelection.svelte'
|
||||
import PlotTable from './PlotTable.svelte'
|
||||
import MetricPlot from './plots/MetricPlot.svelte'
|
||||
@@ -27,28 +27,33 @@
|
||||
let hostnameFilter = ''
|
||||
let selectedMetric = ccconfig.system_view_selectedMetric
|
||||
|
||||
const nodesQuery = operationStore(`query($cluster: String!, $metrics: [String!], $from: Time!, $to: Time!) {
|
||||
nodeMetrics(cluster: $cluster, metrics: $metrics, from: $from, to: $to) {
|
||||
host
|
||||
subCluster
|
||||
metrics {
|
||||
name
|
||||
scope
|
||||
metric {
|
||||
timestep
|
||||
unit { base, prefix }
|
||||
series {
|
||||
statistics { min, avg, max }
|
||||
data
|
||||
const client = getContextClient();
|
||||
$: nodesQuery = queryStore({
|
||||
client: client,
|
||||
query: gql`query($cluster: String!, $metrics: [String!], $from: Time!, $to: Time!) {
|
||||
nodeMetrics(cluster: $cluster, metrics: $metrics, from: $from, to: $to) {
|
||||
host
|
||||
subCluster
|
||||
metrics {
|
||||
name
|
||||
scope
|
||||
metric {
|
||||
timestep
|
||||
unit { base, prefix }
|
||||
series {
|
||||
statistics { min, avg, max }
|
||||
data
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
variables: {
|
||||
cluster: cluster,
|
||||
metrics: [selectedMetric],
|
||||
from: from.toISOString(),
|
||||
to: to.toISOString()
|
||||
}
|
||||
}`, {
|
||||
cluster: cluster,
|
||||
metrics: [],
|
||||
from: from.toISOString(),
|
||||
to: to.toISOString()
|
||||
})
|
||||
|
||||
let metricUnits = {}
|
||||
@@ -63,9 +68,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
$: $nodesQuery.variables = { cluster, metrics: [selectedMetric], from: from.toISOString(), to: to.toISOString() }
|
||||
|
||||
query(nodesQuery)
|
||||
</script>
|
||||
|
||||
<Row>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<script>
|
||||
import { getContext } from 'svelte'
|
||||
import { mutation } from '@urql/svelte'
|
||||
import { gql, getContextClient , mutationStore } from '@urql/svelte'
|
||||
import { Icon, Button, ListGroupItem, Spinner, Modal, Input,
|
||||
ModalBody, ModalHeader, ModalFooter, Alert } from 'sveltestrap'
|
||||
import { fuzzySearchTags } from './utils.js'
|
||||
@@ -15,23 +15,37 @@
|
||||
let pendingChange = false
|
||||
let isOpen = false
|
||||
|
||||
const createTagMutation = mutation({
|
||||
query: `mutation($type: String!, $name: String!) {
|
||||
createTag(type: $type, name: $name) { id, type, name }
|
||||
}`
|
||||
})
|
||||
const client = getContextClient();
|
||||
|
||||
const addTagsToJobMutation = mutation({
|
||||
query: `mutation($job: ID!, $tagIds: [ID!]!) {
|
||||
addTagsToJob(job: $job, tagIds: $tagIds) { id, type, name }
|
||||
}`
|
||||
})
|
||||
const createTagMutation = ({ type, name }) => {
|
||||
return mutationStore({
|
||||
client: client,
|
||||
query: gql`mutation($type: String!, $name: String!) {
|
||||
createTag(type: $type, name: $name) { id, type, name }
|
||||
}`,
|
||||
variables: { type, name}
|
||||
})
|
||||
}
|
||||
|
||||
const removeTagsFromJobMutation = mutation({
|
||||
query: `mutation($job: ID!, $tagIds: [ID!]!) {
|
||||
removeTagsFromJob(job: $job, tagIds: $tagIds) { id, type, name }
|
||||
}`
|
||||
})
|
||||
const addTagsToJobMutation = ({ job, tagIds }) => {
|
||||
return mutationStore({
|
||||
client: client,
|
||||
query: gql`mutation($job: ID!, $tagIds: [ID!]!) {
|
||||
addTagsToJob(job: $job, tagIds: $tagIds) { id, type, name }
|
||||
}`,
|
||||
variables: {job, tagIds}
|
||||
})
|
||||
}
|
||||
|
||||
const removeTagsFromJobMutation = ({ job, tagIds }) => {
|
||||
return mutationStore({
|
||||
client: client,
|
||||
query: gql`mutation($job: ID!, $tagIds: [ID!]!) {
|
||||
removeTagsFromJob(job: $job, tagIds: $tagIds) { id, type, name }
|
||||
}`,
|
||||
variables: {job, tagIds}
|
||||
})
|
||||
}
|
||||
|
||||
let allTagsFiltered // $initialized is in there because when it becomes true, allTags is initailzed.
|
||||
$: allTagsFiltered = ($initialized, fuzzySearchTags(filterTerm, allTags))
|
||||
@@ -55,43 +69,47 @@
|
||||
|
||||
function createTag(type, name) {
|
||||
pendingChange = true
|
||||
return createTagMutation({ type: type, name: name })
|
||||
.then(res => {
|
||||
if (res.error)
|
||||
throw res.error
|
||||
|
||||
createTagMutation({ type: type, name: name })
|
||||
.subscribe(res => {
|
||||
if (res.fetching === false && !res.error) {
|
||||
pendingChange = false
|
||||
allTags = [...allTags, res.data.createTag]
|
||||
newTagType = ''
|
||||
newTagName = ''
|
||||
return res.data.createTag
|
||||
}, err => console.error(err))
|
||||
addTagToJob(res.data.createTag)
|
||||
} else if (res.fetching === false && res.error) {
|
||||
throw res.error
|
||||
// console.log('Error on subscription: ' + res.error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function addTagToJob(tag) {
|
||||
pendingChange = tag.id
|
||||
addTagsToJobMutation({ job: job.id, tagIds: [tag.id] })
|
||||
.then(res => {
|
||||
if (res.error)
|
||||
throw res.error
|
||||
|
||||
.subscribe(res => {
|
||||
if (res.fetching === false && !res.error) {
|
||||
jobTags = job.tags = res.data.addTagsToJob;
|
||||
pendingChange = false;
|
||||
})
|
||||
.catch(err => console.error(err))
|
||||
} else if (res.fetching === false && res.error) {
|
||||
throw res.error
|
||||
// console.log('Error on subscription: ' + res.error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function removeTagFromJob(tag) {
|
||||
pendingChange = tag.id
|
||||
removeTagsFromJobMutation({ job: job.id, tagIds: [tag.id] })
|
||||
.then(res => {
|
||||
if (res.error)
|
||||
throw res.error
|
||||
|
||||
.subscribe(res => {
|
||||
if (res.fetching === false && !res.error) {
|
||||
jobTags = job.tags = res.data.removeTagsFromJob
|
||||
pendingChange = false
|
||||
})
|
||||
.catch(err => console.error(err))
|
||||
} else if (res.fetching === false && res.error) {
|
||||
throw res.error
|
||||
// console.log('Error on subscription: ' + res.error)
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -154,8 +172,7 @@
|
||||
<br/>
|
||||
{#if newTagType && newTagName && isNewTag(newTagType, newTagName)}
|
||||
<Button outline color="success"
|
||||
on:click={e => (e.preventDefault(), createTag(newTagType, newTagName))
|
||||
.then(tag => addTagToJob(tag))}>
|
||||
on:click={e => (e.preventDefault(), createTag(newTagType, newTagName))}>
|
||||
Create & Add Tag:
|
||||
<Tag tag={({ type: newTagType, name: newTagName })} clickable={false}/>
|
||||
</Button>
|
||||
|
@@ -2,7 +2,7 @@
|
||||
import { onMount, getContext } from 'svelte'
|
||||
import { init } from './utils.js'
|
||||
import { Table, Row, Col, Button, Icon, Card, Spinner } from 'sveltestrap'
|
||||
import { operationStore, query } from '@urql/svelte'
|
||||
import { queryStore, gql, getContextClient } from '@urql/svelte'
|
||||
import Filters from './filters/Filters.svelte'
|
||||
import JobList from './joblist/JobList.svelte'
|
||||
import Sorting from './joblist/SortSelection.svelte'
|
||||
@@ -25,31 +25,24 @@
|
||||
let w1, w2, histogramHeight = 250
|
||||
let selectedCluster = filterPresets?.cluster ? filterPresets.cluster : null
|
||||
|
||||
const stats = operationStore(`
|
||||
query($filter: [JobFilter!]!) {
|
||||
jobsStatistics(filter: $filter) {
|
||||
totalJobs
|
||||
shortJobs
|
||||
totalWalltime
|
||||
totalCoreHours
|
||||
histDuration { count, value }
|
||||
histNumNodes { count, value }
|
||||
}
|
||||
}
|
||||
`, {
|
||||
filter: []
|
||||
}, {
|
||||
pause: true
|
||||
const client = getContextClient();
|
||||
$: stats = queryStore({
|
||||
client: client,
|
||||
query: gql`
|
||||
query($filters: [JobFilter!]!) {
|
||||
jobsStatistics(filter: $filters) {
|
||||
totalJobs
|
||||
shortJobs
|
||||
totalWalltime
|
||||
totalCoreHours
|
||||
histDuration { count, value }
|
||||
histNumNodes { count, value }
|
||||
}}`,
|
||||
variables: { filters }
|
||||
})
|
||||
|
||||
// filters[filters.findIndex(filter => filter.cluster != null)] ?
|
||||
// filters[filters.findIndex(filter => filter.cluster != null)].cluster.eq :
|
||||
// null
|
||||
// Cluster filter has to be alwas @ first index, above will throw error
|
||||
$: selectedCluster = filters[0]?.cluster ? filters[0].cluster.eq : null
|
||||
|
||||
query(stats)
|
||||
|
||||
onMount(() => filters.update())
|
||||
</script>
|
||||
|
||||
@@ -84,15 +77,12 @@
|
||||
bind:this={filters}
|
||||
on:update={({ detail }) => {
|
||||
let jobFilters = [...detail.filters, { user: { eq: user.username } }]
|
||||
$stats.variables = { filter: jobFilters }
|
||||
$stats.context.pause = false
|
||||
$stats.reexecute()
|
||||
filters = jobFilters
|
||||
jobList.update(jobFilters)
|
||||
}} />
|
||||
</Col>
|
||||
<Col xs="auto" style="margin-left: auto;">
|
||||
<Refresher on:reload={() => jobList.update()} />
|
||||
<Refresher on:reload={() => jobList.refresh()} />
|
||||
</Col>
|
||||
</Row>
|
||||
<br/>
|
||||
|
@@ -9,83 +9,144 @@
|
||||
- update(filters?: [JobFilter])
|
||||
-->
|
||||
<script>
|
||||
import { operationStore, query, mutation } from '@urql/svelte'
|
||||
import { getContext } from 'svelte';
|
||||
import { Row, Table, Card, Spinner } from 'sveltestrap'
|
||||
import Pagination from './Pagination.svelte'
|
||||
import JobListRow from './Row.svelte'
|
||||
import { stickyHeader } from '../utils.js'
|
||||
import {
|
||||
queryStore,
|
||||
gql,
|
||||
getContextClient,
|
||||
mutationStore,
|
||||
} from "@urql/svelte";
|
||||
import { getContext } from "svelte";
|
||||
import { Row, Table, Card, Spinner } from "sveltestrap";
|
||||
import Pagination from "./Pagination.svelte";
|
||||
import JobListRow from "./Row.svelte";
|
||||
import { stickyHeader } from "../utils.js";
|
||||
|
||||
const ccconfig = getContext('cc-config'),
|
||||
clusters = getContext('clusters'),
|
||||
initialized = getContext('initialized')
|
||||
const ccconfig = getContext("cc-config"),
|
||||
clusters = getContext("clusters"),
|
||||
initialized = getContext("initialized");
|
||||
|
||||
export let sorting = { field: "startTime", order: "DESC" }
|
||||
export let matchedJobs = 0
|
||||
export let metrics = ccconfig.plot_list_selectedMetrics
|
||||
export let sorting = { field: "startTime", order: "DESC" };
|
||||
export let matchedJobs = 0;
|
||||
export let metrics = ccconfig.plot_list_selectedMetrics;
|
||||
|
||||
let itemsPerPage = ccconfig.plot_list_jobsPerPage
|
||||
let page = 1
|
||||
let paging = { itemsPerPage, page }
|
||||
let filter = []
|
||||
let itemsPerPage = ccconfig.plot_list_jobsPerPage;
|
||||
let page = 1;
|
||||
let paging = { itemsPerPage, page };
|
||||
let filter = [];
|
||||
|
||||
const jobs = operationStore(`
|
||||
query($filter: [JobFilter!]!, $sorting: OrderByInput!, $paging: PageRequest! ){
|
||||
jobs(filter: $filter, order: $sorting, page: $paging) {
|
||||
items {
|
||||
id, jobId, user, project, jobName, cluster, subCluster, startTime,
|
||||
duration, numNodes, numHWThreads, numAcc, walltime, resources { hostname },
|
||||
SMT, exclusive, partition, arrayJobId,
|
||||
monitoringStatus, state,
|
||||
tags { id, type, name }
|
||||
userData { name }
|
||||
metaData
|
||||
const client = getContextClient();
|
||||
const query = gql`
|
||||
query (
|
||||
$filter: [JobFilter!]!
|
||||
$sorting: OrderByInput!
|
||||
$paging: PageRequest!
|
||||
) {
|
||||
jobs(filter: $filter, order: $sorting, page: $paging) {
|
||||
items {
|
||||
id
|
||||
jobId
|
||||
user
|
||||
project
|
||||
jobName
|
||||
cluster
|
||||
subCluster
|
||||
startTime
|
||||
duration
|
||||
numNodes
|
||||
numHWThreads
|
||||
numAcc
|
||||
walltime
|
||||
resources {
|
||||
hostname
|
||||
}
|
||||
SMT
|
||||
exclusive
|
||||
partition
|
||||
arrayJobId
|
||||
monitoringStatus
|
||||
state
|
||||
tags {
|
||||
id
|
||||
type
|
||||
name
|
||||
}
|
||||
userData {
|
||||
name
|
||||
}
|
||||
metaData
|
||||
}
|
||||
count
|
||||
}
|
||||
count
|
||||
}
|
||||
}`, {
|
||||
paging,
|
||||
sorting,
|
||||
filter,
|
||||
}, {
|
||||
pause: true
|
||||
})
|
||||
`;
|
||||
|
||||
const updateConfiguration = mutation({
|
||||
query: `mutation($name: String!, $value: String!) {
|
||||
updateConfiguration(name: $name, value: $value)
|
||||
}`
|
||||
})
|
||||
$: jobs = queryStore({
|
||||
client: client,
|
||||
query: query,
|
||||
variables: { paging, sorting, filter }
|
||||
});
|
||||
|
||||
$: $jobs.variables = { ...$jobs.variables, sorting, paging }
|
||||
$: matchedJobs = $jobs.data != null ? $jobs.data.jobs.count : 0
|
||||
$: matchedJobs = $jobs.data != null ? $jobs.data.jobs.count : 0;
|
||||
|
||||
// Force refresh list with existing unchanged variables (== usually would not trigger reactivity)
|
||||
export function refresh() {
|
||||
queryStore({
|
||||
client: client,
|
||||
query: query,
|
||||
variables: { paging, sorting, filter },
|
||||
requestPolicy: 'network-only'
|
||||
});
|
||||
}
|
||||
|
||||
// (Re-)query and optionally set new filters.
|
||||
export function update(filters) {
|
||||
if (filters != null) {
|
||||
let minRunningFor = ccconfig.plot_list_hideShortRunningJobs
|
||||
let minRunningFor = ccconfig.plot_list_hideShortRunningJobs;
|
||||
if (minRunningFor && minRunningFor > 0) {
|
||||
filters.push({ minRunningFor })
|
||||
filters.push({ minRunningFor });
|
||||
}
|
||||
|
||||
$jobs.variables.filter = filters
|
||||
// console.log('filters:', ...filters.map(f => Object.entries(f)).flat(2))
|
||||
filter = filters;
|
||||
}
|
||||
|
||||
page = 1
|
||||
$jobs.variables.paging = paging = { page, itemsPerPage };
|
||||
$jobs.context.pause = false
|
||||
$jobs.reexecute({ requestPolicy: 'network-only' })
|
||||
page = 1;
|
||||
paging = paging = { page, itemsPerPage };
|
||||
}
|
||||
|
||||
query(jobs)
|
||||
const updateConfigurationMutation = ({ name, value }) => {
|
||||
return mutationStore({
|
||||
client: client,
|
||||
query: gql`
|
||||
mutation ($name: String!, $value: String!) {
|
||||
updateConfiguration(name: $name, value: $value)
|
||||
}
|
||||
`,
|
||||
variables: { name, value }
|
||||
});
|
||||
}
|
||||
|
||||
let tableWidth = null
|
||||
let jobInfoColumnWidth = 250
|
||||
$: plotWidth = Math.floor((tableWidth - jobInfoColumnWidth) / metrics.length - 10)
|
||||
function updateConfiguration(value, page) {
|
||||
updateConfigurationMutation({ name: 'plot_list_jobsPerPage', value: value })
|
||||
.subscribe(res => {
|
||||
if (res.fetching === false && !res.error) {
|
||||
paging = { itemsPerPage: value, page: page }; // Trigger reload of jobList
|
||||
} else if (res.fetching === false && res.error) {
|
||||
throw res.error
|
||||
// console.log('Error on subscription: ' + res.error)
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
let headerPaddingTop = 0
|
||||
stickyHeader('.cc-table-wrapper > table.table >thead > tr > th.position-sticky:nth-child(1)', (x) => (headerPaddingTop = x))
|
||||
let tableWidth = null;
|
||||
let jobInfoColumnWidth = 250;
|
||||
|
||||
$: plotWidth = Math.floor(
|
||||
(tableWidth - jobInfoColumnWidth) / metrics.length - 10
|
||||
);
|
||||
|
||||
let headerPaddingTop = 0;
|
||||
stickyHeader(
|
||||
".cc-table-wrapper > table.table >thead > tr > th.position-sticky:nth-child(1)",
|
||||
(x) => (headerPaddingTop = x)
|
||||
);
|
||||
</script>
|
||||
|
||||
<Row>
|
||||
@@ -93,20 +154,43 @@
|
||||
<Table cellspacing="0px" cellpadding="0px">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="position-sticky top-0" scope="col" style="width: {jobInfoColumnWidth}px; padding-top: {headerPaddingTop}px">
|
||||
<th
|
||||
class="position-sticky top-0"
|
||||
scope="col"
|
||||
style="width: {jobInfoColumnWidth}px; padding-top: {headerPaddingTop}px"
|
||||
>
|
||||
Job Info
|
||||
</th>
|
||||
{#each metrics as metric (metric)}
|
||||
<th class="position-sticky top-0 text-center" scope="col" style="width: {plotWidth}px; padding-top: {headerPaddingTop}px">
|
||||
<th
|
||||
class="position-sticky top-0 text-center"
|
||||
scope="col"
|
||||
style="width: {plotWidth}px; padding-top: {headerPaddingTop}px"
|
||||
>
|
||||
{metric}
|
||||
{#if $initialized}
|
||||
({clusters
|
||||
.map(cluster => cluster.metricConfig.find(m => m.name == metric))
|
||||
.filter(m => m != null)
|
||||
.map(m => (m.unit?.prefix?m.unit?.prefix:'') + (m.unit?.base?m.unit?.base:'')) // Build unitStr
|
||||
.reduce((arr, unitStr) => arr.includes(unitStr) ? arr : [...arr, unitStr], []) // w/o this, output would be [unitStr, unitStr]
|
||||
.join(', ')
|
||||
})
|
||||
.map((cluster) =>
|
||||
cluster.metricConfig.find(
|
||||
(m) => m.name == metric
|
||||
)
|
||||
)
|
||||
.filter((m) => m != null)
|
||||
.map(
|
||||
(m) =>
|
||||
(m.unit?.prefix
|
||||
? m.unit?.prefix
|
||||
: "") +
|
||||
(m.unit?.base ? m.unit?.base : "")
|
||||
) // Build unitStr
|
||||
.reduce(
|
||||
(arr, unitStr) =>
|
||||
arr.includes(unitStr)
|
||||
? arr
|
||||
: [...arr, unitStr],
|
||||
[]
|
||||
) // w/o this, output would be [unitStr, unitStr]
|
||||
.join(", ")})
|
||||
{/if}
|
||||
</th>
|
||||
{/each}
|
||||
@@ -115,28 +199,27 @@
|
||||
<tbody>
|
||||
{#if $jobs.error}
|
||||
<tr>
|
||||
<td colspan="{metrics.length + 1}">
|
||||
<Card body color="danger" class="mb-3"><h2>{$jobs.error.message}</h2></Card>
|
||||
<td colspan={metrics.length + 1}>
|
||||
<Card body color="danger" class="mb-3"
|
||||
><h2>{$jobs.error.message}</h2></Card
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
{:else if $jobs.fetching || !$jobs.data}
|
||||
<tr>
|
||||
<td colspan="{metrics.length + 1}">
|
||||
<td colspan={metrics.length + 1}>
|
||||
<Spinner secondary />
|
||||
</td>
|
||||
</tr>
|
||||
{:else if $jobs.data && $initialized}
|
||||
{#each $jobs.data.jobs.items as job (job)}
|
||||
<JobListRow
|
||||
job={job}
|
||||
metrics={metrics}
|
||||
plotWidth={plotWidth} />
|
||||
<JobListRow {job} {metrics} {plotWidth} />
|
||||
{:else}
|
||||
<tr>
|
||||
<td colspan="{metrics.length + 1}">
|
||||
No jobs found
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan={metrics.length + 1}>
|
||||
No jobs found
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
{/if}
|
||||
</tbody>
|
||||
@@ -145,24 +228,21 @@
|
||||
</Row>
|
||||
|
||||
<Pagination
|
||||
bind:page={page}
|
||||
bind:page
|
||||
{itemsPerPage}
|
||||
itemText="Jobs"
|
||||
totalItems={matchedJobs}
|
||||
on:update={({ detail }) => {
|
||||
if (detail.itemsPerPage != itemsPerPage) {
|
||||
itemsPerPage = detail.itemsPerPage
|
||||
updateConfiguration({
|
||||
name: "plot_list_jobsPerPage",
|
||||
value: itemsPerPage.toString()
|
||||
}).then(res => {
|
||||
if (res.error)
|
||||
console.error(res.error);
|
||||
})
|
||||
updateConfiguration(
|
||||
detail.itemsPerPage.toString(),
|
||||
detail.page
|
||||
)
|
||||
} else {
|
||||
paging = { itemsPerPage: detail.itemsPerPage, page: detail.page }
|
||||
}
|
||||
|
||||
paging = { itemsPerPage: detail.itemsPerPage, page: detail.page }
|
||||
}} />
|
||||
}}
|
||||
/>
|
||||
|
||||
<style>
|
||||
.cc-table-wrapper {
|
||||
|
@@ -9,132 +9,180 @@
|
||||
-->
|
||||
|
||||
<script>
|
||||
import { operationStore, query } from '@urql/svelte'
|
||||
import { getContext } from 'svelte'
|
||||
import { Card, Spinner } from 'sveltestrap'
|
||||
import MetricPlot from '../plots/MetricPlot.svelte'
|
||||
import JobInfo from './JobInfo.svelte'
|
||||
import { maxScope } from '../utils.js'
|
||||
import { queryStore, gql, getContextClient } from "@urql/svelte";
|
||||
import { getContext } from "svelte";
|
||||
import { Card, Spinner } from "sveltestrap";
|
||||
import MetricPlot from "../plots/MetricPlot.svelte";
|
||||
import JobInfo from "./JobInfo.svelte";
|
||||
import { maxScope } from "../utils.js";
|
||||
|
||||
export let job
|
||||
export let metrics
|
||||
export let plotWidth
|
||||
export let plotHeight = 275
|
||||
export let job;
|
||||
export let metrics;
|
||||
export let plotWidth;
|
||||
export let plotHeight = 275;
|
||||
|
||||
let scopes = [job.numNodes == 1 ? 'core' : 'node']
|
||||
let { id } = job;
|
||||
let scopes = [job.numNodes == 1 ? "core" : "node"];
|
||||
|
||||
const cluster = getContext('clusters').find(c => c.name == job.cluster)
|
||||
// Get all MetricConfs which include subCluster-specific settings for this job
|
||||
const metricConfig = getContext('metrics')
|
||||
const metricsQuery = operationStore(`query($id: ID!, $metrics: [String!]!, $scopes: [MetricScope!]!) {
|
||||
jobMetrics(id: $id, metrics: $metrics, scopes: $scopes) {
|
||||
name
|
||||
scope
|
||||
metric {
|
||||
unit { prefix, base }, timestep
|
||||
statisticsSeries { min, mean, max }
|
||||
series {
|
||||
hostname, id, data
|
||||
statistics { min, avg, max }
|
||||
const cluster = getContext("clusters").find((c) => c.name == job.cluster);
|
||||
const metricConfig = getContext("metrics"); // Get all MetricConfs which include subCluster-specific settings for this job
|
||||
const client = getContextClient();
|
||||
const query = gql`
|
||||
query ($id: ID!, $metrics: [String!]!, $scopes: [MetricScope!]!) {
|
||||
jobMetrics(id: $id, metrics: $metrics, scopes: $scopes) {
|
||||
name
|
||||
scope
|
||||
metric {
|
||||
unit {
|
||||
prefix
|
||||
base
|
||||
}
|
||||
timestep
|
||||
statisticsSeries {
|
||||
min
|
||||
mean
|
||||
max
|
||||
}
|
||||
series {
|
||||
hostname
|
||||
id
|
||||
data
|
||||
statistics {
|
||||
min
|
||||
avg
|
||||
max
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`, {
|
||||
id: job.id,
|
||||
metrics,
|
||||
scopes
|
||||
})
|
||||
`;
|
||||
|
||||
const selectScope = (jobMetrics) => jobMetrics.reduce(
|
||||
(a, b) => maxScope([a.scope, b.scope]) == a.scope
|
||||
? (job.numNodes > 1 ? a : b)
|
||||
: (job.numNodes > 1 ? b : a), jobMetrics[0])
|
||||
$: metricsQuery = queryStore({
|
||||
client: client,
|
||||
query: query,
|
||||
variables: { id, metrics, scopes }
|
||||
});
|
||||
|
||||
const sortAndSelectScope = (jobMetrics) => metrics
|
||||
.map(function(name) {
|
||||
// Get MetricConf for this selected/requested metric
|
||||
let thisConfig = metricConfig(cluster, name)
|
||||
let thisSCIndex = thisConfig.subClusters.findIndex(sc => sc.name == job.subCluster)
|
||||
// Check if Subcluster has MetricConf: If not found (index == -1), no further remove flag check required
|
||||
if (thisSCIndex >= 0) {
|
||||
// SubCluster Config present: Check if remove flag is set
|
||||
if (thisConfig.subClusters[thisSCIndex].remove == true) {
|
||||
// Return null data and informational flag
|
||||
return {removed: true, data: null}
|
||||
} else {
|
||||
// load and return metric, if data available
|
||||
let thisMetric = jobMetrics.filter(jobMetric => jobMetric.name == name) // Returns Array
|
||||
if (thisMetric.length > 0) {
|
||||
return {removed: false, data: thisMetric}
|
||||
function refresh() {
|
||||
queryStore({
|
||||
client: client,
|
||||
query: query,
|
||||
variables: { id, metrics, scopes }
|
||||
});
|
||||
}
|
||||
|
||||
const selectScope = (jobMetrics) =>
|
||||
jobMetrics.reduce(
|
||||
(a, b) =>
|
||||
maxScope([a.scope, b.scope]) == a.scope
|
||||
? job.numNodes > 1
|
||||
? a
|
||||
: b
|
||||
: job.numNodes > 1
|
||||
? b
|
||||
: a,
|
||||
jobMetrics[0]
|
||||
);
|
||||
|
||||
const sortAndSelectScope = (jobMetrics) =>
|
||||
metrics
|
||||
.map(function (name) {
|
||||
// Get MetricConf for this selected/requested metric
|
||||
let thisConfig = metricConfig(cluster, name);
|
||||
let thisSCIndex = -1
|
||||
if (thisConfig) {
|
||||
thisSCIndex = thisConfig.subClusters.findIndex(
|
||||
(sc) => sc.name == job.subCluster
|
||||
);
|
||||
};
|
||||
// Check if Subcluster has MetricConf: If not found (index == -1), no further remove flag check required
|
||||
if (thisSCIndex >= 0) {
|
||||
// SubCluster Config present: Check if remove flag is set
|
||||
if (thisConfig.subClusters[thisSCIndex].remove == true) {
|
||||
// Return null data and informational flag
|
||||
return { removed: true, data: null };
|
||||
} else {
|
||||
return {removed: false, data: null}
|
||||
// load and return metric, if data available
|
||||
let thisMetric = jobMetrics.filter(
|
||||
(jobMetric) => jobMetric.name == name
|
||||
); // Returns Array
|
||||
if (thisMetric.length > 0) {
|
||||
return { removed: false, data: thisMetric };
|
||||
} else {
|
||||
return { removed: false, data: null };
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No specific subCluster config: 'remove' flag not set, deemed false -> load and return metric, if data available
|
||||
let thisMetric = jobMetrics.filter(
|
||||
(jobMetric) => jobMetric.name == name
|
||||
); // Returns Array
|
||||
if (thisMetric.length > 0) {
|
||||
return { removed: false, data: thisMetric };
|
||||
} else {
|
||||
return { removed: false, data: null };
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No specific subCluster config: 'remove' flag not set, deemed false -> load and return metric, if data available
|
||||
let thisMetric = jobMetrics.filter(jobMetric => jobMetric.name == name) // Returns Array
|
||||
if (thisMetric.length > 0) {
|
||||
return {removed: false, data: thisMetric}
|
||||
})
|
||||
.map(function (jobMetrics) {
|
||||
if (jobMetrics.data != null && jobMetrics.data.length > 0) {
|
||||
return {
|
||||
removed: jobMetrics.removed,
|
||||
data: selectScope(jobMetrics.data),
|
||||
};
|
||||
} else {
|
||||
return {removed: false, data: null}
|
||||
return jobMetrics;
|
||||
}
|
||||
}
|
||||
})
|
||||
.map(function(jobMetrics) {
|
||||
if (jobMetrics.data != null && jobMetrics.data.length > 0) {
|
||||
return {removed: jobMetrics.removed, data: selectScope(jobMetrics.data)}
|
||||
} else {
|
||||
return jobMetrics
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
$: metricsQuery.variables = { id: job.id, metrics, scopes }
|
||||
|
||||
if (job.monitoringStatus)
|
||||
query(metricsQuery)
|
||||
if (job.monitoringStatus) refresh();
|
||||
</script>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<JobInfo job={job}/>
|
||||
<JobInfo {job} />
|
||||
</td>
|
||||
{#if job.monitoringStatus == 0 || job.monitoringStatus == 2}
|
||||
<td colspan="{metrics.length}">
|
||||
<td colspan={metrics.length}>
|
||||
<Card body color="warning">Not monitored or archiving failed</Card>
|
||||
</td>
|
||||
{:else if $metricsQuery.fetching}
|
||||
<td colspan="{metrics.length}" style="text-align: center;">
|
||||
<td colspan={metrics.length} style="text-align: center;">
|
||||
<Spinner secondary />
|
||||
</td>
|
||||
{:else if $metricsQuery.error}
|
||||
<td colspan="{metrics.length}">
|
||||
<td colspan={metrics.length}>
|
||||
<Card body color="danger" class="mb-3">
|
||||
{$metricsQuery.error.message.length > 500
|
||||
? $metricsQuery.error.message.substring(0, 499)+'...'
|
||||
? $metricsQuery.error.message.substring(0, 499) + "..."
|
||||
: $metricsQuery.error.message}
|
||||
</Card>
|
||||
</td>
|
||||
{:else}
|
||||
{#each sortAndSelectScope($metricsQuery.data.jobMetrics) as metric, i (metric || i)}
|
||||
<td>
|
||||
<!-- Subluster Metricconfig remove keyword for jobtables (joblist main, user joblist, project joblist) to be used here as toplevel case-->
|
||||
{#if metric.removed == false && metric.data != null}
|
||||
<MetricPlot
|
||||
width={plotWidth}
|
||||
height={plotHeight}
|
||||
timestep={metric.data.metric.timestep}
|
||||
scope={metric.data.scope}
|
||||
series={metric.data.metric.series}
|
||||
statisticsSeries={metric.data.metric.statisticsSeries}
|
||||
metric={metric.data.name}
|
||||
cluster={cluster}
|
||||
subCluster={job.subCluster}
|
||||
isShared={(job.exclusive != 1)}/>
|
||||
{:else if metric.removed == true && metric.data == null}
|
||||
<Card body color="info">Metric disabled for subcluster '{ job.subCluster }'</Card>
|
||||
{:else}
|
||||
<Card body color="warning">Missing Data</Card>
|
||||
{/if}
|
||||
<!-- Subluster Metricconfig remove keyword for jobtables (joblist main, user joblist, project joblist) to be used here as toplevel case-->
|
||||
{#if metric.removed == false && metric.data != null}
|
||||
<MetricPlot
|
||||
width={plotWidth}
|
||||
height={plotHeight}
|
||||
timestep={metric.data.metric.timestep}
|
||||
scope={metric.data.scope}
|
||||
series={metric.data.metric.series}
|
||||
statisticsSeries={metric.data.metric.statisticsSeries}
|
||||
metric={metric.data.name}
|
||||
{cluster}
|
||||
subCluster={job.subCluster}
|
||||
isShared={(job.exclusive != 1)}
|
||||
/>
|
||||
{:else if metric.removed == true && metric.data == null}
|
||||
<Card body color="info"
|
||||
>Metric disabled for subcluster '{job.subCluster}'</Card
|
||||
>
|
||||
{:else}
|
||||
<Card body color="warning">Missing Data</Card>
|
||||
{/if}
|
||||
</td>
|
||||
{/each}
|
||||
{/if}
|
||||
|
@@ -323,7 +323,7 @@
|
||||
|
||||
let ctx, canvasElement, prevWidth = width, prevHeight = height
|
||||
data = data != null ? data : (flopsAny && memBw
|
||||
? transformData(flopsAny, memBw, colorDots) // Use Metric Object from Parent
|
||||
? transformData(flopsAny.metric, memBw.metric, colorDots) // Use Metric Object from Parent
|
||||
: {
|
||||
tiles: tiles,
|
||||
xLabel: 'Intensity [FLOPS/byte]',
|
||||
|
@@ -1,8 +1,11 @@
|
||||
import { expiringCacheExchange } from './cache-exchange.js'
|
||||
import { initClient } from '@urql/svelte'
|
||||
import { setContext, getContext, hasContext, onDestroy, tick } from 'svelte'
|
||||
import { dedupExchange, fetchExchange } from '@urql/core'
|
||||
import { readable } from 'svelte/store'
|
||||
import { expiringCacheExchange } from "./cache-exchange.js";
|
||||
import {
|
||||
Client,
|
||||
setContextClient,
|
||||
fetchExchange,
|
||||
} from "@urql/svelte";
|
||||
import { setContext, getContext, hasContext, onDestroy, tick } from "svelte";
|
||||
import { readable } from "svelte/store";
|
||||
|
||||
/*
|
||||
* Call this function only at component initialization time!
|
||||
@@ -14,26 +17,29 @@ import { readable } from 'svelte/store'
|
||||
* - Adds 'clusters' to the context (object with cluster names as keys)
|
||||
* - Adds 'metrics' to the context, a function that takes a cluster and metric name and returns the MetricConfig (or undefined)
|
||||
*/
|
||||
export function init(extraInitQuery = '') {
|
||||
const jwt = hasContext('jwt')
|
||||
? getContext('jwt')
|
||||
: getContext('cc-config')['jwt']
|
||||
export function init(extraInitQuery = "") {
|
||||
const jwt = hasContext("jwt")
|
||||
? getContext("jwt")
|
||||
: getContext("cc-config")["jwt"];
|
||||
|
||||
const client = initClient({
|
||||
const client = new Client({
|
||||
url: `${window.location.origin}/query`,
|
||||
fetchOptions: jwt != null
|
||||
? { headers: { 'Authorization': `Bearer ${jwt}` } } : {},
|
||||
fetchOptions:
|
||||
jwt != null ? { headers: { Authorization: `Bearer ${jwt}` } } : {},
|
||||
exchanges: [
|
||||
dedupExchange,
|
||||
expiringCacheExchange({
|
||||
ttl: 5 * 60 * 1000,
|
||||
maxSize: 150,
|
||||
}),
|
||||
fetchExchange
|
||||
]
|
||||
})
|
||||
fetchExchange,
|
||||
],
|
||||
});
|
||||
|
||||
const query = client.query(`query {
|
||||
setContextClient(client);
|
||||
|
||||
const query = client
|
||||
.query(
|
||||
`query {
|
||||
clusters {
|
||||
name,
|
||||
metricConfig {
|
||||
@@ -61,227 +67,247 @@ export function init(extraInitQuery = '') {
|
||||
}
|
||||
tags { id, name, type }
|
||||
${extraInitQuery}
|
||||
}`).toPromise()
|
||||
}`
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
let state = { fetching: true, error: null, data: null }
|
||||
let subscribers = []
|
||||
let state = { fetching: true, error: null, data: null };
|
||||
let subscribers = [];
|
||||
const subscribe = (callback) => {
|
||||
callback(state)
|
||||
subscribers.push(callback)
|
||||
callback(state);
|
||||
subscribers.push(callback);
|
||||
return () => {
|
||||
subscribers = subscribers.filter(cb => cb != callback)
|
||||
}
|
||||
subscribers = subscribers.filter((cb) => cb != callback);
|
||||
};
|
||||
};
|
||||
|
||||
const tags = [], clusters = []
|
||||
setContext('tags', tags)
|
||||
setContext('clusters', clusters)
|
||||
setContext('metrics', (cluster, metric) => {
|
||||
if (typeof cluster !== 'object')
|
||||
cluster = clusters.find(c => c.name == cluster)
|
||||
const tags = [],
|
||||
clusters = [];
|
||||
setContext("tags", tags);
|
||||
setContext("clusters", clusters);
|
||||
setContext("metrics", (cluster, metric) => {
|
||||
if (typeof cluster !== "object")
|
||||
cluster = clusters.find((c) => c.name == cluster);
|
||||
|
||||
return cluster.metricConfig.find(m => m.name == metric)
|
||||
})
|
||||
setContext('on-init', callback => state.fetching
|
||||
? subscribers.push(callback)
|
||||
: callback(state))
|
||||
setContext('initialized', readable(false, (set) =>
|
||||
subscribers.push(() => set(true))))
|
||||
return cluster.metricConfig.find((m) => m.name == metric);
|
||||
});
|
||||
setContext("on-init", (callback) =>
|
||||
state.fetching ? subscribers.push(callback) : callback(state)
|
||||
);
|
||||
setContext(
|
||||
"initialized",
|
||||
readable(false, (set) => subscribers.push(() => set(true)))
|
||||
);
|
||||
|
||||
query.then(({ error, data }) => {
|
||||
state.fetching = false
|
||||
state.fetching = false;
|
||||
if (error != null) {
|
||||
console.error(error)
|
||||
state.error = error
|
||||
tick().then(() => subscribers.forEach(cb => cb(state)))
|
||||
return
|
||||
console.error(error);
|
||||
state.error = error;
|
||||
tick().then(() => subscribers.forEach((cb) => cb(state)));
|
||||
return;
|
||||
}
|
||||
|
||||
for (let tag of data.tags)
|
||||
tags.push(tag)
|
||||
for (let tag of data.tags) tags.push(tag);
|
||||
|
||||
for (let cluster of data.clusters)
|
||||
clusters.push(cluster)
|
||||
for (let cluster of data.clusters) clusters.push(cluster);
|
||||
|
||||
state.data = data
|
||||
tick().then(() => subscribers.forEach(cb => cb(state)))
|
||||
})
|
||||
state.data = data;
|
||||
tick().then(() => subscribers.forEach((cb) => cb(state)));
|
||||
});
|
||||
|
||||
return {
|
||||
query: { subscribe },
|
||||
tags,
|
||||
clusters,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function formatNumber(x) {
|
||||
let suffix = ''
|
||||
let suffix = "";
|
||||
if (x >= 1000000000) {
|
||||
x /= 1000000
|
||||
suffix = 'G'
|
||||
x /= 1000000;
|
||||
suffix = "G";
|
||||
} else if (x >= 1000000) {
|
||||
x /= 1000000
|
||||
suffix = 'M'
|
||||
x /= 1000000;
|
||||
suffix = "M";
|
||||
} else if (x >= 1000) {
|
||||
x /= 1000
|
||||
suffix = 'k'
|
||||
x /= 1000;
|
||||
suffix = "k";
|
||||
}
|
||||
|
||||
return `${(Math.round(x * 100) / 100)} ${suffix}`
|
||||
return `${Math.round(x * 100) / 100} ${suffix}`;
|
||||
}
|
||||
|
||||
// Use https://developer.mozilla.org/en-US/docs/Web/API/structuredClone instead?
|
||||
export function deepCopy(x) {
|
||||
return JSON.parse(JSON.stringify(x))
|
||||
return JSON.parse(JSON.stringify(x));
|
||||
}
|
||||
|
||||
function fuzzyMatch(term, string) {
|
||||
return string.toLowerCase().includes(term)
|
||||
return string.toLowerCase().includes(term);
|
||||
}
|
||||
|
||||
export function fuzzySearchTags(term, tags) {
|
||||
if (!tags)
|
||||
return []
|
||||
if (!tags) return [];
|
||||
|
||||
let results = []
|
||||
let termparts = term.split(':').map(s => s.trim()).filter(s => s.length > 0)
|
||||
let results = [];
|
||||
let termparts = term
|
||||
.split(":")
|
||||
.map((s) => s.trim())
|
||||
.filter((s) => s.length > 0);
|
||||
|
||||
if (termparts.length == 0) {
|
||||
results = tags.slice()
|
||||
results = tags.slice();
|
||||
} else if (termparts.length == 1) {
|
||||
for (let tag of tags)
|
||||
if (fuzzyMatch(termparts[0], tag.type)
|
||||
|| fuzzyMatch(termparts[0], tag.name))
|
||||
results.push(tag)
|
||||
if (
|
||||
fuzzyMatch(termparts[0], tag.type) ||
|
||||
fuzzyMatch(termparts[0], tag.name)
|
||||
)
|
||||
results.push(tag);
|
||||
} else if (termparts.length == 2) {
|
||||
for (let tag of tags)
|
||||
if (fuzzyMatch(termparts[0], tag.type)
|
||||
&& fuzzyMatch(termparts[1], tag.name))
|
||||
results.push(tag)
|
||||
if (
|
||||
fuzzyMatch(termparts[0], tag.type) &&
|
||||
fuzzyMatch(termparts[1], tag.name)
|
||||
)
|
||||
results.push(tag);
|
||||
}
|
||||
|
||||
return results.sort((a, b) => {
|
||||
if (a.type < b.type) return -1
|
||||
if (a.type > b.type) return 1
|
||||
if (a.name < b.name) return -1
|
||||
if (a.name > b.name) return 1
|
||||
return 0
|
||||
})
|
||||
if (a.type < b.type) return -1;
|
||||
if (a.type > b.type) return 1;
|
||||
if (a.name < b.name) return -1;
|
||||
if (a.name > b.name) return 1;
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
export function groupByScope(jobMetrics) {
|
||||
let metrics = new Map()
|
||||
let metrics = new Map();
|
||||
for (let metric of jobMetrics) {
|
||||
if (metrics.has(metric.name))
|
||||
metrics.get(metric.name).push(metric)
|
||||
else
|
||||
metrics.set(metric.name, [metric])
|
||||
if (metrics.has(metric.name)) metrics.get(metric.name).push(metric);
|
||||
else metrics.set(metric.name, [metric]);
|
||||
}
|
||||
|
||||
return [...metrics.values()].sort((a, b) => a[0].name.localeCompare(b[0].name))
|
||||
return [...metrics.values()].sort((a, b) =>
|
||||
a[0].name.localeCompare(b[0].name)
|
||||
);
|
||||
}
|
||||
|
||||
const scopeGranularity = {
|
||||
"node": 10,
|
||||
"socket": 5,
|
||||
"accelerator": 5,
|
||||
"core": 2,
|
||||
"hwthread": 1
|
||||
node: 10,
|
||||
socket: 5,
|
||||
accelerator: 5,
|
||||
core: 2,
|
||||
hwthread: 1,
|
||||
};
|
||||
|
||||
export function maxScope(scopes) {
|
||||
console.assert(scopes.length > 0 && scopes.every(x => scopeGranularity[x] != null))
|
||||
let sm = scopes[0], gran = scopeGranularity[scopes[0]]
|
||||
console.assert(
|
||||
scopes.length > 0 && scopes.every((x) => scopeGranularity[x] != null)
|
||||
);
|
||||
let sm = scopes[0],
|
||||
gran = scopeGranularity[scopes[0]];
|
||||
for (let scope of scopes) {
|
||||
let otherGran = scopeGranularity[scope]
|
||||
let otherGran = scopeGranularity[scope];
|
||||
if (otherGran > gran) {
|
||||
sm = scope
|
||||
gran = otherGran
|
||||
sm = scope;
|
||||
gran = otherGran;
|
||||
}
|
||||
}
|
||||
return sm
|
||||
return sm;
|
||||
}
|
||||
|
||||
export function minScope(scopes) {
|
||||
console.assert(scopes.length > 0 && scopes.every(x => scopeGranularity[x] != null))
|
||||
let sm = scopes[0], gran = scopeGranularity[scopes[0]]
|
||||
console.assert(
|
||||
scopes.length > 0 && scopes.every((x) => scopeGranularity[x] != null)
|
||||
);
|
||||
let sm = scopes[0],
|
||||
gran = scopeGranularity[scopes[0]];
|
||||
for (let scope of scopes) {
|
||||
let otherGran = scopeGranularity[scope]
|
||||
let otherGran = scopeGranularity[scope];
|
||||
if (otherGran < gran) {
|
||||
sm = scope
|
||||
gran = otherGran
|
||||
sm = scope;
|
||||
gran = otherGran;
|
||||
}
|
||||
}
|
||||
return sm
|
||||
return sm;
|
||||
}
|
||||
|
||||
export async function fetchMetrics(job, metrics, scopes) {
|
||||
if (job.monitoringStatus == 0)
|
||||
return null
|
||||
if (job.monitoringStatus == 0) return null;
|
||||
|
||||
let query = []
|
||||
let query = [];
|
||||
if (metrics != null) {
|
||||
for (let metric of metrics) {
|
||||
query.push(`metric=${metric}`)
|
||||
query.push(`metric=${metric}`);
|
||||
}
|
||||
}
|
||||
if (scopes != null) {
|
||||
for (let scope of scopes) {
|
||||
query.push(`scope=${scope}`)
|
||||
query.push(`scope=${scope}`);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
let res = await fetch(`/api/jobs/metrics/${job.id}${(query.length > 0) ? '?' : ''}${query.join('&')}`)
|
||||
let res = await fetch(
|
||||
`/api/jobs/metrics/${job.id}${query.length > 0 ? "?" : ""}${query.join(
|
||||
"&"
|
||||
)}`
|
||||
);
|
||||
if (res.status != 200) {
|
||||
return { error: { status: res.status, message: await res.text() } }
|
||||
return { error: { status: res.status, message: await res.text() } };
|
||||
}
|
||||
|
||||
return await res.json()
|
||||
return await res.json();
|
||||
} catch (e) {
|
||||
return { error: e }
|
||||
return { error: e };
|
||||
}
|
||||
}
|
||||
|
||||
export function fetchMetricsStore() {
|
||||
let set = null
|
||||
let prev = { fetching: true, error: null, data: null }
|
||||
let set = null;
|
||||
let prev = { fetching: true, error: null, data: null };
|
||||
return [
|
||||
readable(prev, (_set) => { set = _set }),
|
||||
(job, metrics, scopes) => fetchMetrics(job, metrics, scopes).then(res => {
|
||||
let next = { fetching: false, error: res.error, data: res.data }
|
||||
if (prev.data && next.data)
|
||||
next.data.jobMetrics.push(...prev.data.jobMetrics)
|
||||
readable(prev, (_set) => {
|
||||
set = _set;
|
||||
}),
|
||||
(job, metrics, scopes) =>
|
||||
fetchMetrics(job, metrics, scopes).then((res) => {
|
||||
let next = { fetching: false, error: res.error, data: res.data };
|
||||
if (prev.data && next.data)
|
||||
next.data.jobMetrics.push(...prev.data.jobMetrics);
|
||||
|
||||
prev = next
|
||||
set(next)
|
||||
})
|
||||
]
|
||||
prev = next;
|
||||
set(next);
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
export function stickyHeader(datatableHeaderSelector, updatePading) {
|
||||
const header = document.querySelector('header > nav.navbar')
|
||||
if (!header)
|
||||
return
|
||||
const header = document.querySelector("header > nav.navbar");
|
||||
if (!header) return;
|
||||
|
||||
let ticking = false, datatableHeader = null
|
||||
const onscroll = event => {
|
||||
if (ticking)
|
||||
return
|
||||
let ticking = false,
|
||||
datatableHeader = null;
|
||||
const onscroll = (event) => {
|
||||
if (ticking) return;
|
||||
|
||||
ticking = true
|
||||
ticking = true;
|
||||
window.requestAnimationFrame(() => {
|
||||
ticking = false
|
||||
ticking = false;
|
||||
if (!datatableHeader)
|
||||
datatableHeader = document.querySelector(datatableHeaderSelector)
|
||||
datatableHeader = document.querySelector(datatableHeaderSelector);
|
||||
|
||||
const top = datatableHeader.getBoundingClientRect().top
|
||||
updatePading(top < header.clientHeight
|
||||
? (header.clientHeight - top) + 10
|
||||
: 10)
|
||||
})
|
||||
}
|
||||
const top = datatableHeader.getBoundingClientRect().top;
|
||||
updatePading(
|
||||
top < header.clientHeight ? header.clientHeight - top + 10 : 10
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
document.addEventListener('scroll', onscroll)
|
||||
onDestroy(() => document.removeEventListener('scroll', onscroll))
|
||||
document.addEventListener("scroll", onscroll);
|
||||
onDestroy(() => document.removeEventListener("scroll", onscroll));
|
||||
}
|
||||
|
@@ -1,534 +0,0 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@babel/code-frame@^7.10.4":
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431"
|
||||
integrity sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==
|
||||
dependencies:
|
||||
"@babel/highlight" "^7.16.0"
|
||||
|
||||
"@babel/helper-validator-identifier@^7.15.7":
|
||||
version "7.15.7"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389"
|
||||
integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==
|
||||
|
||||
"@babel/highlight@^7.16.0":
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a"
|
||||
integrity sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.15.7"
|
||||
chalk "^2.0.0"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@graphql-typed-document-node/core@^3.1.0":
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.1.1.tgz#076d78ce99822258cf813ecc1e7fa460fa74d052"
|
||||
integrity sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg==
|
||||
|
||||
"@jridgewell/gen-mapping@^0.3.0":
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9"
|
||||
integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==
|
||||
dependencies:
|
||||
"@jridgewell/set-array" "^1.0.1"
|
||||
"@jridgewell/sourcemap-codec" "^1.4.10"
|
||||
"@jridgewell/trace-mapping" "^0.3.9"
|
||||
|
||||
"@jridgewell/resolve-uri@^3.0.3":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78"
|
||||
integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==
|
||||
|
||||
"@jridgewell/set-array@^1.0.1":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72"
|
||||
integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
|
||||
|
||||
"@jridgewell/source-map@^0.3.2":
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb"
|
||||
integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==
|
||||
dependencies:
|
||||
"@jridgewell/gen-mapping" "^0.3.0"
|
||||
"@jridgewell/trace-mapping" "^0.3.9"
|
||||
|
||||
"@jridgewell/sourcemap-codec@^1.4.10":
|
||||
version "1.4.14"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
|
||||
integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
|
||||
|
||||
"@jridgewell/trace-mapping@^0.3.9":
|
||||
version "0.3.14"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed"
|
||||
integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==
|
||||
dependencies:
|
||||
"@jridgewell/resolve-uri" "^3.0.3"
|
||||
"@jridgewell/sourcemap-codec" "^1.4.10"
|
||||
|
||||
"@popperjs/core@^2.9.2":
|
||||
version "2.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.0.tgz#6734f8ebc106a0860dff7f92bf90df193f0935d7"
|
||||
integrity sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ==
|
||||
|
||||
"@rollup/plugin-commonjs@^17.0.0":
|
||||
version "17.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-17.1.0.tgz#757ec88737dffa8aa913eb392fade2e45aef2a2d"
|
||||
integrity sha512-PoMdXCw0ZyvjpCMT5aV4nkL0QywxP29sODQsSGeDpr/oI49Qq9tRtAsb/LbYbDzFlOydVEqHmmZWFtXJEAX9ew==
|
||||
dependencies:
|
||||
"@rollup/pluginutils" "^3.1.0"
|
||||
commondir "^1.0.1"
|
||||
estree-walker "^2.0.1"
|
||||
glob "^7.1.6"
|
||||
is-reference "^1.2.1"
|
||||
magic-string "^0.25.7"
|
||||
resolve "^1.17.0"
|
||||
|
||||
"@rollup/plugin-node-resolve@^11.0.0":
|
||||
version "11.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz#82aa59397a29cd4e13248b106e6a4a1880362a60"
|
||||
integrity sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==
|
||||
dependencies:
|
||||
"@rollup/pluginutils" "^3.1.0"
|
||||
"@types/resolve" "1.17.1"
|
||||
builtin-modules "^3.1.0"
|
||||
deepmerge "^4.2.2"
|
||||
is-module "^1.0.0"
|
||||
resolve "^1.19.0"
|
||||
|
||||
"@rollup/plugin-replace@^2.4.1":
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz#a2d539314fbc77c244858faa523012825068510a"
|
||||
integrity sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==
|
||||
dependencies:
|
||||
"@rollup/pluginutils" "^3.1.0"
|
||||
magic-string "^0.25.7"
|
||||
|
||||
"@rollup/pluginutils@4":
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.1.1.tgz#1d4da86dd4eded15656a57d933fda2b9a08d47ec"
|
||||
integrity sha512-clDjivHqWGXi7u+0d2r2sBi4Ie6VLEAzWMIkvJLnDmxoOhBYOTfzGbOQBA32THHm11/LiJbd01tJUpJsbshSWQ==
|
||||
dependencies:
|
||||
estree-walker "^2.0.1"
|
||||
picomatch "^2.2.2"
|
||||
|
||||
"@rollup/pluginutils@^3.1.0":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b"
|
||||
integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==
|
||||
dependencies:
|
||||
"@types/estree" "0.0.39"
|
||||
estree-walker "^1.0.1"
|
||||
picomatch "^2.2.2"
|
||||
|
||||
"@types/estree@*":
|
||||
version "0.0.50"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83"
|
||||
integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==
|
||||
|
||||
"@types/estree@0.0.39":
|
||||
version "0.0.39"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
|
||||
integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
|
||||
|
||||
"@types/node@*":
|
||||
version "16.11.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.12.tgz#ac7fb693ac587ee182c3780c26eb65546a1a3c10"
|
||||
integrity sha512-+2Iggwg7PxoO5Kyhvsq9VarmPbIelXP070HMImEpbtGCoyWNINQj4wzjbQCXzdHTRXnqufutJb5KAURZANNBAw==
|
||||
|
||||
"@types/resolve@1.17.1":
|
||||
version "1.17.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6"
|
||||
integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@urql/core@^2.3.4":
|
||||
version "2.3.5"
|
||||
resolved "https://registry.yarnpkg.com/@urql/core/-/core-2.3.5.tgz#eb1cbbfe23236615ecb8e65850bb772d4f61b6b5"
|
||||
integrity sha512-kM/um4OjXmuN6NUS/FSm7dESEKWT7By1kCRCmjvU4+4uEoF1cd4TzIhQ7J1I3zbDAFhZzmThq9X0AHpbHAn3bA==
|
||||
dependencies:
|
||||
"@graphql-typed-document-node/core" "^3.1.0"
|
||||
wonka "^4.0.14"
|
||||
|
||||
"@urql/svelte@^1.3.0":
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@urql/svelte/-/svelte-1.3.2.tgz#7fc16253a36669dddec39755fc9c31077a9c279a"
|
||||
integrity sha512-L/fSKb+jTrxfeKbnA4+7T69sL0XlzMv4d9i0j9J+fCkBCpUOGgPsYzsyBttbVbjrlaw61Wrc6J2NKuokrd570w==
|
||||
dependencies:
|
||||
"@urql/core" "^2.3.4"
|
||||
wonka "^4.0.14"
|
||||
|
||||
acorn@^8.5.0:
|
||||
version "8.8.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8"
|
||||
integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==
|
||||
|
||||
ansi-styles@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
|
||||
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
|
||||
dependencies:
|
||||
color-convert "^1.9.0"
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
buffer-from@^1.0.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
|
||||
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
|
||||
|
||||
builtin-modules@^3.1.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887"
|
||||
integrity sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==
|
||||
|
||||
chalk@^2.0.0:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
||||
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
|
||||
dependencies:
|
||||
ansi-styles "^3.2.1"
|
||||
escape-string-regexp "^1.0.5"
|
||||
supports-color "^5.3.0"
|
||||
|
||||
color-convert@^1.9.0:
|
||||
version "1.9.3"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
||||
integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
|
||||
dependencies:
|
||||
color-name "1.1.3"
|
||||
|
||||
color-name@1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
|
||||
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
|
||||
|
||||
commander@^2.20.0:
|
||||
version "2.20.3"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
||||
|
||||
commondir@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
|
||||
integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
|
||||
|
||||
deepmerge@^4.2.2:
|
||||
version "4.2.2"
|
||||
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
|
||||
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
|
||||
|
||||
escape-string-regexp@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
||||
|
||||
estree-walker@^0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362"
|
||||
integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==
|
||||
|
||||
estree-walker@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700"
|
||||
integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==
|
||||
|
||||
estree-walker@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
|
||||
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
||||
|
||||
fsevents@~2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
|
||||
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
||||
|
||||
function-bind@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
||||
|
||||
glob@^7.1.6:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
|
||||
integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^3.0.4"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
graphql@^15.6.0:
|
||||
version "15.8.0"
|
||||
resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.8.0.tgz#33410e96b012fa3bdb1091cc99a94769db212b38"
|
||||
integrity sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==
|
||||
|
||||
has-flag@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
||||
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
|
||||
|
||||
has-flag@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
|
||||
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
|
||||
|
||||
has@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
|
||||
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
|
||||
dependencies:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
is-core-module@^2.2.0:
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548"
|
||||
integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==
|
||||
dependencies:
|
||||
has "^1.0.3"
|
||||
|
||||
is-module@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
|
||||
integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=
|
||||
|
||||
is-reference@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7"
|
||||
integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==
|
||||
dependencies:
|
||||
"@types/estree" "*"
|
||||
|
||||
jest-worker@^26.2.1:
|
||||
version "26.6.2"
|
||||
resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed"
|
||||
integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
merge-stream "^2.0.0"
|
||||
supports-color "^7.0.0"
|
||||
|
||||
js-tokens@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
|
||||
|
||||
magic-string@^0.25.7:
|
||||
version "0.25.7"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"
|
||||
integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==
|
||||
dependencies:
|
||||
sourcemap-codec "^1.4.4"
|
||||
|
||||
merge-stream@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
|
||||
integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
|
||||
|
||||
minimatch@^3.0.4:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
||||
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
once@^1.3.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
path-is-absolute@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
||||
|
||||
path-parse@^1.0.6:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
||||
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
||||
|
||||
picomatch@^2.2.2:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
|
||||
integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
|
||||
|
||||
randombytes@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
|
||||
integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
|
||||
dependencies:
|
||||
safe-buffer "^5.1.0"
|
||||
|
||||
require-relative@^0.8.7:
|
||||
version "0.8.7"
|
||||
resolved "https://registry.yarnpkg.com/require-relative/-/require-relative-0.8.7.tgz#7999539fc9e047a37928fa196f8e1563dabd36de"
|
||||
integrity sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=
|
||||
|
||||
resolve@^1.17.0, resolve@^1.19.0:
|
||||
version "1.20.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
|
||||
integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
|
||||
dependencies:
|
||||
is-core-module "^2.2.0"
|
||||
path-parse "^1.0.6"
|
||||
|
||||
rollup-plugin-css-only@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-css-only/-/rollup-plugin-css-only-3.1.0.tgz#6a701cc5b051c6b3f0961e69b108a9a118e1b1df"
|
||||
integrity sha512-TYMOE5uoD76vpj+RTkQLzC9cQtbnJNktHPB507FzRWBVaofg7KhIqq1kGbcVOadARSozWF883Ho9KpSPKH8gqA==
|
||||
dependencies:
|
||||
"@rollup/pluginutils" "4"
|
||||
|
||||
rollup-plugin-svelte@^7.0.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-svelte/-/rollup-plugin-svelte-7.1.0.tgz#d45f2b92b1014be4eb46b55aa033fb9a9c65f04d"
|
||||
integrity sha512-vopCUq3G+25sKjwF5VilIbiY6KCuMNHP1PFvx2Vr3REBNMDllKHFZN2B9jwwC+MqNc3UPKkjXnceLPEjTjXGXg==
|
||||
dependencies:
|
||||
require-relative "^0.8.7"
|
||||
rollup-pluginutils "^2.8.2"
|
||||
|
||||
rollup-plugin-terser@^7.0.0:
|
||||
version "7.0.2"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d"
|
||||
integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.10.4"
|
||||
jest-worker "^26.2.1"
|
||||
serialize-javascript "^4.0.0"
|
||||
terser "^5.0.0"
|
||||
|
||||
rollup-pluginutils@^2.8.2:
|
||||
version "2.8.2"
|
||||
resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e"
|
||||
integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==
|
||||
dependencies:
|
||||
estree-walker "^0.6.1"
|
||||
|
||||
rollup@^2.3.4:
|
||||
version "2.61.0"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.61.0.tgz#ccd927bcd6cc0c78a4689c918627a717977208f4"
|
||||
integrity sha512-teQ+T1mUYbyvGyUavCodiyA9hD4DxwYZJwr/qehZGhs1Z49vsmzelMVYMxGU4ZhGRKxYPupHuz5yzm/wj7VpWA==
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
safe-buffer@^5.1.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
||||
serialize-javascript@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa"
|
||||
integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==
|
||||
dependencies:
|
||||
randombytes "^2.1.0"
|
||||
|
||||
source-map-support@~0.5.20:
|
||||
version "0.5.21"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
|
||||
integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
|
||||
dependencies:
|
||||
buffer-from "^1.0.0"
|
||||
source-map "^0.6.0"
|
||||
|
||||
source-map@^0.6.0:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||
|
||||
sourcemap-codec@^1.4.4:
|
||||
version "1.4.8"
|
||||
resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
|
||||
integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
|
||||
|
||||
supports-color@^5.3.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
||||
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
|
||||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
supports-color@^7.0.0:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
|
||||
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
|
||||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
|
||||
svelte@^3.49.0:
|
||||
version "3.49.0"
|
||||
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.49.0.tgz#5baee3c672306de1070c3b7888fc2204e36a4029"
|
||||
integrity sha512-+lmjic1pApJWDfPCpUUTc1m8azDqYCG1JN9YEngrx/hUyIcFJo6VZhj0A1Ai0wqoHcEIuQy+e9tk+4uDgdtsFA==
|
||||
|
||||
sveltestrap@^5.6.1:
|
||||
version "5.6.3"
|
||||
resolved "https://registry.yarnpkg.com/sveltestrap/-/sveltestrap-5.6.3.tgz#afb81b00d0b378719988e5339f92254dce41194f"
|
||||
integrity sha512-/geTKJbPmJGzwHFKYC3NkUNDk/GKxrppgdSxcg58w/qcxs0S6RiN4PaQ1tgBKsdSrZDfbHfkFF+dybHAyUlV0A==
|
||||
dependencies:
|
||||
"@popperjs/core" "^2.9.2"
|
||||
|
||||
terser@^5.0.0:
|
||||
version "5.14.2"
|
||||
resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10"
|
||||
integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==
|
||||
dependencies:
|
||||
"@jridgewell/source-map" "^0.3.2"
|
||||
acorn "^8.5.0"
|
||||
commander "^2.20.0"
|
||||
source-map-support "~0.5.20"
|
||||
|
||||
uplot@^1.6.7:
|
||||
version "1.6.17"
|
||||
resolved "https://registry.yarnpkg.com/uplot/-/uplot-1.6.17.tgz#1f8fc07a0e48008798beca463523621ad66dcc46"
|
||||
integrity sha512-WHNHvDCXURn+Qwb3QUUzP6rOxx+3kUZUspREyhkqmXCxFIND99l5z9intTh+uPEt+/EEu7lCaMjSd1uTfuTXfg==
|
||||
|
||||
wonka@^4.0.14, wonka@^4.0.15:
|
||||
version "4.0.15"
|
||||
resolved "https://registry.yarnpkg.com/wonka/-/wonka-4.0.15.tgz#9aa42046efa424565ab8f8f451fcca955bf80b89"
|
||||
integrity sha512-U0IUQHKXXn6PFo9nqsHphVCE5m3IntqZNB9Jjn7EB1lrR7YTDY3YWgFvEvwniTzXSvOH/XMzAZaIfJF/LvHYXg==
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
Reference in New Issue
Block a user