data endpoint for entity 90008 (aka. a website)

cleanup

ptr.pet e7c0dcaf ebcd9b9d

verified
Waiting for spindle ...
+136 -181
+81 -74
deno.lock
··· 3 3 "specifiers": { 4 4 "npm:@darkvisitors/sdk@^1.6.0": "1.6.0", 5 5 "npm:@jsr/std__toml@1.0.11": "1.0.11", 6 - "npm:@neodrag/svelte@^2.3.3": "2.3.3_svelte@5.46.0__acorn@8.15.0", 6 + "npm:@neodrag/svelte@^2.3.3": "2.3.3_svelte@5.46.1__acorn@8.15.0", 7 7 "npm:@rowanmanning/feed-parser@^2.1.1": "2.1.1", 8 8 "npm:@skyware/bot@0.4": "0.4.0", 9 - "npm:@sveltejs/adapter-node@^5.4.0": "5.4.0_@sveltejs+kit@2.49.2__@sveltejs+vite-plugin-svelte@6.2.1___svelte@5.46.0____acorn@8.15.0___vite@7.3.0____@types+node@25.0.3____picomatch@4.0.3___@types+node@25.0.3__svelte@5.46.0___acorn@8.15.0__vite@7.3.0___@types+node@25.0.3___picomatch@4.0.3__acorn@8.15.0__@types+node@25.0.3_rollup@4.53.3_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.46.0___acorn@8.15.0__vite@7.3.0___@types+node@25.0.3___picomatch@4.0.3__@types+node@25.0.3_svelte@5.46.0__acorn@8.15.0_vite@7.3.0__@types+node@25.0.3__picomatch@4.0.3_@types+node@25.0.3", 10 - "npm:@sveltejs/kit@^2.49.2": "2.49.2_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.46.0___acorn@8.15.0__vite@7.3.0___@types+node@25.0.3___picomatch@4.0.3__@types+node@25.0.3_svelte@5.46.0__acorn@8.15.0_vite@7.3.0__@types+node@25.0.3__picomatch@4.0.3_acorn@8.15.0_@types+node@25.0.3", 11 - "npm:@sveltejs/vite-plugin-svelte@^6.2.1": "6.2.1_svelte@5.46.0__acorn@8.15.0_vite@7.3.0__@types+node@25.0.3__picomatch@4.0.3_@types+node@25.0.3", 9 + "npm:@sveltejs/adapter-node@^5.4.0": "5.4.0_@sveltejs+kit@2.49.4__@sveltejs+vite-plugin-svelte@6.2.4___svelte@5.46.1____acorn@8.15.0___vite@7.3.1____@types+node@25.0.6____picomatch@4.0.3___@types+node@25.0.6__svelte@5.46.1___acorn@8.15.0__typescript@5.9.3__vite@7.3.1___@types+node@25.0.6___picomatch@4.0.3__acorn@8.15.0__@types+node@25.0.6_rollup@4.53.3_@sveltejs+vite-plugin-svelte@6.2.4__svelte@5.46.1___acorn@8.15.0__vite@7.3.1___@types+node@25.0.6___picomatch@4.0.3__@types+node@25.0.6_svelte@5.46.1__acorn@8.15.0_typescript@5.9.3_vite@7.3.1__@types+node@25.0.6__picomatch@4.0.3_@types+node@25.0.6", 10 + "npm:@sveltejs/kit@^2.49.4": "2.49.4_@sveltejs+vite-plugin-svelte@6.2.4__svelte@5.46.1___acorn@8.15.0__vite@7.3.1___@types+node@25.0.6___picomatch@4.0.3__@types+node@25.0.6_svelte@5.46.1__acorn@8.15.0_typescript@5.9.3_vite@7.3.1__@types+node@25.0.6__picomatch@4.0.3_acorn@8.15.0_@types+node@25.0.6", 11 + "npm:@sveltejs/vite-plugin-svelte@^6.2.4": "6.2.4_svelte@5.46.1__acorn@8.15.0_vite@7.3.1__@types+node@25.0.6__picomatch@4.0.3_@types+node@25.0.6", 12 12 "npm:@tailwindcss/forms@~0.5.11": "0.5.11_tailwindcss@3.4.19__postcss@8.5.6__jiti@1.21.7", 13 13 "npm:@tailwindcss/typography@~0.5.19": "0.5.19_tailwindcss@3.4.19__postcss@8.5.6__jiti@1.21.7", 14 14 "npm:@types/deno@^2.5.0": "2.5.0", 15 15 "npm:@types/eslint@^9.6.1": "9.6.1", 16 16 "npm:@types/node-schedule@^2.1.8": "2.1.8", 17 - "npm:@types/node@^25.0.3": "25.0.3", 17 + "npm:@types/node@^25.0.6": "25.0.6", 18 18 "npm:autoprefixer@^10.4.23": "10.4.23_postcss@8.5.6", 19 19 "npm:eslint-config-prettier@^10.1.8": "10.1.8_eslint@9.39.2", 20 - "npm:eslint-plugin-svelte@^3.13.1": "3.13.1_eslint@9.39.2_svelte@5.46.0__acorn@8.15.0_postcss@8.5.6", 20 + "npm:eslint-plugin-svelte@^3.14.0": "3.14.0_eslint@9.39.2_svelte@5.46.1__acorn@8.15.0_postcss@8.5.6", 21 21 "npm:eslint@^9.39.2": "9.39.2", 22 22 "npm:globals@^16.5.0": "16.5.0", 23 - "npm:mdsvex@~0.12.6": "0.12.6_svelte@5.46.0__acorn@8.15.0", 23 + "npm:mdsvex@~0.12.6": "0.12.6_svelte@5.46.1__acorn@8.15.0", 24 24 "npm:nanoid@^5.1.6": "5.1.6", 25 25 "npm:node-fetch@^3.3.2": "3.3.2", 26 26 "npm:postcss@^8.5.6": "8.5.6", 27 - "npm:prettier-plugin-svelte@^3.4.1": "3.4.1_prettier@3.7.4_svelte@5.46.0__acorn@8.15.0", 27 + "npm:prettier-plugin-svelte@^3.4.1": "3.4.1_prettier@3.7.4_svelte@5.46.1__acorn@8.15.0", 28 28 "npm:prettier@^3.7.4": "3.7.4", 29 29 "npm:prometheus-remote-write@~0.5.1": "0.5.1_node-fetch@3.3.2", 30 30 "npm:robots-parser@^3.0.1": "3.0.1", 31 31 "npm:steamgriddb@^2.2.1": "2.2.1", 32 - "npm:svelte-check@^4.3.5": "4.3.5_svelte@5.46.0__acorn@8.15.0_typescript@5.9.3", 33 - "npm:svelte@^5.46.0": "5.46.0_acorn@8.15.0", 34 - "npm:sveltekit-rate-limiter@0.7": "0.7.0_@sveltejs+kit@2.49.2__@sveltejs+vite-plugin-svelte@6.2.1___svelte@5.46.0____acorn@8.15.0___vite@7.3.0____@types+node@25.0.3____picomatch@4.0.3___@types+node@25.0.3__svelte@5.46.0___acorn@8.15.0__vite@7.3.0___@types+node@25.0.3___picomatch@4.0.3__acorn@8.15.0__@types+node@25.0.3_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.46.0___acorn@8.15.0__vite@7.3.0___@types+node@25.0.3___picomatch@4.0.3__@types+node@25.0.3_svelte@5.46.0__acorn@8.15.0_vite@7.3.0__@types+node@25.0.3__picomatch@4.0.3_@types+node@25.0.3", 32 + "npm:svelte-check@^4.3.5": "4.3.5_svelte@5.46.1__acorn@8.15.0_typescript@5.9.3", 33 + "npm:svelte@^5.46.1": "5.46.1_acorn@8.15.0", 34 + "npm:sveltekit-rate-limiter@0.7": "0.7.0_@sveltejs+kit@2.49.4__@sveltejs+vite-plugin-svelte@6.2.4___svelte@5.46.1____acorn@8.15.0___vite@7.3.1____@types+node@25.0.6____picomatch@4.0.3___@types+node@25.0.6__svelte@5.46.1___acorn@8.15.0__typescript@5.9.3__vite@7.3.1___@types+node@25.0.6___picomatch@4.0.3__acorn@8.15.0__@types+node@25.0.6_@sveltejs+vite-plugin-svelte@6.2.4__svelte@5.46.1___acorn@8.15.0__vite@7.3.1___@types+node@25.0.6___picomatch@4.0.3__@types+node@25.0.6_svelte@5.46.1__acorn@8.15.0_typescript@5.9.3_vite@7.3.1__@types+node@25.0.6__picomatch@4.0.3_@types+node@25.0.6", 35 35 "npm:tailwindcss@^3.4.19": "3.4.19_postcss@8.5.6_jiti@1.21.7", 36 36 "npm:toad-scheduler@^3.1.0": "3.1.0", 37 37 "npm:tslib@^2.8.1": "2.8.1", 38 - "npm:typescript-eslint@^8.50.0": "8.50.0_eslint@9.39.2_typescript@5.9.3_@typescript-eslint+parser@8.50.0__eslint@9.39.2__typescript@5.9.3", 39 - "npm:typescript-svelte-plugin@~0.3.50": "0.3.50_svelte@5.46.0__acorn@8.15.0_typescript@5.9.3", 38 + "npm:typescript-eslint@^8.52.0": "8.52.0_eslint@9.39.2_typescript@5.9.3_@typescript-eslint+parser@8.52.0__eslint@9.39.2__typescript@5.9.3", 39 + "npm:typescript-svelte-plugin@~0.3.50": "0.3.50_svelte@5.46.1__acorn@8.15.0_typescript@5.9.3", 40 40 "npm:typescript@^5.9.3": "5.9.3", 41 - "npm:vite@^7.3.0": "7.3.0_@types+node@25.0.3_picomatch@4.0.3" 41 + "npm:vite@^7.3.1": "7.3.1_@types+node@25.0.6_picomatch@4.0.3" 42 42 }, 43 43 "npm": { 44 44 "@alloc/quick-lru@5.2.0": { ··· 266 266 "os": ["win32"], 267 267 "cpu": ["x64"] 268 268 }, 269 - "@eslint-community/eslint-utils@4.9.0_eslint@9.39.2": { 270 - "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", 269 + "@eslint-community/eslint-utils@4.9.1_eslint@9.39.2": { 270 + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", 271 271 "dependencies": [ 272 272 "eslint", 273 273 "eslint-visitor-keys@3.4.3" ··· 380 380 ], 381 381 "tarball": "https://npm.jsr.io/~/11/@jsr/std__toml/1.0.11.tgz" 382 382 }, 383 - "@neodrag/svelte@2.3.3_svelte@5.46.0__acorn@8.15.0": { 383 + "@neodrag/svelte@2.3.3_svelte@5.46.1__acorn@8.15.0": { 384 384 "integrity": "sha512-avXzhrilsBsnMFljhVAQ7h+6hbSIrvRCJ61GCiGbGISkC1QOhjDCNvPZo2+7KVwiYrnUBx4NRH0kTIqrcxv9Lg==", 385 385 "dependencies": [ 386 386 "svelte" ··· 653 653 "acorn" 654 654 ] 655 655 }, 656 - "@sveltejs/adapter-node@5.4.0_@sveltejs+kit@2.49.2__@sveltejs+vite-plugin-svelte@6.2.1___svelte@5.46.0____acorn@8.15.0___vite@7.3.0____@types+node@25.0.3____picomatch@4.0.3___@types+node@25.0.3__svelte@5.46.0___acorn@8.15.0__vite@7.3.0___@types+node@25.0.3___picomatch@4.0.3__acorn@8.15.0__@types+node@25.0.3_rollup@4.53.3_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.46.0___acorn@8.15.0__vite@7.3.0___@types+node@25.0.3___picomatch@4.0.3__@types+node@25.0.3_svelte@5.46.0__acorn@8.15.0_vite@7.3.0__@types+node@25.0.3__picomatch@4.0.3_@types+node@25.0.3": { 656 + "@sveltejs/adapter-node@5.4.0_@sveltejs+kit@2.49.4__@sveltejs+vite-plugin-svelte@6.2.4___svelte@5.46.1____acorn@8.15.0___vite@7.3.1____@types+node@25.0.6____picomatch@4.0.3___@types+node@25.0.6__svelte@5.46.1___acorn@8.15.0__typescript@5.9.3__vite@7.3.1___@types+node@25.0.6___picomatch@4.0.3__acorn@8.15.0__@types+node@25.0.6_rollup@4.53.3_@sveltejs+vite-plugin-svelte@6.2.4__svelte@5.46.1___acorn@8.15.0__vite@7.3.1___@types+node@25.0.6___picomatch@4.0.3__@types+node@25.0.6_svelte@5.46.1__acorn@8.15.0_typescript@5.9.3_vite@7.3.1__@types+node@25.0.6__picomatch@4.0.3_@types+node@25.0.6": { 657 657 "integrity": "sha512-NMsrwGVPEn+J73zH83Uhss/hYYZN6zT3u31R3IHAn3MiKC3h8fjmIAhLfTSOeNHr5wPYfjjMg8E+1gyFgyrEcQ==", 658 658 "dependencies": [ 659 659 "@rollup/plugin-commonjs", ··· 663 663 "rollup" 664 664 ] 665 665 }, 666 - "@sveltejs/kit@2.49.2_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.46.0___acorn@8.15.0__vite@7.3.0___@types+node@25.0.3___picomatch@4.0.3__@types+node@25.0.3_svelte@5.46.0__acorn@8.15.0_vite@7.3.0__@types+node@25.0.3__picomatch@4.0.3_acorn@8.15.0_@types+node@25.0.3": { 667 - "integrity": "sha512-Vp3zX/qlwerQmHMP6x0Ry1oY7eKKRcOWGc2P59srOp4zcqyn+etJyQpELgOi4+ZSUgteX8Y387NuwruLgGXLUQ==", 666 + "@sveltejs/kit@2.49.4_@sveltejs+vite-plugin-svelte@6.2.4__svelte@5.46.1___acorn@8.15.0__vite@7.3.1___@types+node@25.0.6___picomatch@4.0.3__@types+node@25.0.6_svelte@5.46.1__acorn@8.15.0_typescript@5.9.3_vite@7.3.1__@types+node@25.0.6__picomatch@4.0.3_acorn@8.15.0_@types+node@25.0.6": { 667 + "integrity": "sha512-JFtOqDoU0DI/+QSG8qnq5bKcehVb3tCHhOG4amsSYth5/KgO4EkJvi42xSAiyKmXAAULW1/Zdb6lkgGEgSxdZg==", 668 668 "dependencies": [ 669 669 "@standard-schema/spec", 670 670 "@sveltejs/acorn-typescript", ··· 681 681 "set-cookie-parser", 682 682 "sirv", 683 683 "svelte", 684 + "typescript", 684 685 "vite" 685 686 ], 687 + "optionalPeers": [ 688 + "typescript" 689 + ], 686 690 "bin": true 687 691 }, 688 - "@sveltejs/vite-plugin-svelte-inspector@5.0.1_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.46.0___acorn@8.15.0__vite@7.3.0___@types+node@25.0.3___picomatch@4.0.3__@types+node@25.0.3_svelte@5.46.0__acorn@8.15.0_vite@7.3.0__@types+node@25.0.3__picomatch@4.0.3_@types+node@25.0.3": { 692 + "@sveltejs/vite-plugin-svelte-inspector@5.0.1_@sveltejs+vite-plugin-svelte@6.2.4__svelte@5.46.1___acorn@8.15.0__vite@7.3.1___@types+node@25.0.6___picomatch@4.0.3__@types+node@25.0.6_svelte@5.46.1__acorn@8.15.0_vite@7.3.1__@types+node@25.0.6__picomatch@4.0.3_@types+node@25.0.6": { 689 693 "integrity": "sha512-ubWshlMk4bc8mkwWbg6vNvCeT7lGQojE3ijDh3QTR6Zr/R+GXxsGbyH4PExEPpiFmqPhYiVSVmHBjUcVc1JIrA==", 690 694 "dependencies": [ 691 695 "@sveltejs/vite-plugin-svelte", ··· 694 698 "vite" 695 699 ] 696 700 }, 697 - "@sveltejs/vite-plugin-svelte@6.2.1_svelte@5.46.0__acorn@8.15.0_vite@7.3.0__@types+node@25.0.3__picomatch@4.0.3_@types+node@25.0.3": { 698 - "integrity": "sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==", 701 + "@sveltejs/vite-plugin-svelte@6.2.4_svelte@5.46.1__acorn@8.15.0_vite@7.3.1__@types+node@25.0.6__picomatch@4.0.3_@types+node@25.0.6": { 702 + "integrity": "sha512-ou/d51QSdTyN26D7h6dSpusAKaZkAiGM55/AKYi+9AGZw7q85hElbjK3kEyzXHhLSnRISHOYzVge6x0jRZ7DXA==", 699 703 "dependencies": [ 700 704 "@sveltejs/vite-plugin-svelte-inspector", 701 - "debug", 702 705 "deepmerge", 703 706 "magic-string", 707 + "obug", 704 708 "svelte", 705 709 "vite", 706 710 "vitefu" ··· 757 761 "undici-types@6.21.0" 758 762 ] 759 763 }, 760 - "@types/node@25.0.3": { 761 - "integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==", 764 + "@types/node@25.0.6": { 765 + "integrity": "sha512-NNu0sjyNxpoiW3YuVFfNz7mxSQ+S4X2G28uqg2s+CzoqoQjLPsWSbsFFyztIAqt2vb8kfEAsJNepMGPTxFDx3Q==", 762 766 "dependencies": [ 763 767 "undici-types@7.16.0" 764 768 ] ··· 769 773 "@types/unist@2.0.11": { 770 774 "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" 771 775 }, 772 - "@typescript-eslint/eslint-plugin@8.50.0_@typescript-eslint+parser@8.50.0__eslint@9.39.2__typescript@5.9.3_eslint@9.39.2_typescript@5.9.3": { 773 - "integrity": "sha512-O7QnmOXYKVtPrfYzMolrCTfkezCJS9+ljLdKW/+DCvRsc3UAz+sbH6Xcsv7p30+0OwUbeWfUDAQE0vpabZ3QLg==", 776 + "@typescript-eslint/eslint-plugin@8.52.0_@typescript-eslint+parser@8.52.0__eslint@9.39.2__typescript@5.9.3_eslint@9.39.2_typescript@5.9.3": { 777 + "integrity": "sha512-okqtOgqu2qmZJ5iN4TWlgfF171dZmx2FzdOv2K/ixL2LZWDStL8+JgQerI2sa8eAEfoydG9+0V96m7V+P8yE1Q==", 774 778 "dependencies": [ 775 779 "@eslint-community/regexpp", 776 780 "@typescript-eslint/parser", ··· 785 789 "typescript" 786 790 ] 787 791 }, 788 - "@typescript-eslint/parser@8.50.0_eslint@9.39.2_typescript@5.9.3": { 789 - "integrity": "sha512-6/cmF2piao+f6wSxUsJLZjck7OQsYyRtcOZS02k7XINSNlz93v6emM8WutDQSXnroG2xwYlEVHJI+cPA7CPM3Q==", 792 + "@typescript-eslint/parser@8.52.0_eslint@9.39.2_typescript@5.9.3": { 793 + "integrity": "sha512-iIACsx8pxRnguSYhHiMn2PvhvfpopO9FXHyn1mG5txZIsAaB6F0KwbFnUQN3KCiG3Jcuad/Cao2FAs1Wp7vAyg==", 790 794 "dependencies": [ 791 795 "@typescript-eslint/scope-manager", 792 796 "@typescript-eslint/types", ··· 797 801 "typescript" 798 802 ] 799 803 }, 800 - "@typescript-eslint/project-service@8.50.0_typescript@5.9.3": { 801 - "integrity": "sha512-Cg/nQcL1BcoTijEWyx4mkVC56r8dj44bFDvBdygifuS20f3OZCHmFbjF34DPSi07kwlFvqfv/xOLnJ5DquxSGQ==", 804 + "@typescript-eslint/project-service@8.52.0_typescript@5.9.3": { 805 + "integrity": "sha512-xD0MfdSdEmeFa3OmVqonHi+Cciab96ls1UhIF/qX/O/gPu5KXD0bY9lu33jj04fjzrXHcuvjBcBC+D3SNSadaw==", 802 806 "dependencies": [ 803 807 "@typescript-eslint/tsconfig-utils", 804 808 "@typescript-eslint/types", ··· 806 810 "typescript" 807 811 ] 808 812 }, 809 - "@typescript-eslint/scope-manager@8.50.0": { 810 - "integrity": "sha512-xCwfuCZjhIqy7+HKxBLrDVT5q/iq7XBVBXLn57RTIIpelLtEIZHXAF/Upa3+gaCpeV1NNS5Z9A+ID6jn50VD4A==", 813 + "@typescript-eslint/scope-manager@8.52.0": { 814 + "integrity": "sha512-ixxqmmCcc1Nf8S0mS0TkJ/3LKcC8mruYJPOU6Ia2F/zUUR4pApW7LzrpU3JmtePbRUTes9bEqRc1Gg4iyRnDzA==", 811 815 "dependencies": [ 812 816 "@typescript-eslint/types", 813 817 "@typescript-eslint/visitor-keys" 814 818 ] 815 819 }, 816 - "@typescript-eslint/tsconfig-utils@8.50.0_typescript@5.9.3": { 817 - "integrity": "sha512-vxd3G/ybKTSlm31MOA96gqvrRGv9RJ7LGtZCn2Vrc5htA0zCDvcMqUkifcjrWNNKXHUU3WCkYOzzVSFBd0wa2w==", 820 + "@typescript-eslint/tsconfig-utils@8.52.0_typescript@5.9.3": { 821 + "integrity": "sha512-jl+8fzr/SdzdxWJznq5nvoI7qn2tNYV/ZBAEcaFMVXf+K6jmXvAFrgo/+5rxgnL152f//pDEAYAhhBAZGrVfwg==", 818 822 "dependencies": [ 819 823 "typescript" 820 824 ] 821 825 }, 822 - "@typescript-eslint/type-utils@8.50.0_eslint@9.39.2_typescript@5.9.3": { 823 - "integrity": "sha512-7OciHT2lKCewR0mFoBrvZJ4AXTMe/sYOe87289WAViOocEmDjjv8MvIOT2XESuKj9jp8u3SZYUSh89QA4S1kQw==", 826 + "@typescript-eslint/type-utils@8.52.0_eslint@9.39.2_typescript@5.9.3": { 827 + "integrity": "sha512-JD3wKBRWglYRQkAtsyGz1AewDu3mTc7NtRjR/ceTyGoPqmdS5oCdx/oZMWD5Zuqmo6/MpsYs0wp6axNt88/2EQ==", 824 828 "dependencies": [ 825 829 "@typescript-eslint/types", 826 830 "@typescript-eslint/typescript-estree", ··· 831 835 "typescript" 832 836 ] 833 837 }, 834 - "@typescript-eslint/types@8.50.0": { 835 - "integrity": "sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w==" 838 + "@typescript-eslint/types@8.52.0": { 839 + "integrity": "sha512-LWQV1V4q9V4cT4H5JCIx3481iIFxH1UkVk+ZkGGAV1ZGcjGI9IoFOfg3O6ywz8QqCDEp7Inlg6kovMofsNRaGg==" 836 840 }, 837 - "@typescript-eslint/typescript-estree@8.50.0_typescript@5.9.3": { 838 - "integrity": "sha512-W7SVAGBR/IX7zm1t70Yujpbk+zdPq/u4soeFSknWFdXIFuWsBGBOUu/Tn/I6KHSKvSh91OiMuaSnYp3mtPt5IQ==", 841 + "@typescript-eslint/typescript-estree@8.52.0_typescript@5.9.3": { 842 + "integrity": "sha512-XP3LClsCc0FsTK5/frGjolyADTh3QmsLp6nKd476xNI9CsSsLnmn4f0jrzNoAulmxlmNIpeXuHYeEQv61Q6qeQ==", 839 843 "dependencies": [ 840 844 "@typescript-eslint/project-service", 841 845 "@typescript-eslint/tsconfig-utils", ··· 849 853 "typescript" 850 854 ] 851 855 }, 852 - "@typescript-eslint/utils@8.50.0_eslint@9.39.2_typescript@5.9.3": { 853 - "integrity": "sha512-87KgUXET09CRjGCi2Ejxy3PULXna63/bMYv72tCAlDJC3Yqwln0HiFJ3VJMst2+mEtNtZu5oFvX4qJGjKsnAgg==", 856 + "@typescript-eslint/utils@8.52.0_eslint@9.39.2_typescript@5.9.3": { 857 + "integrity": "sha512-wYndVMWkweqHpEpwPhwqE2lnD2DxC6WVLupU/DOt/0/v+/+iQbbzO3jOHjmBMnhu0DgLULvOaU4h4pwHYi2oRQ==", 854 858 "dependencies": [ 855 859 "@eslint-community/eslint-utils", 856 860 "@typescript-eslint/scope-manager", ··· 860 864 "typescript" 861 865 ] 862 866 }, 863 - "@typescript-eslint/visitor-keys@8.50.0": { 864 - "integrity": "sha512-Xzmnb58+Db78gT/CCj/PVCvK+zxbnsw6F+O1oheYszJbBSdEjVhQi3C/Xttzxgi/GLmpvOggRs1RFpiJ8+c34Q==", 867 + "@typescript-eslint/visitor-keys@8.52.0": { 868 + "integrity": "sha512-ink3/Zofus34nmBsPjow63FP5M7IGff0RKAgqR6+CFpdk22M7aLwC9gOcLGYqr7MczLPzZVERW9hRog3O4n1sQ==", 865 869 "dependencies": [ 866 870 "@typescript-eslint/types", 867 871 "eslint-visitor-keys@4.2.1" ··· 1174 1178 ], 1175 1179 "bin": true 1176 1180 }, 1177 - "eslint-plugin-svelte@3.13.1_eslint@9.39.2_svelte@5.46.0__acorn@8.15.0_postcss@8.5.6": { 1178 - "integrity": "sha512-Ng+kV/qGS8P/isbNYVE3sJORtubB+yLEcYICMkUWNaDTb0SwZni/JhAYXh/Dz/q2eThUwWY0VMPZ//KYD1n3eQ==", 1181 + "eslint-plugin-svelte@3.14.0_eslint@9.39.2_svelte@5.46.1__acorn@8.15.0_postcss@8.5.6": { 1182 + "integrity": "sha512-Isw0GvaMm0yHxAj71edAdGFh28ufYs+6rk2KlbbZphnqZAzrH3Se3t12IFh2H9+1F/jlDhBBL4oiOJmLqmYX0g==", 1179 1183 "dependencies": [ 1180 1184 "@eslint-community/eslint-utils", 1181 1185 "@jridgewell/sourcemap-codec", ··· 1589 1593 "math-intrinsics@1.1.0": { 1590 1594 "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==" 1591 1595 }, 1592 - "mdsvex@0.12.6_svelte@5.46.0__acorn@8.15.0": { 1596 + "mdsvex@0.12.6_svelte@5.46.1__acorn@8.15.0": { 1593 1597 "integrity": "sha512-pupx2gzWh3hDtm/iDW4WuCpljmyHbHi34r7ktOqpPGvyiM4MyfNgdJ3qMizXdgCErmvYC9Nn/qyjePy+4ss9Wg==", 1594 1598 "dependencies": [ 1595 1599 "@types/mdast", ··· 1690 1694 }, 1691 1695 "object-hash@3.0.0": { 1692 1696 "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==" 1697 + }, 1698 + "obug@2.1.1": { 1699 + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==" 1693 1700 }, 1694 1701 "optionator@0.9.4": { 1695 1702 "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", ··· 1843 1850 "prelude-ls@1.2.1": { 1844 1851 "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" 1845 1852 }, 1846 - "prettier-plugin-svelte@3.4.1_prettier@3.7.4_svelte@5.46.0__acorn@8.15.0": { 1853 + "prettier-plugin-svelte@3.4.1_prettier@3.7.4_svelte@5.46.1__acorn@8.15.0": { 1847 1854 "integrity": "sha512-xL49LCloMoZRvSwa6IEdN2GV6cq2IqpYGstYtMT+5wmml1/dClEoI0MZR78MiVPpu6BdQFfN0/y73yO6+br5Pg==", 1848 1855 "dependencies": [ 1849 1856 "prettier", ··· 1884 1891 "@protobufjs/path", 1885 1892 "@protobufjs/pool", 1886 1893 "@protobufjs/utf8", 1887 - "@types/node@25.0.3", 1894 + "@types/node@25.0.6", 1888 1895 "long" 1889 1896 ], 1890 1897 "scripts": true ··· 2048 2055 "supports-preserve-symlinks-flag@1.0.0": { 2049 2056 "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" 2050 2057 }, 2051 - "svelte-check@4.3.5_svelte@5.46.0__acorn@8.15.0_typescript@5.9.3": { 2058 + "svelte-check@4.3.5_svelte@5.46.1__acorn@8.15.0_typescript@5.9.3": { 2052 2059 "integrity": "sha512-e4VWZETyXaKGhpkxOXP+B/d0Fp/zKViZoJmneZWe/05Y2aqSKj3YN2nLfYPJBQ87WEiY4BQCQ9hWGu9mPT1a1Q==", 2053 2060 "dependencies": [ 2054 2061 "@jridgewell/trace-mapping", ··· 2061 2068 ], 2062 2069 "bin": true 2063 2070 }, 2064 - "svelte-eslint-parser@1.4.1_svelte@5.46.0__acorn@8.15.0_postcss@8.5.6": { 2071 + "svelte-eslint-parser@1.4.1_svelte@5.46.1__acorn@8.15.0_postcss@8.5.6": { 2065 2072 "integrity": "sha512-1eqkfQ93goAhjAXxZiu1SaKI9+0/sxp4JIWQwUpsz7ybehRE5L8dNuz7Iry7K22R47p5/+s9EM+38nHV2OlgXA==", 2066 2073 "dependencies": [ 2067 2074 "eslint-scope", ··· 2076 2083 "svelte" 2077 2084 ] 2078 2085 }, 2079 - "svelte2tsx@0.7.45_svelte@5.46.0__acorn@8.15.0_typescript@5.9.3": { 2086 + "svelte2tsx@0.7.45_svelte@5.46.1__acorn@8.15.0_typescript@5.9.3": { 2080 2087 "integrity": "sha512-cSci+mYGygYBHIZLHlm/jYlEc1acjAHqaQaDFHdEBpUueM9kSTnPpvPtSl5VkJOU1qSJ7h1K+6F/LIUYiqC8VA==", 2081 2088 "dependencies": [ 2082 2089 "dedent-js", ··· 2085 2092 "typescript" 2086 2093 ] 2087 2094 }, 2088 - "svelte@5.46.0_acorn@8.15.0": { 2089 - "integrity": "sha512-ZhLtvroYxUxr+HQJfMZEDRsGsmU46x12RvAv/zi9584f5KOX7bUrEbhPJ7cKFmUvZTJXi/CFZUYwDC6M1FigPw==", 2095 + "svelte@5.46.1_acorn@8.15.0": { 2096 + "integrity": "sha512-ynjfCHD3nP2el70kN5Pmg37sSi0EjOm9FgHYQdC4giWG/hzO3AatzXXJJgP305uIhGQxSufJLuYWtkY8uK/8RA==", 2090 2097 "dependencies": [ 2091 2098 "@jridgewell/remapping", 2092 2099 "@jridgewell/sourcemap-codec", ··· 2105 2112 "zimmerframe" 2106 2113 ] 2107 2114 }, 2108 - "sveltekit-rate-limiter@0.7.0_@sveltejs+kit@2.49.2__@sveltejs+vite-plugin-svelte@6.2.1___svelte@5.46.0____acorn@8.15.0___vite@7.3.0____@types+node@25.0.3____picomatch@4.0.3___@types+node@25.0.3__svelte@5.46.0___acorn@8.15.0__vite@7.3.0___@types+node@25.0.3___picomatch@4.0.3__acorn@8.15.0__@types+node@25.0.3_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.46.0___acorn@8.15.0__vite@7.3.0___@types+node@25.0.3___picomatch@4.0.3__@types+node@25.0.3_svelte@5.46.0__acorn@8.15.0_vite@7.3.0__@types+node@25.0.3__picomatch@4.0.3_@types+node@25.0.3": { 2115 + "sveltekit-rate-limiter@0.7.0_@sveltejs+kit@2.49.4__@sveltejs+vite-plugin-svelte@6.2.4___svelte@5.46.1____acorn@8.15.0___vite@7.3.1____@types+node@25.0.6____picomatch@4.0.3___@types+node@25.0.6__svelte@5.46.1___acorn@8.15.0__typescript@5.9.3__vite@7.3.1___@types+node@25.0.6___picomatch@4.0.3__acorn@8.15.0__@types+node@25.0.6_@sveltejs+vite-plugin-svelte@6.2.4__svelte@5.46.1___acorn@8.15.0__vite@7.3.1___@types+node@25.0.6___picomatch@4.0.3__@types+node@25.0.6_svelte@5.46.1__acorn@8.15.0_typescript@5.9.3_vite@7.3.1__@types+node@25.0.6__picomatch@4.0.3_@types+node@25.0.6": { 2109 2116 "integrity": "sha512-aQI8Y1dTWKsB4YiZMBYORMDwy2SaFA2J5t848dEPVNkXWzhqrHqHUBb7QiNiLWqAeWvOJBwD+MZnsbmvbhGQdg==", 2110 2117 "dependencies": [ 2111 2118 "@isaacs/ttlcache", ··· 2177 2184 "totalist@3.0.1": { 2178 2185 "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==" 2179 2186 }, 2180 - "ts-api-utils@2.1.0_typescript@5.9.3": { 2181 - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", 2187 + "ts-api-utils@2.4.0_typescript@5.9.3": { 2188 + "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", 2182 2189 "dependencies": [ 2183 2190 "typescript" 2184 2191 ] ··· 2195 2202 "prelude-ls" 2196 2203 ] 2197 2204 }, 2198 - "typescript-eslint@8.50.0_eslint@9.39.2_typescript@5.9.3_@typescript-eslint+parser@8.50.0__eslint@9.39.2__typescript@5.9.3": { 2199 - "integrity": "sha512-Q1/6yNUmCpH94fbgMUMg2/BSAr/6U7GBk61kZTv1/asghQOWOjTlp9K8mixS5NcJmm2creY+UFfGeW/+OcA64A==", 2205 + "typescript-eslint@8.52.0_eslint@9.39.2_typescript@5.9.3_@typescript-eslint+parser@8.52.0__eslint@9.39.2__typescript@5.9.3": { 2206 + "integrity": "sha512-atlQQJ2YkO4pfTVQmQ+wvYQwexPDOIgo+RaVcD7gHgzy/IQA+XTyuxNM9M9TVXvttkF7koBHmcwisKdOAf2EcA==", 2200 2207 "dependencies": [ 2201 2208 "@typescript-eslint/eslint-plugin", 2202 2209 "@typescript-eslint/parser", ··· 2206 2213 "typescript" 2207 2214 ] 2208 2215 }, 2209 - "typescript-svelte-plugin@0.3.50_svelte@5.46.0__acorn@8.15.0_typescript@5.9.3": { 2216 + "typescript-svelte-plugin@0.3.50_svelte@5.46.1__acorn@8.15.0_typescript@5.9.3": { 2210 2217 "integrity": "sha512-CD6jMNAYJwqCyQ5zZBDRuveeJvAgIogLwXMf5eXAl4K36wD8W+Npw49h6j5fXnpd7SKcG3uptGpeCGETED6WSA==", 2211 2218 "dependencies": [ 2212 2219 "@jridgewell/sourcemap-codec", ··· 2272 2279 "unist-util-stringify-position" 2273 2280 ] 2274 2281 }, 2275 - "vite@7.3.0_@types+node@25.0.3_picomatch@4.0.3": { 2276 - "integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==", 2282 + "vite@7.3.1_@types+node@25.0.6_picomatch@4.0.3": { 2283 + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", 2277 2284 "dependencies": [ 2278 - "@types/node@25.0.3", 2285 + "@types/node@25.0.6", 2279 2286 "esbuild", 2280 2287 "fdir", 2281 2288 "picomatch@4.0.3", ··· 2287 2294 "fsevents" 2288 2295 ], 2289 2296 "optionalPeers": [ 2290 - "@types/node@25.0.3" 2297 + "@types/node@25.0.6" 2291 2298 ], 2292 2299 "bin": true 2293 2300 }, 2294 - "vitefu@1.1.1_vite@7.3.0__@types+node@25.0.3__picomatch@4.0.3_@types+node@25.0.3": { 2301 + "vitefu@1.1.1_vite@7.3.1__@types+node@25.0.6__picomatch@4.0.3_@types+node@25.0.6": { 2295 2302 "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", 2296 2303 "dependencies": [ 2297 2304 "vite" ··· 2337 2344 "npm:@rowanmanning/feed-parser@^2.1.1", 2338 2345 "npm:@skyware/bot@0.4", 2339 2346 "npm:@sveltejs/adapter-node@^5.4.0", 2340 - "npm:@sveltejs/kit@^2.49.2", 2341 - "npm:@sveltejs/vite-plugin-svelte@^6.2.1", 2347 + "npm:@sveltejs/kit@^2.49.4", 2348 + "npm:@sveltejs/vite-plugin-svelte@^6.2.4", 2342 2349 "npm:@tailwindcss/forms@~0.5.11", 2343 2350 "npm:@tailwindcss/typography@~0.5.19", 2344 2351 "npm:@types/deno@^2.5.0", 2345 2352 "npm:@types/eslint@^9.6.1", 2346 2353 "npm:@types/node-schedule@^2.1.8", 2347 - "npm:@types/node@^25.0.3", 2354 + "npm:@types/node@^25.0.6", 2348 2355 "npm:autoprefixer@^10.4.23", 2349 2356 "npm:eslint-config-prettier@^10.1.8", 2350 - "npm:eslint-plugin-svelte@^3.13.1", 2357 + "npm:eslint-plugin-svelte@^3.14.0", 2351 2358 "npm:eslint@^9.39.2", 2352 2359 "npm:globals@^16.5.0", 2353 2360 "npm:mdsvex@~0.12.6", ··· 2360 2367 "npm:robots-parser@^3.0.1", 2361 2368 "npm:steamgriddb@^2.2.1", 2362 2369 "npm:svelte-check@^4.3.5", 2363 - "npm:svelte@^5.46.0", 2370 + "npm:svelte@^5.46.1", 2364 2371 "npm:sveltekit-rate-limiter@0.7", 2365 2372 "npm:tailwindcss@^3.4.19", 2366 2373 "npm:toad-scheduler@^3.1.0", 2367 2374 "npm:tslib@^2.8.1", 2368 - "npm:typescript-eslint@^8.50.0", 2375 + "npm:typescript-eslint@^8.52.0", 2369 2376 "npm:typescript-svelte-plugin@~0.3.50", 2370 2377 "npm:typescript@^5.9.3", 2371 - "npm:vite@^7.3.0" 2378 + "npm:vite@^7.3.1" 2372 2379 ] 2373 2380 } 2374 2381 }
+7 -1
eunomia/deno.json
··· 1 - {} 1 + { 2 + "lint": { 3 + "rules": { 4 + "exclude": ["no-local"] 5 + } 6 + } 7 + }
+7 -7
eunomia/package.json
··· 9 9 }, 10 10 "devDependencies": { 11 11 "@sveltejs/adapter-node": "^5.4.0", 12 - "@sveltejs/kit": "^2.49.2", 13 - "@sveltejs/vite-plugin-svelte": "^6.2.1", 12 + "@sveltejs/kit": "^2.49.4", 13 + "@sveltejs/vite-plugin-svelte": "^6.2.4", 14 14 "@tailwindcss/forms": "^0.5.11", 15 15 "@tailwindcss/typography": "^0.5.19", 16 16 "@types/deno": "^2.5.0", 17 17 "@types/eslint": "^9.6.1", 18 - "@types/node": "^25.0.3", 18 + "@types/node": "^25.0.6", 19 19 "autoprefixer": "^10.4.23", 20 20 "eslint": "^9.39.2", 21 21 "eslint-config-prettier": "^10.1.8", 22 - "eslint-plugin-svelte": "^3.13.1", 22 + "eslint-plugin-svelte": "^3.14.0", 23 23 "globals": "^16.5.0", 24 24 "mdsvex": "^0.12.6", 25 25 "postcss": "^8.5.6", 26 26 "prettier": "^3.7.4", 27 27 "prettier-plugin-svelte": "^3.4.1", 28 - "svelte": "^5.46.0", 28 + "svelte": "^5.46.1", 29 29 "svelte-check": "^4.3.5", 30 30 "sveltekit-rate-limiter": "^0.7.0", 31 31 "tailwindcss": "^3.4.19", 32 32 "tslib": "^2.8.1", 33 33 "typescript": "^5.9.3", 34 - "typescript-eslint": "^8.50.0", 34 + "typescript-eslint": "^8.52.0", 35 35 "typescript-svelte-plugin": "^0.3.50", 36 - "vite": "^7.3.0" 36 + "vite": "^7.3.1" 37 37 }, 38 38 "type": "module", 39 39 "dependencies": {
+2 -2
eunomia/src/components/eye.svelte
··· 32 32 let src = $derived(closed ? `/eyes/closed.webp` : `/eyes/${kind}_${look}.webp`); 33 33 34 34 // generate dollcode based on time, but mod by 3 hours 35 - const timeDollcode = genDollcode((visits[0] / 1000) % (60 * 60 * 24)); 36 - const visitsDollcode = genDollcode(visits.length); 35 + const timeDollcode = $derived(genDollcode((visits[0] / 1000) % (60 * 60 * 24))); 36 + const visitsDollcode = $derived(genDollcode(visits.length)); 37 37 38 38 randomizeLook(); 39 39 </script>
+32 -47
eunomia/src/hooks.server.ts
··· 1 - import { updateLastPosts } from '$lib/bluesky'; 2 - import { getLastTrack, updateNowPlayingTrack } from '$lib/lastfm'; 3 - import { steamReadLastGame, steamUpdateNowPlaying } from '$lib/steam'; 4 - import { updateCommits } from '$lib/activity'; 5 - import { ToadScheduler, SimpleIntervalJob, Task, AsyncTask } from 'toad-scheduler'; 1 + import { updateLastPosts } from './lib/bluesky.ts'; 2 + import { updateNowPlayingTrack } from '$lib/lastfm.ts'; 3 + import { steamUpdateNowPlaying } from '$lib/steam.ts'; 4 + import { updateCommits } from '$lib/activity.ts'; 5 + import { ToadScheduler, SimpleIntervalJob, AsyncTask } from 'toad-scheduler'; 6 6 import { 7 7 incrementFakeVisitCount, 8 8 incrementLegitVisitCount, 9 9 pushMetric, 10 10 sendAllMetrics 11 - } from '$lib/metrics'; 12 - import { 13 - addLastVisitor, 14 - decrementVisitCount, 15 - incrementVisitCount, 16 - notifyDarkVisitors, 17 - removeLastVisitor 18 - } from '$lib/visits'; 19 - import { testUa } from '$lib/robots'; 11 + } from '$lib/metrics.ts'; 12 + import { addLastVisitor, notifyDarkVisitors, removeLastVisitor } from '$lib/visits.ts'; 13 + import { testUa } from '$lib/robots.ts'; 20 14 import { error, type Handle } from '@sveltejs/kit'; 21 - import { _fetchEntries } from './routes/(site)/guestbook/+page.server'; 15 + import { _fetchEntries } from './routes/(site)/guestbook/+page.server.ts'; 22 16 import { sequence } from '@sveltejs/kit/hooks'; 23 17 24 18 const updateNowPlaying = async () => { ··· 57 51 ); 58 52 59 53 const corsHandler = (allowedOrigins = ['*']) => { 60 - return async ({ event, resolve }: Parameters<Handle>[0]) => { 61 - const origin = event.request.headers.get('origin'); 62 - 63 - const corsHeaders: Record<string, string> = { 64 - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS', 65 - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', 66 - }; 54 + return async ({ event, resolve }: Parameters<Handle>[0]) => { 55 + const origin = event.request.headers.get('origin'); 56 + 57 + const corsHeaders: Record<string, string> = { 58 + 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS', 59 + 'Access-Control-Allow-Headers': 'Content-Type, Authorization' 60 + }; 61 + 62 + if (allowedOrigins.includes('*')) corsHeaders['Access-Control-Allow-Origin'] = '*'; 63 + else if (origin && allowedOrigins.includes(origin)) { 64 + corsHeaders['Access-Control-Allow-Origin'] = origin; 65 + corsHeaders['Access-Control-Allow-Credentials'] = 'true'; 66 + } 67 + 68 + if (event.request.method === 'OPTIONS') return new Response(null, { headers: corsHeaders }); 67 69 68 - if (allowedOrigins.includes('*')) 69 - corsHeaders['Access-Control-Allow-Origin'] = '*'; 70 - else if (origin && allowedOrigins.includes(origin)) { 71 - corsHeaders['Access-Control-Allow-Origin'] = origin; 72 - corsHeaders['Access-Control-Allow-Credentials'] = 'true'; 73 - } 70 + const response = await resolve(event); 74 71 75 - if (event.request.method === 'OPTIONS') 76 - return new Response(null, { headers: corsHeaders }); 77 - 78 - const response = await resolve(event); 79 - 80 - Object.entries(corsHeaders).forEach(([key, value]) => { 81 - response.headers.set(key, value); 82 - }); 72 + Object.entries(corsHeaders).forEach(([key, value]) => { 73 + response.headers.set(key, value); 74 + }); 83 75 84 - return response; 85 - }; 86 - } 76 + return response; 77 + }; 78 + }; 87 79 88 80 const handler = async ({ event, resolve }: Parameters<Handle>[0]) => { 89 81 notifyDarkVisitors(event.url, event.request); // no await so it doesnt block ··· 117 109 118 110 // only add visitors if its a "legit" page visit 119 111 let id = null; 120 - let valid = false; 121 112 if (isPageVisit && !isRss()) { 122 113 id = addLastVisitor(event.request, event.cookies); 123 - valid = await incrementVisitCount(event.request, event.cookies); 124 114 } 125 115 126 116 // actually resolve event ··· 128 118 // remove visitors if it was a 404 129 119 if (resp.status === 404) { 130 120 if (id !== null) removeLastVisitor(id); 131 - if (valid) decrementVisitCount(); 132 121 } 133 122 134 123 return resp; 135 124 }; 136 125 137 - const allowedOrigins = [ 138 - "https://gaze.systems", 139 - "https://ptr.pet", 140 - "https://poor.dog", 141 - ]; 126 + const allowedOrigins = ['https://gaze.systems', 'https://ptr.pet', 'https://poor.dog']; 142 127 export const handle = sequence(corsHandler(allowedOrigins), handler);
+3 -1
eunomia/src/lib/counter.ts
··· 10 10 let countRaw: string | null = null; 11 11 try { 12 12 countRaw = await Deno.readTextFile(filePath); 13 - } catch {} 13 + } catch { 14 + // we use initial value if not found 15 + } 14 16 15 17 const counter = writable(parseInt(countRaw ?? initialValue.toString())); 16 18
+2 -41
eunomia/src/lib/visits.ts
··· 1 - import { env } from '$env/dynamic/private'; 2 - import { scopeCookies } from '$lib'; 3 - import { DarkVisitors } from '@darkvisitors/sdk'; 1 + import { scopeCookies } from '$lib/index.ts'; 4 2 import type { Cookies } from '@sveltejs/kit'; 5 3 import { nanoid } from 'nanoid'; 6 4 import { get, writable } from 'svelte/store'; 7 - import { darkVisitors } from './darkvisitors'; 8 - 9 - const visitCountFile = `${env.WEBSITE_DATA_DIR}/visitcount`; 10 - const readVisitCount = async () => { 11 - try { 12 - return parseInt(await Deno.readTextFile(visitCountFile)); 13 - } catch { 14 - return 0; 15 - } 16 - }; 17 - export const visitCount = writable(await readVisitCount()); 5 + import { darkVisitors } from './darkvisitors.ts'; 18 6 19 7 export type Visitor = { visits: number[] }; 20 8 export const lastVisitors = writable<Map<string, Visitor>>(new Map()); 21 9 const VISITOR_EXPIRY_SECONDS = 60 * 60; // an hour seems reasonable 22 - 23 - export const decrementVisitCount = () => { 24 - visitCount.set(get(visitCount) - 1); 25 - }; 26 - 27 - export const incrementVisitCount = async (request: Request, cookies: Cookies) => { 28 - let currentVisitCount = get(visitCount); 29 - // check whether the request is from a bot or not (this doesnt need to be accurate we just want to filter out honest bots) 30 - if (isBot(request)) return false; 31 - const scopedCookies = scopeCookies(cookies, '/'); 32 - // parse the last visit timestamp from cookies if it exists 33 - const visitedTimestamp = parseInt(scopedCookies.get('visitedTimestamp') || '0'); 34 - // get unix timestamp 35 - const currentTime = Date.now(); 36 - const timeSinceVisit = currentTime - visitedTimestamp; 37 - // check if this is the first time a client is visiting or if an hour has passed since they last visited 38 - if (visitedTimestamp === 0 || timeSinceVisit > 1000 * 60 * 60 * 24) { 39 - // increment current and write to the store 40 - currentVisitCount += 1; 41 - visitCount.set(currentVisitCount); 42 - // update the cookie with the current timestamp 43 - scopedCookies.set('visitedTimestamp', currentTime.toString()); 44 - // write the visit count to a file so we can load it later again 45 - await Deno.writeTextFile(visitCountFile, currentVisitCount.toString()); 46 - } 47 - return true; 48 - }; 49 10 50 11 export const removeLastVisitor = (id: string) => { 51 12 const visitors = get(lastVisitors);
+1 -2
eunomia/src/routes/(site)/+layout.server.ts
··· 1 1 import { getRequestEvent } from '$app/server'; 2 2 import { newToken as getApiToken } from '$lib/apiToken.js'; 3 3 import { bounceCount, distanceTravelled } from '$lib/metrics.js'; 4 - import { lastVisitors, visitCount } from '$lib/visits.js'; 4 + import { lastVisitors } from '$lib/visits.js'; 5 5 import { isIPv6 } from 'node:net'; 6 6 import { get } from 'svelte/store'; 7 7 ··· 62 62 route: url.pathname, 63 63 petTotalBounce: bounceCount.get(), 64 64 petTotalDistance: distanceTravelled.get(), 65 - visitCount: get(visitCount), 66 65 lastVisitors: visitors, 67 66 recentVisitCount, 68 67 eyePositions,
-1
eunomia/src/routes/(site)/+layout.svelte
··· 269 269 ></nobr 270 270 > 271 271 {/snippet} 272 - {@render stat('total visits', data.visitCount)} 273 272 {@render stat('uniq recent visits', data.lastVisitors.size)} 274 273 {@render stat('pet global bounce', data.petTotalBounce)} 275 274 {@render stat('pet global travel', data.petTotalDistance)}
+1 -5
eunomia/tsconfig.json
··· 5 5 "checkJs": true, 6 6 "esModuleInterop": true, 7 7 "forceConsistentCasingInFileNames": true, 8 + "allowImportingTsExtensions": true, 8 9 "resolveJsonModule": true, 9 10 "skipLibCheck": true, 10 11 "sourceMap": true, ··· 16 17 } 17 18 ] 18 19 } 19 - // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias 20 - // except $lib which is handled by https://kit.svelte.dev/docs/configuration#files 21 - // 22 - // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes 23 - // from the referenced tsconfig.json - TypeScript does not merge them in 24 20 }