@volter/world-console 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -4
- package/client/console.css +192 -106
- package/client/console.tsx +1239 -492
- package/client/kit/kit.css +279 -0
- package/client/kit/kit.tsx +259 -0
- package/client/vendor-logos.ts +42 -0
- package/dist/client/console.bundle.js +126 -113
- package/dist/client/console.css +192 -106
- package/dist/client/console.tsx +1239 -492
- package/dist/client/kit/kit.css +279 -0
- package/dist/client/kit/kit.tsx +259 -0
- package/dist/client/vendor-logos.ts +42 -0
- package/dist/src/console.d.ts +20 -11
- package/dist/src/console.js +36 -24
- package/package.json +8 -6
- package/src/console.ts +43 -30
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// GENERATED from Simple Icons (https://simpleicons.org, CC0 1.0), simple-icons@13: each vendor's mark and brand colour,
|
|
2
|
+
// for the console's vendor tiles. A vendor not here shows its initial. A near-black mark draws in the text's colour.
|
|
3
|
+
export const VENDOR_LOGOS: Record<string, { title: string; fill: string; d: string }> = {
|
|
4
|
+
"x": { title: "X", fill: 'currentColor', d: "M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z" },
|
|
5
|
+
"youtube": { title: "YouTube", fill: "#FF0000", d: "M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z" },
|
|
6
|
+
"tiktok": { title: "TikTok", fill: 'currentColor', d: "M12.525.02c1.31-.02 2.61-.01 3.91-.02.08 1.53.63 3.09 1.75 4.17 1.12 1.11 2.7 1.62 4.24 1.79v4.03c-1.44-.05-2.89-.35-4.2-.97-.57-.26-1.1-.59-1.62-.93-.01 2.92.01 5.84-.02 8.75-.08 1.4-.54 2.79-1.35 3.94-1.31 1.92-3.58 3.17-5.91 3.21-1.43.08-2.86-.31-4.08-1.03-2.02-1.19-3.44-3.37-3.65-5.71-.02-.5-.03-1-.01-1.49.18-1.9 1.12-3.72 2.58-4.96 1.66-1.44 3.98-2.13 6.15-1.72.02 1.48-.04 2.96-.04 4.44-.99-.32-2.15-.23-3.02.37-.63.41-1.11 1.04-1.36 1.75-.21.51-.15 1.07-.14 1.61.24 1.64 1.82 3.02 3.5 2.87 1.12-.01 2.19-.66 2.77-1.61.19-.33.4-.67.41-1.06.1-1.79.06-3.57.07-5.36.01-4.03-.01-8.05.02-12.07z" },
|
|
7
|
+
"discord": { title: "Discord", fill: "#5865F2", d: "M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z" },
|
|
8
|
+
"resend": { title: "Resend", fill: 'currentColor', d: "M2.023 0v24h5.553v-8.434h2.998L15.326 24h6.65l-5.372-9.258a7.652 7.652 0 0 0 3.316-3.016c.709-1.21 1.062-2.57 1.062-4.08 0-1.462-.353-2.767-1.062-3.91-.709-1.165-1.692-2.079-2.95-2.742C15.737.331 14.355 0 12.823 0Zm5.553 4.87h4.219c.731 0 1.349.125 1.851.376.526.252.925.618 1.2 1.098.274.457.412.994.412 1.611S15.132 9.12 14.88 9.6c-.229.48-.572.856-1.03 1.13-.434.252-.948.38-1.542.38H7.576Z" },
|
|
9
|
+
"linkedin": { title: "LinkedIn", fill: "#0A66C2", d: "M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" },
|
|
10
|
+
"reddit": { title: "Reddit", fill: "#FF4500", d: "M12 0C5.373 0 0 5.373 0 12c0 3.314 1.343 6.314 3.515 8.485l-2.286 2.286C.775 23.225 1.097 24 1.738 24H12c6.627 0 12-5.373 12-12S18.627 0 12 0Zm4.388 3.199c1.104 0 1.999.895 1.999 1.999 0 1.105-.895 2-1.999 2-.946 0-1.739-.657-1.947-1.539v.002c-1.147.162-2.032 1.15-2.032 2.341v.007c1.776.067 3.4.567 4.686 1.363.473-.363 1.064-.58 1.707-.58 1.547 0 2.802 1.254 2.802 2.802 0 1.117-.655 2.081-1.601 2.531-.088 3.256-3.637 5.876-7.997 5.876-4.361 0-7.905-2.617-7.998-5.87-.954-.447-1.614-1.415-1.614-2.538 0-1.548 1.255-2.802 2.803-2.802.645 0 1.239.218 1.712.585 1.275-.79 2.881-1.291 4.64-1.365v-.01c0-1.663 1.263-3.034 2.88-3.207.188-.911.993-1.595 1.959-1.595Zm-8.085 8.376c-.784 0-1.459.78-1.506 1.797-.047 1.016.64 1.429 1.426 1.429.786 0 1.371-.369 1.418-1.385.047-1.017-.553-1.841-1.338-1.841Zm7.406 0c-.786 0-1.385.824-1.338 1.841.047 1.017.634 1.385 1.418 1.385.785 0 1.473-.413 1.426-1.429-.046-1.017-.721-1.797-1.506-1.797Zm-3.703 4.013c-.974 0-1.907.048-2.77.135-.147.015-.241.168-.183.305.483 1.154 1.622 1.964 2.953 1.964 1.33 0 2.47-.81 2.953-1.964.057-.137-.037-.29-.184-.305-.863-.087-1.795-.135-2.769-.135Z" },
|
|
11
|
+
"bluesky": { title: "Bluesky", fill: "#0285FF", d: "M12 10.8c-1.087-2.114-4.046-6.053-6.798-7.995C2.566.944 1.561 1.266.902 1.565.139 1.908 0 3.08 0 3.768c0 .69.378 5.65.624 6.479.815 2.736 3.713 3.66 6.383 3.364.136-.02.275-.039.415-.056-.138.022-.276.04-.415.056-3.912.58-7.387 2.005-2.83 7.078 5.013 5.19 6.87-1.113 7.823-4.308.953 3.195 2.05 9.271 7.733 4.308 4.267-4.308 1.172-6.498-2.74-7.078a8.741 8.741 0 0 1-.415-.056c.14.017.279.036.415.056 2.67.297 5.568-.628 6.383-3.364.246-.828.624-5.79.624-6.478 0-.69-.139-1.861-.902-2.206-.659-.298-1.664-.62-4.3 1.24C16.046 4.748 13.087 8.687 12 10.8Z" },
|
|
12
|
+
"instagram": { title: "Instagram", fill: "#FF0069", d: "M7.0301.084c-1.2768.0602-2.1487.264-2.911.5634-.7888.3075-1.4575.72-2.1228 1.3877-.6652.6677-1.075 1.3368-1.3802 2.127-.2954.7638-.4956 1.6365-.552 2.914-.0564 1.2775-.0689 1.6882-.0626 4.947.0062 3.2586.0206 3.6671.0825 4.9473.061 1.2765.264 2.1482.5635 2.9107.308.7889.72 1.4573 1.388 2.1228.6679.6655 1.3365 1.0743 2.1285 1.38.7632.295 1.6361.4961 2.9134.552 1.2773.056 1.6884.069 4.9462.0627 3.2578-.0062 3.668-.0207 4.9478-.0814 1.28-.0607 2.147-.2652 2.9098-.5633.7889-.3086 1.4578-.72 2.1228-1.3881.665-.6682 1.0745-1.3378 1.3795-2.1284.2957-.7632.4966-1.636.552-2.9124.056-1.2809.0692-1.6898.063-4.948-.0063-3.2583-.021-3.6668-.0817-4.9465-.0607-1.2797-.264-2.1487-.5633-2.9117-.3084-.7889-.72-1.4568-1.3876-2.1228C21.2982 1.33 20.628.9208 19.8378.6165 19.074.321 18.2017.1197 16.9244.0645 15.6471.0093 15.236-.005 11.977.0014 8.718.0076 8.31.0215 7.0301.0839m.1402 21.6932c-1.17-.0509-1.8053-.2453-2.2287-.408-.5606-.216-.96-.4771-1.3819-.895-.422-.4178-.6811-.8186-.9-1.378-.1644-.4234-.3624-1.058-.4171-2.228-.0595-1.2645-.072-1.6442-.079-4.848-.007-3.2037.0053-3.583.0607-4.848.05-1.169.2456-1.805.408-2.2282.216-.5613.4762-.96.895-1.3816.4188-.4217.8184-.6814 1.3783-.9003.423-.1651 1.0575-.3614 2.227-.4171 1.2655-.06 1.6447-.072 4.848-.079 3.2033-.007 3.5835.005 4.8495.0608 1.169.0508 1.8053.2445 2.228.408.5608.216.96.4754 1.3816.895.4217.4194.6816.8176.9005 1.3787.1653.4217.3617 1.056.4169 2.2263.0602 1.2655.0739 1.645.0796 4.848.0058 3.203-.0055 3.5834-.061 4.848-.051 1.17-.245 1.8055-.408 2.2294-.216.5604-.4763.96-.8954 1.3814-.419.4215-.8181.6811-1.3783.9-.4224.1649-1.0577.3617-2.2262.4174-1.2656.0595-1.6448.072-4.8493.079-3.2045.007-3.5825-.006-4.848-.0608M16.953 5.5864A1.44 1.44 0 1 0 18.39 4.144a1.44 1.44 0 0 0-1.437 1.4424M5.8385 12.012c.0067 3.4032 2.7706 6.1557 6.173 6.1493 3.4026-.0065 6.157-2.7701 6.1506-6.1733-.0065-3.4032-2.771-6.1565-6.174-6.1498-3.403.0067-6.156 2.771-6.1496 6.1738M8 12.0077a4 4 0 1 1 4.008 3.9921A3.9996 3.9996 0 0 1 8 12.0077" },
|
|
13
|
+
"github": { title: "GitHub", fill: 'currentColor', d: "M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" },
|
|
14
|
+
"stripe": { title: "Stripe", fill: "#635BFF", d: "M13.976 9.15c-2.172-.806-3.356-1.426-3.356-2.409 0-.831.683-1.305 1.901-1.305 2.227 0 4.515.858 6.09 1.631l.89-5.494C18.252.975 15.697 0 12.165 0 9.667 0 7.589.654 6.104 1.872 4.56 3.147 3.757 4.992 3.757 7.218c0 4.039 2.467 5.76 6.476 7.219 2.585.92 3.445 1.574 3.445 2.583 0 .98-.84 1.545-2.354 1.545-1.875 0-4.965-.921-6.99-2.109l-.9 5.555C5.175 22.99 8.385 24 11.714 24c2.641 0 4.843-.624 6.328-1.813 1.664-1.305 2.525-3.236 2.525-5.732 0-4.128-2.524-5.851-6.594-7.305h.003z" },
|
|
15
|
+
"slack": { title: "Slack", fill: "#4A154B", d: "M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zM6.313 15.165a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313zM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zM8.834 6.313a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312zM18.956 8.834a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zM17.688 8.834a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312zM15.165 18.956a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zM15.165 17.688a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313z" },
|
|
16
|
+
"openai": { title: "OpenAI", fill: "#412991", d: "M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z" },
|
|
17
|
+
"anthropic": { title: "Anthropic", fill: 'currentColor', d: "M17.3041 3.541h-3.6718l6.696 16.918H24Zm-10.6082 0L0 20.459h3.7442l1.3693-3.5527h7.0052l1.3693 3.5528h3.7442L10.5363 3.5409Zm-.3712 10.2232 2.2914-5.9456 2.2914 5.9456Z" },
|
|
18
|
+
"twilio": { title: "Twilio", fill: "#F22F46", d: "M12 0C5.381-.008.008 5.352 0 11.971V12c0 6.64 5.359 12 12 12 6.64 0 12-5.36 12-12 0-6.641-5.36-12-12-12zm0 20.801c-4.846.015-8.786-3.904-8.801-8.75V12c-.014-4.846 3.904-8.786 8.75-8.801H12c4.847-.014 8.786 3.904 8.801 8.75V12c.015 4.847-3.904 8.786-8.75 8.801H12zm5.44-11.76c0 1.359-1.12 2.479-2.481 2.479-1.366-.007-2.472-1.113-2.479-2.479 0-1.361 1.12-2.481 2.479-2.481 1.361 0 2.481 1.12 2.481 2.481zm0 5.919c0 1.36-1.12 2.48-2.481 2.48-1.367-.008-2.473-1.114-2.479-2.48 0-1.359 1.12-2.479 2.479-2.479 1.361-.001 2.481 1.12 2.481 2.479zm-5.919 0c0 1.36-1.12 2.48-2.479 2.48-1.368-.007-2.475-1.113-2.481-2.48 0-1.359 1.12-2.479 2.481-2.479 1.358-.001 2.479 1.12 2.479 2.479zm0-5.919c0 1.359-1.12 2.479-2.479 2.479-1.367-.007-2.475-1.112-2.481-2.479 0-1.361 1.12-2.481 2.481-2.481 1.358 0 2.479 1.12 2.479 2.481z" },
|
|
19
|
+
"sendgrid": { title: "SendGrid", fill: "#51A9E3", d: "M.8 24h13.6c.88 0 1.6-.72 1.6-1.6v-4.8c0-.88-.72-1.6-1.6-1.6H9.6c-.88 0-1.6-.72-1.6-1.6V9.6C8 8.72 7.28 8 6.4 8H1.6C.72 8 0 8.72 0 9.6v13.6c0 .44.36.8.8.8zM23.2 0H9.6C8.72 0 8 .72 8 1.6v4.8C8 7.28 8.72 8 9.6 8h4.8c.88 0 1.6.72 1.6 1.6v4.8c0 .88.72 1.6 1.6 1.6h4.8c.88 0 1.6-.72 1.6-1.6V.8c0-.44-.36-.8-.8-.8Z" },
|
|
20
|
+
"mailgun": { title: "Mailgun", fill: "#F06B66", d: "M11.837 0c6.602 0 11.984 5.381 11.984 11.994-.017 2.99-3.264 4.84-5.844 3.331a3.805 3.805 0 0 1-.06-.035l-.055-.033-.022.055c-2.554 4.63-9.162 4.758-11.894.232-2.732-4.527.46-10.313 5.746-10.416a6.868 6.868 0 0 1 7.002 6.866 1.265 1.265 0 0 0 2.52 0c0-5.18-4.197-9.38-9.377-9.387C4.611 2.594.081 10.41 3.683 16.673c3.238 5.632 11.08 6.351 15.289 1.402l1.997 1.686A11.95 11.95 0 0 1 11.837 24C2.6 23.72-2.87 13.543 1.992 5.684A12.006 12.006 0 0 1 11.837 0Zm0 7.745c-3.276-.163-5.5 3.281-4.003 6.2a4.26 4.26 0 0 0 4.014 2.31c3.276-.171 5.137-3.824 3.35-6.575a4.26 4.26 0 0 0-3.36-1.935Zm0 2.53c1.324 0 2.152 1.433 1.49 2.58a1.72 1.72 0 0 1-1.49.86 1.72 1.72 0 1 1 0-3.44Z" },
|
|
21
|
+
"notion": { title: "Notion", fill: 'currentColor', d: "M4.459 4.208c.746.606 1.026.56 2.428.466l13.215-.793c.28 0 .047-.28-.046-.326L17.86 1.968c-.42-.326-.981-.7-2.055-.607L3.01 2.295c-.466.046-.56.28-.374.466zm.793 3.08v13.904c0 .747.373 1.027 1.214.98l14.523-.84c.841-.046.935-.56.935-1.167V6.354c0-.606-.233-.933-.748-.887l-15.177.887c-.56.047-.747.327-.747.933zm14.337.745c.093.42 0 .84-.42.888l-.7.14v10.264c-.608.327-1.168.514-1.635.514-.748 0-.935-.234-1.495-.933l-4.577-7.186v6.952L12.21 19s0 .84-1.168.84l-3.222.186c-.093-.186 0-.653.327-.746l.84-.233V9.854L7.822 9.76c-.094-.42.14-1.026.793-1.073l3.456-.233 4.764 7.279v-6.44l-1.215-.139c-.093-.514.28-.887.747-.933zM1.936 1.035l13.31-.98c1.634-.14 2.055-.047 3.082.7l4.249 2.986c.7.513.934.653.934 1.213v16.378c0 1.026-.373 1.634-1.68 1.726l-15.458.934c-.98.047-1.448-.093-1.962-.747l-3.129-4.06c-.56-.747-.793-1.306-.793-1.96V2.667c0-.839.374-1.54 1.447-1.632z" },
|
|
22
|
+
"linear": { title: "Linear", fill: "#5E6AD2", d: "M2.886 4.18A11.982 11.982 0 0 1 11.99 0C18.624 0 24 5.376 24 12.009c0 3.64-1.62 6.903-4.18 9.105L2.887 4.18ZM1.817 5.626l16.556 16.556c-.524.33-1.075.62-1.65.866L.951 7.277c.247-.575.537-1.126.866-1.65ZM.322 9.163l14.515 14.515c-.71.172-1.443.282-2.195.322L0 11.358a12 12 0 0 1 .322-2.195Zm-.17 4.862 9.823 9.824a12.02 12.02 0 0 1-9.824-9.824Z" },
|
|
23
|
+
"jira": { title: "Jira", fill: "#0052CC", d: "M11.571 11.513H0a5.218 5.218 0 0 0 5.232 5.215h2.13v2.057A5.215 5.215 0 0 0 12.575 24V12.518a1.005 1.005 0 0 0-1.005-1.005zm5.723-5.756H5.736a5.215 5.215 0 0 0 5.215 5.214h2.129v2.058a5.218 5.218 0 0 0 5.215 5.214V6.758a1.001 1.001 0 0 0-1.001-1.001zM23.013 0H11.455a5.215 5.215 0 0 0 5.215 5.215h2.129v2.057A5.215 5.215 0 0 0 24 12.483V1.005A1.001 1.001 0 0 0 23.013 0Z" },
|
|
24
|
+
"hubspot": { title: "HubSpot", fill: "#FF7A59", d: "M18.164 7.93V5.084a2.198 2.198 0 001.267-1.978v-.067A2.2 2.2 0 0017.238.845h-.067a2.2 2.2 0 00-2.193 2.193v.067a2.196 2.196 0 001.252 1.973l.013.006v2.852a6.22 6.22 0 00-2.969 1.31l.012-.01-7.828-6.095A2.497 2.497 0 104.3 4.656l-.012.006 7.697 5.991a6.176 6.176 0 00-1.038 3.446c0 1.343.425 2.588 1.147 3.607l-.013-.02-2.342 2.343a1.968 1.968 0 00-.58-.095h-.002a2.033 2.033 0 102.033 2.033 1.978 1.978 0 00-.1-.595l.005.014 2.317-2.317a6.247 6.247 0 104.782-11.134l-.036-.005zm-.964 9.378a3.206 3.206 0 113.215-3.207v.002a3.206 3.206 0 01-3.207 3.207z" },
|
|
25
|
+
"paypal": { title: "PayPal", fill: "#003087", d: "M7.016 19.198h-4.2a.562.562 0 0 1-.555-.65L5.093.584A.692.692 0 0 1 5.776 0h7.222c3.417 0 5.904 2.488 5.846 5.5-.006.25-.027.5-.066.747A6.794 6.794 0 0 1 12.071 12H8.743a.69.69 0 0 0-.682.583l-.325 2.056-.013.083-.692 4.39-.015.087zM19.79 6.142c-.01.087-.01.175-.023.261a7.76 7.76 0 0 1-7.695 6.598H9.007l-.283 1.795-.013.083-.692 4.39-.134.843-.014.088H6.86l-.497 3.15a.562.562 0 0 0 .555.65h3.612c.34 0 .63-.249.683-.585l.952-6.031a.692.692 0 0 1 .683-.584h2.126a6.793 6.793 0 0 0 6.707-5.752c.306-1.95-.466-3.744-1.89-4.906z" },
|
|
26
|
+
"shopify": { title: "Shopify", fill: "#7AB55C", d: "M15.337 23.979l7.216-1.561s-2.604-17.613-2.625-17.73c-.018-.116-.114-.192-.211-.192s-1.929-.136-1.929-.136-1.275-1.274-1.439-1.411c-.045-.037-.075-.057-.121-.074l-.914 21.104h.023zM11.71 11.305s-.81-.424-1.774-.424c-1.447 0-1.504.906-1.504 1.141 0 1.232 3.24 1.715 3.24 4.629 0 2.295-1.44 3.76-3.406 3.76-2.354 0-3.54-1.465-3.54-1.465l.646-2.086s1.245 1.066 2.28 1.066c.675 0 .975-.545.975-.932 0-1.619-2.654-1.694-2.654-4.359-.034-2.237 1.571-4.416 4.827-4.416 1.257 0 1.875.361 1.875.361l-.945 2.715-.02.01zM11.17.83c.136 0 .271.038.405.135-.984.465-2.064 1.639-2.508 3.992-.656.213-1.293.405-1.889.578C7.697 3.75 8.951.84 11.17.84V.83zm1.235 2.949v.135c-.754.232-1.583.484-2.394.736.466-1.777 1.333-2.645 2.085-2.971.193.501.309 1.176.309 2.1zm.539-2.234c.694.074 1.141.867 1.429 1.755-.349.114-.735.231-1.158.366v-.252c0-.752-.096-1.371-.271-1.871v.002zm2.992 1.289c-.02 0-.06.021-.078.021s-.289.075-.714.21c-.423-1.233-1.176-2.37-2.508-2.37h-.115C12.135.209 11.669 0 11.265 0 8.159 0 6.675 3.877 6.21 5.846c-1.194.365-2.063.636-2.16.674-.675.213-.694.232-.772.87-.075.462-1.83 14.063-1.83 14.063L15.009 24l.927-21.166z" },
|
|
27
|
+
"sentry": { title: "Sentry", fill: "#362D59", d: "M13.91 2.505c-.873-1.448-2.972-1.448-3.844 0L6.904 7.92a15.478 15.478 0 0 1 8.53 12.811h-2.221A13.301 13.301 0 0 0 5.784 9.814l-2.926 5.06a7.65 7.65 0 0 1 4.435 5.848H2.194a.365.365 0 0 1-.298-.534l1.413-2.402a5.16 5.16 0 0 0-1.614-.913L.296 19.275a2.182 2.182 0 0 0 .812 2.999 2.24 2.24 0 0 0 1.086.288h6.983a9.322 9.322 0 0 0-3.845-8.318l1.11-1.922a11.47 11.47 0 0 1 4.95 10.24h5.915a17.242 17.242 0 0 0-7.885-15.28l2.244-3.845a.37.37 0 0 1 .504-.13c.255.14 9.75 16.708 9.928 16.9a.365.365 0 0 1-.327.543h-2.287c.029.612.029 1.223 0 1.831h2.297a2.206 2.206 0 0 0 1.922-3.31z" },
|
|
28
|
+
"vercel": { title: "Vercel", fill: 'currentColor', d: "M24 22.525H0l12-21.05 12 21.05z" },
|
|
29
|
+
"supabase": { title: "Supabase", fill: "#3FCF8E", d: "M11.9 1.036c-.015-.986-1.26-1.41-1.874-.637L.764 12.05C-.33 13.427.65 15.455 2.409 15.455h9.579l.113 7.51c.014.985 1.259 1.408 1.873.636l9.262-11.653c1.093-1.375.113-3.403-1.645-3.403h-9.642z" },
|
|
30
|
+
"clerk": { title: "Clerk", fill: "#6C47FF", d: "m21.47 20.829-2.881-2.881a.572.572 0 0 0-.7-.084 6.854 6.854 0 0 1-7.081 0 .576.576 0 0 0-.7.084l-2.881 2.881a.576.576 0 0 0-.103.69.57.57 0 0 0 .166.186 12 12 0 0 0 14.113 0 .58.58 0 0 0 .239-.423.576.576 0 0 0-.172-.453Zm.002-17.668-2.88 2.88a.569.569 0 0 1-.701.084A6.857 6.857 0 0 0 8.724 8.08a6.862 6.862 0 0 0-1.222 3.692 6.86 6.86 0 0 0 .978 3.764.573.573 0 0 1-.083.699l-2.881 2.88a.567.567 0 0 1-.864-.063A11.993 11.993 0 0 1 6.771 2.7a11.99 11.99 0 0 1 14.637-.405.566.566 0 0 1 .232.418.57.57 0 0 1-.168.448Zm-7.118 12.261a3.427 3.427 0 1 0 0-6.854 3.427 3.427 0 0 0 0 6.854Z" },
|
|
31
|
+
"aws": { title: "Amazon Web Services", fill: "#232F3E", d: "M6.763 10.036c0 .296.032.535.088.71.064.176.144.368.256.576.04.063.056.127.056.183 0 .08-.048.16-.152.24l-.503.335a.383.383 0 0 1-.208.072c-.08 0-.16-.04-.239-.112a2.47 2.47 0 0 1-.287-.375 6.18 6.18 0 0 1-.248-.471c-.622.734-1.405 1.101-2.347 1.101-.67 0-1.205-.191-1.596-.574-.391-.384-.59-.894-.59-1.533 0-.678.239-1.23.726-1.644.487-.415 1.133-.623 1.955-.623.272 0 .551.024.846.064.296.04.6.104.918.176v-.583c0-.607-.127-1.03-.375-1.277-.255-.248-.686-.367-1.3-.367-.28 0-.568.031-.863.103-.295.072-.583.16-.862.272a2.287 2.287 0 0 1-.28.104.488.488 0 0 1-.127.023c-.112 0-.168-.08-.168-.247v-.391c0-.128.016-.224.056-.28a.597.597 0 0 1 .224-.167c.279-.144.614-.264 1.005-.36a4.84 4.84 0 0 1 1.246-.151c.95 0 1.644.216 2.091.647.439.43.662 1.085.662 1.963v2.586zm-3.24 1.214c.263 0 .534-.048.822-.144.287-.096.543-.271.758-.51.128-.152.224-.32.272-.512.047-.191.08-.423.08-.694v-.335a6.66 6.66 0 0 0-.735-.136 6.02 6.02 0 0 0-.75-.048c-.535 0-.926.104-1.19.32-.263.215-.39.518-.39.917 0 .375.095.655.295.846.191.2.47.296.838.296zm6.41.862c-.144 0-.24-.024-.304-.08-.064-.048-.12-.16-.168-.311L7.586 5.55a1.398 1.398 0 0 1-.072-.32c0-.128.064-.2.191-.2h.783c.151 0 .255.025.31.08.065.048.113.16.16.312l1.342 5.284 1.245-5.284c.04-.16.088-.264.151-.312a.549.549 0 0 1 .32-.08h.638c.152 0 .256.025.32.08.063.048.12.16.151.312l1.261 5.348 1.381-5.348c.048-.16.104-.264.16-.312a.52.52 0 0 1 .311-.08h.743c.127 0 .2.065.2.2 0 .04-.009.08-.017.128a1.137 1.137 0 0 1-.056.2l-1.923 6.17c-.048.16-.104.263-.168.311a.51.51 0 0 1-.303.08h-.687c-.151 0-.255-.024-.32-.08-.063-.056-.119-.16-.15-.32l-1.238-5.148-1.23 5.14c-.04.16-.087.264-.15.32-.065.056-.177.08-.32.08zm10.256.215c-.415 0-.83-.048-1.229-.143-.399-.096-.71-.2-.918-.32-.128-.071-.215-.151-.247-.223a.563.563 0 0 1-.048-.224v-.407c0-.167.064-.247.183-.247.048 0 .096.008.144.024.048.016.12.048.2.08.271.12.566.215.878.279.319.064.63.096.95.096.502 0 .894-.088 1.165-.264a.86.86 0 0 0 .415-.758.777.777 0 0 0-.215-.559c-.144-.151-.416-.287-.807-.415l-1.157-.36c-.583-.183-1.014-.454-1.277-.813a1.902 1.902 0 0 1-.4-1.158c0-.335.073-.63.216-.886.144-.255.335-.479.575-.654.24-.184.51-.32.83-.415.32-.096.655-.136 1.006-.136.175 0 .359.008.535.032.183.024.35.056.518.088.16.04.312.08.455.127.144.048.256.096.336.144a.69.69 0 0 1 .24.2.43.43 0 0 1 .071.263v.375c0 .168-.064.256-.184.256a.83.83 0 0 1-.303-.096 3.652 3.652 0 0 0-1.532-.311c-.455 0-.815.071-1.062.223-.248.152-.375.383-.375.71 0 .224.08.416.24.567.159.152.454.304.877.44l1.134.358c.574.184.99.44 1.237.767.247.327.367.702.367 1.117 0 .343-.072.655-.207.926-.144.272-.336.511-.583.703-.248.2-.543.343-.886.447-.36.111-.734.167-1.142.167zM21.698 16.207c-2.626 1.94-6.442 2.969-9.722 2.969-4.598 0-8.74-1.7-11.87-4.526-.247-.223-.024-.527.272-.351 3.384 1.963 7.559 3.153 11.877 3.153 2.914 0 6.114-.607 9.06-1.852.439-.2.814.287.383.607zM22.792 14.961c-.336-.43-2.22-.207-3.074-.103-.255.032-.295-.192-.063-.36 1.5-1.053 3.967-.75 4.254-.399.287.36-.08 2.826-1.485 4.007-.215.184-.423.088-.327-.151.32-.79 1.03-2.57.695-2.994z" },
|
|
32
|
+
"figma": { title: "Figma", fill: "#F24E1E", d: "M15.852 8.981h-4.588V0h4.588c2.476 0 4.49 2.014 4.49 4.49s-2.014 4.491-4.49 4.491zM12.735 7.51h3.117c1.665 0 3.019-1.355 3.019-3.019s-1.355-3.019-3.019-3.019h-3.117V7.51zm0 1.471H8.148c-2.476 0-4.49-2.014-4.49-4.49S5.672 0 8.148 0h4.588v8.981zm-4.587-7.51c-1.665 0-3.019 1.355-3.019 3.019s1.354 3.02 3.019 3.02h3.117V1.471H8.148zm4.587 15.019H8.148c-2.476 0-4.49-2.014-4.49-4.49s2.014-4.49 4.49-4.49h4.588v8.98zM8.148 8.981c-1.665 0-3.019 1.355-3.019 3.019s1.355 3.019 3.019 3.019h3.117V8.981H8.148zM8.172 24c-2.489 0-4.515-2.014-4.515-4.49s2.014-4.49 4.49-4.49h4.588v4.441c0 2.503-2.047 4.539-4.563 4.539zm-.024-7.51a3.023 3.023 0 0 0-3.019 3.019c0 1.665 1.365 3.019 3.044 3.019 1.705 0 3.093-1.376 3.093-3.068v-2.97H8.148zm7.704 0h-.098c-2.476 0-4.49-2.014-4.49-4.49s2.014-4.49 4.49-4.49h.098c2.476 0 4.49 2.014 4.49 4.49s-2.014 4.49-4.49 4.49zm-.097-7.509c-1.665 0-3.019 1.355-3.019 3.019s1.355 3.019 3.019 3.019h.098c1.665 0 3.019-1.355 3.019-3.019s-1.355-3.019-3.019-3.019h-.098z" },
|
|
33
|
+
"airtable": { title: "Airtable", fill: "#18BFFF", d: "M11.992 1.966c-.434 0-.87.086-1.28.257L1.779 5.917c-.503.208-.49.908.012 1.116l8.982 3.558a3.266 3.266 0 0 0 2.454 0l8.982-3.558c.503-.196.503-.908.012-1.116l-8.957-3.694a3.255 3.255 0 0 0-1.272-.257zM23.4 8.056a.589.589 0 0 0-.222.045l-10.012 3.877a.612.612 0 0 0-.38.564v8.896a.6.6 0 0 0 .821.552L23.62 18.1a.583.583 0 0 0 .38-.551V8.653a.6.6 0 0 0-.6-.596zM.676 8.095a.644.644 0 0 0-.48.19C.086 8.396 0 8.53 0 8.69v8.355c0 .442.515.737.908.54l6.27-3.006.307-.147 2.969-1.436c.466-.22.43-.908-.061-1.092L.883 8.138a.57.57 0 0 0-.207-.044z" },
|
|
34
|
+
"intercom": { title: "Intercom", fill: "#6AFDEF", d: "M21 0H3C1.343 0 0 1.343 0 3v18c0 1.658 1.343 3 3 3h18c1.658 0 3-1.342 3-3V3c0-1.657-1.342-3-3-3zm-5.801 4.399c0-.44.36-.8.802-.8.44 0 .8.36.8.8v10.688c0 .442-.36.801-.8.801-.443 0-.802-.359-.802-.801V4.399zM11.2 3.994c0-.44.357-.799.8-.799s.8.359.8.799v11.602c0 .44-.357.8-.8.8s-.8-.36-.8-.8V3.994zm-4 .405c0-.44.359-.8.799-.8.443 0 .802.36.802.8v10.688c0 .442-.36.801-.802.801-.44 0-.799-.359-.799-.801V4.399zM3.199 6c0-.442.36-.8.802-.8.44 0 .799.358.799.8v7.195c0 .441-.359.8-.799.8-.443 0-.802-.36-.802-.8V6zM20.52 18.202c-.123.105-3.086 2.593-8.52 2.593-5.433 0-8.397-2.486-8.521-2.593-.335-.288-.375-.792-.086-1.128.285-.334.79-.375 1.125-.09.047.041 2.693 2.211 7.481 2.211 4.848 0 7.456-2.186 7.479-2.207.334-.289.839-.25 1.128.086.289.336.25.84-.086 1.128zm.281-5.007c0 .441-.36.8-.801.8-.441 0-.801-.36-.801-.8V6c0-.442.361-.8.801-.8.441 0 .801.357.801.8v7.195z" },
|
|
35
|
+
"posthog": { title: "PostHog", fill: 'currentColor', d: "M9.854 14.5 5 9.647.854 5.5A.5.5 0 0 0 0 5.854V8.44a.5.5 0 0 0 .146.353L5 13.647l.147.146L9.854 18.5l.146.147v-.049c.065.03.134.049.207.049h2.586a.5.5 0 0 0 .353-.854L9.854 14.5zm0-5-4-4a.487.487 0 0 0-.409-.144.515.515 0 0 0-.356.21.493.493 0 0 0-.089.288V8.44a.5.5 0 0 0 .147.353l9 9a.5.5 0 0 0 .853-.354v-2.585a.5.5 0 0 0-.146-.354l-5-5zm1-4a.5.5 0 0 0-.854.354V8.44a.5.5 0 0 0 .147.353l4 4a.5.5 0 0 0 .853-.354V9.854a.5.5 0 0 0-.146-.354l-4-4zm12.647 11.515a3.863 3.863 0 0 1-2.232-1.1l-4.708-4.707a.5.5 0 0 0-.854.354v6.585a.5.5 0 0 0 .5.5H23.5a.5.5 0 0 0 .5-.5v-.6c0-.276-.225-.497-.499-.532zm-5.394.032a.8.8 0 1 1 0-1.6.8.8 0 0 1 0 1.6zM.854 15.5a.5.5 0 0 0-.854.354v2.293a.5.5 0 0 0 .5.5h2.293c.222 0 .39-.135.462-.309a.493.493 0 0 0-.109-.545L.854 15.501zM5 14.647.854 10.5a.5.5 0 0 0-.854.353v2.586a.5.5 0 0 0 .146.353L4.854 18.5l.146.147h2.793a.5.5 0 0 0 .353-.854L5 14.647z" },
|
|
36
|
+
"datadog": { title: "Datadog", fill: "#632CA6", d: "M19.57 17.04l-1.997-1.316-1.665 2.782-1.937-.567-1.706 2.604.087.82 9.274-1.71-.538-5.794zm-8.649-2.498l1.488-.204c.241.108.409.15.697.223.45.117.97.23 1.741-.16.18-.088.553-.43.704-.625l6.096-1.106.622 7.527-10.444 1.882zm11.325-2.712l-.602.115L20.488 0 .789 2.285l2.427 19.693 2.306-.334c-.184-.263-.471-.581-.96-.989-.68-.564-.44-1.522-.039-2.127.53-1.022 3.26-2.322 3.106-3.956-.056-.594-.15-1.368-.702-1.898-.02.22.017.432.017.432s-.227-.289-.34-.683c-.112-.15-.2-.199-.319-.4-.085.233-.073.503-.073.503s-.186-.437-.216-.807c-.11.166-.137.48-.137.48s-.241-.69-.186-1.062c-.11-.323-.436-.965-.343-2.424.6.421 1.924.321 2.44-.439.171-.251.288-.939-.086-2.293-.24-.868-.835-2.16-1.066-2.651l-.028.02c.122.395.374 1.223.47 1.625.293 1.218.372 1.642.234 2.204-.116.488-.397.808-1.107 1.165-.71.358-1.653-.514-1.713-.562-.69-.55-1.224-1.447-1.284-1.883-.062-.477.275-.763.445-1.153-.243.07-.514.192-.514.192s.323-.334.722-.624c.165-.109.262-.178.436-.323a9.762 9.762 0 0 0-.456.003s.42-.227.855-.392c-.318-.014-.623-.003-.623-.003s.937-.419 1.678-.727c.509-.208 1.006-.147 1.286.257.367.53.752.817 1.569.996.501-.223.653-.337 1.284-.509.554-.61.99-.688.99-.688s-.216.198-.274.51c.314-.249.66-.455.66-.455s-.134.164-.259.426l.03.043c.366-.22.797-.394.797-.394s-.123.156-.268.358c.277-.002.838.012 1.056.037 1.285.028 1.552-1.374 2.045-1.55.618-.22.894-.353 1.947.68.903.888 1.609 2.477 1.259 2.833-.294.295-.874-.115-1.516-.916a3.466 3.466 0 0 1-.716-1.562 1.533 1.533 0 0 0-.497-.85s.23.51.23.96c0 .246.03 1.165.424 1.68-.039.076-.057.374-.1.43-.458-.554-1.443-.95-1.604-1.067.544.445 1.793 1.468 2.273 2.449.453.927.186 1.777.416 1.997.065.063.976 1.197 1.15 1.767.306.994.019 2.038-.381 2.685l-1.117.174c-.163-.045-.273-.068-.42-.153.08-.143.241-.5.243-.572l-.063-.111c-.348.492-.93.97-1.414 1.245-.633.359-1.363.304-1.838.156-1.348-.415-2.623-1.327-2.93-1.566 0 0-.01.191.048.234.34.383 1.119 1.077 1.872 1.56l-1.605.177.759 5.908c-.337.048-.39.071-.757.124-.325-1.147-.946-1.895-1.624-2.332-.599-.384-1.424-.47-2.214-.314l-.05.059a2.851 2.851 0 0 1 1.863.444c.654.413 1.181 1.481 1.375 2.124.248.822.42 1.7-.248 2.632-.476.662-1.864 1.028-2.986.237.3.481.705.876 1.25.95.809.11 1.577-.03 2.106-.574.452-.464.69-1.434.628-2.456l.714-.104.258 1.834 11.827-1.424zM15.05 6.848c-.034.075-.085.125-.007.37l.004.014.013.032.032.073c.14.287.295.558.552.696.067-.011.136-.019.207-.023.242-.01.395.028.492.08.009-.048.01-.119.005-.222-.018-.364.072-.982-.626-1.308-.264-.122-.634-.084-.757.068a.302.302 0 0 1 .058.013c.186.066.06.13.027.207m1.958 3.392c-.092-.05-.52-.03-.821.005-.574.068-1.193.267-1.328.372-.247.191-.135.523.047.66.511.382.96.638 1.432.575.29-.038.546-.497.728-.914.124-.288.124-.598-.058-.698m-5.077-2.942c.162-.154-.805-.355-1.556.156-.554.378-.571 1.187-.041 1.646.053.046.096.078.137.104a4.77 4.77 0 0 1 1.396-.412c.113-.125.243-.345.21-.745-.044-.542-.455-.456-.146-.749" },
|
|
37
|
+
"algolia": { title: "Algolia", fill: "#003DFF", d: "M12 0C5.445 0 .103 5.285.01 11.817c-.097 6.634 5.285 12.131 11.92 12.17a11.91 11.91 0 0 0 5.775-1.443.281.281 0 0 0 .052-.457l-1.122-.994a.79.79 0 0 0-.833-.14 9.693 9.693 0 0 1-3.923.77c-5.36-.067-9.692-4.527-9.607-9.888.084-5.293 4.417-9.573 9.73-9.573h9.73v17.296l-5.522-4.907a.407.407 0 0 0-.596.063 4.52 4.52 0 0 1-3.934 1.793 4.538 4.538 0 0 1-4.192-4.168 4.53 4.53 0 0 1 4.512-4.872 4.532 4.532 0 0 1 4.509 4.126c.018.205.11.397.265.533l1.438 1.275a.28.28 0 0 0 .462-.158 6.82 6.82 0 0 0 .099-1.725c-.232-3.376-2.966-6.092-6.345-6.3-3.873-.24-7.11 2.79-7.214 6.588-.1 3.7 2.933 6.892 6.634 6.974a6.75 6.75 0 0 0 4.136-1.294l7.212 6.394a.48.48 0 0 0 .797-.36V.456A.456.456 0 0 0 23.54 0Z" },
|
|
38
|
+
"cloudflare": { title: "Cloudflare", fill: "#F38020", d: "M16.5088 16.8447c.1475-.5068.0908-.9707-.1553-1.3154-.2246-.3164-.6045-.499-1.0615-.5205l-8.6592-.1123a.1559.1559 0 0 1-.1333-.0713c-.0283-.042-.0351-.0986-.021-.1553.0278-.084.1123-.1484.2036-.1562l8.7359-.1123c1.0351-.0489 2.1601-.8868 2.5537-1.9136l.499-1.3013c.0215-.0561.0293-.1128.0147-.168-.5625-2.5463-2.835-4.4453-5.5499-4.4453-2.5039 0-4.6284 1.6177-5.3876 3.8614-.4927-.3658-1.1187-.5625-1.794-.499-1.2026.119-2.1665 1.083-2.2861 2.2856-.0283.31-.0069.6128.0635.894C1.5683 13.171 0 14.7754 0 16.752c0 .1748.0142.3515.0352.5273.0141.083.0844.1475.1689.1475h15.9814c.0909 0 .1758-.0645.2032-.1553l.12-.4268zm2.7568-5.5634c-.0771 0-.1611 0-.2383.0112-.0566 0-.1054.0415-.127.0976l-.3378 1.1744c-.1475.5068-.0918.9707.1543 1.3164.2256.3164.6055.498 1.0625.5195l1.8437.1133c.0557 0 .1055.0263.1329.0703.0283.043.0351.1074.0214.1562-.0283.084-.1132.1485-.204.1553l-1.921.1123c-1.041.0488-2.1582.8867-2.5527 1.914l-.1406.3585c-.0283.0713.0215.1416.0986.1416h6.5977c.0771 0 .1474-.0489.169-.126.1122-.4082.1757-.837.1757-1.2803 0-2.6025-2.125-4.727-4.7344-4.727" },
|
|
39
|
+
"upstash": { title: "Upstash", fill: "#00E9A3", d: "M13.8027 0C11.193 0 8.583.9952 6.5918 2.9863c-3.9823 3.9823-3.9823 10.4396 0 14.4219 1.9911 1.9911 5.2198 1.9911 7.211 0 1.991-1.9911 1.991-5.2198 0-7.211L12 12c.9956.9956.9956 2.6098 0 3.6055-.9956.9955-2.6099.9955-3.6055 0-2.9866-2.9868-2.9866-7.8297 0-10.8164 2.9868-2.9868 7.8297-2.9868 10.8164 0l1.8028-1.8028C19.0225.9952 16.4125 0 13.8027 0zM12 12c-.9956-.9956-.9956-2.6098 0-3.6055.9956-.9955 2.6098-.9955 3.6055 0 2.9867 2.9868 2.9867 7.8297 0 10.8164-2.9867 2.9868-7.8297 2.9868-10.8164 0l-1.8028 1.8028c3.9823 3.9822 10.4396 3.9822 14.4219 0 3.9823-3.9824 3.9823-10.4396 0-14.4219-.9956-.9956-2.3006-1.4922-3.6055-1.4922-1.3048 0-2.6099.4966-3.6054 1.4922-1.9912 1.9912-1.9912 5.2198 0 7.211z" },
|
|
40
|
+
"mixpanel": { title: "Mixpanel", fill: "#7856FF", d: "M6.967 9.996h3.053c-.763-.477-1.048-1.145-1.431-2.384L7.443 3.366C6.919 1.458 6.49.551 4.39.551H.004v1.145h.621c1.286 0 1.431.477 1.814 1.908L3.44 7.326c.524 1.814 1.337 2.67 3.53 2.67h-.003Zm7.06 0h3.053c2.194 0 2.956-.86 3.484-2.67l1.001-3.722c.382-1.431.57-1.908 1.814-1.908H24V.551h-4.34c-2.146 0-2.576.86-3.053 2.815l-1.145 4.246c-.384 1.286-.673 1.907-1.435 2.384Zm-4.007 4.008h4.007V9.996H10.02v4.008ZM0 23.449h4.39c2.1 0 2.529-.907 3.053-2.815l1.146-4.246c.383-1.239.668-1.907 1.431-2.384H6.967c-2.194 0-3.007.86-3.531 2.67l-1.001 3.722c-.383 1.431-.524 1.907-1.814 1.907H0v1.146Zm19.65 0h4.343v-1.146h-.622c-1.239 0-1.431-.476-1.814-1.907l-1.001-3.722c-.524-1.814-1.286-2.67-3.483-2.67h-3.046c.762.477 1.041 1.098 1.424 2.384l1.145 4.246c.477 1.955.907 2.815 3.054 2.815Z" },
|
|
41
|
+
"gemini": { title: "Google Gemini", fill: "#8E75B2", d: "M11.04 19.32Q12 21.51 12 24q0-2.49.93-4.68.96-2.19 2.58-3.81t3.81-2.55Q21.51 12 24 12q-2.49 0-4.68-.93a12.3 12.3 0 0 1-3.81-2.58 12.3 12.3 0 0 1-2.58-3.81Q12 2.49 12 0q0 2.49-.96 4.68-.93 2.19-2.55 3.81a12.3 12.3 0 0 1-3.81 2.58Q2.49 12 0 12q2.49 0 4.68.96 2.19.93 3.81 2.55t2.55 3.81" },
|
|
42
|
+
};
|
package/dist/src/console.d.ts
CHANGED
|
@@ -1,22 +1,31 @@
|
|
|
1
|
+
/** Volter World's mark, served by the brand (brand.volter.ai): the favicon. */
|
|
2
|
+
declare const WORLD_LOGO = "https://brand.volter.ai/logo/twin-world/svg?size=64&variant=mono";
|
|
3
|
+
/** The dashboard's pages run only their own origin's scripts (a `javascript:` link or an injected script runs nothing) and
|
|
4
|
+
* are framed by nothing; frames and images stay open, since a console on its own origin frames the Worlds'. */
|
|
5
|
+
export declare const DASHBOARD_CSP = "script-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'";
|
|
1
6
|
export type ConsoleMount = {
|
|
2
7
|
/** `worlds`: the origin the Worlds are served at, when the console has an origin of its own; `names`: the
|
|
3
|
-
* Worlds (`<org>/<world>`) a World token may open there, for a host that does not list its Worlds (a hosted one)
|
|
8
|
+
* Worlds (`<org>/<world>`) a World token may open there, for a host that does not list its Worlds (a hosted one);
|
|
9
|
+
* `worldOrigin`: this page is served on a World's own origin, beside its twins and mirrors, so it keeps no token
|
|
10
|
+
* script can read. */
|
|
4
11
|
handle: (request: Request, base: string, opts?: {
|
|
5
12
|
worlds?: string;
|
|
6
13
|
names?: string[];
|
|
14
|
+
worldOrigin?: boolean;
|
|
7
15
|
}) => Promise<Response | null>;
|
|
8
|
-
/** Serve the shell with a session already in it — the platform's portal (managed mode). */
|
|
9
|
-
/** `scripts`: HTML the mount puts before the app script — the platform's identity keep-alive rides here. */
|
|
10
|
-
shell: (base: string, opts: {
|
|
11
|
-
token: string;
|
|
12
|
-
managed: boolean;
|
|
13
|
-
scripts?: string;
|
|
14
|
-
}) => Response;
|
|
15
16
|
};
|
|
16
17
|
/** The client, built once per process and kept (bundleClient: Bun.build under Bun, the prebuilt
|
|
17
18
|
* dist/client/console.bundle.js under Node, written by this package's build). */
|
|
18
19
|
export declare function buildConsoleClient(): Promise<string>;
|
|
19
|
-
/** The
|
|
20
|
-
*
|
|
21
|
-
* path (the client routes by path: `base/<org>/<world>`), or null for a path
|
|
20
|
+
/** The dashboard as a host mounts it: `handle(request, '/-/console')` answers the shell at `base/`, the bundle at
|
|
21
|
+
* `base/app.js`, the styles at `base/styles.css` (the kit's, then the dashboard's) over the brand's at `base/brand/`,
|
|
22
|
+
* and the shell again for any deeper path (the client routes by path: `base/<org>/<world>`), or null for a path
|
|
23
|
+
* outside `base`. */
|
|
22
24
|
export declare function createConsole(): ConsoleMount;
|
|
25
|
+
/** The kit's stylesheet (client/kit/kit.css): the roles and pieces every Volter World page shares. The platform's
|
|
26
|
+
* pages serve it before their own sheet. */
|
|
27
|
+
export declare function kitCss(): string;
|
|
28
|
+
/** The brand's tokens and faces (client/brand/, fetched at build) under a mount's `brand/`; `rest` is the path after it. */
|
|
29
|
+
export declare function brandAsset(rest: string): Response;
|
|
30
|
+
/** The brand's mark, for a page's favicon and header. */
|
|
31
|
+
export { WORLD_LOGO };
|
package/dist/src/console.js
CHANGED
|
@@ -1,31 +1,38 @@
|
|
|
1
|
-
// THE
|
|
2
|
-
// FRONTEND the way a pack's mirror is — a React client bundled by `Bun.build` at serve time behind
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
// THE DASHBOARD (apps/console/README.md; docs/contributing/architecture.md, "The hosted product"): a World's pages, a
|
|
2
|
+
// PURE FRONTEND the way a pack's mirror is — a React client bundled by `Bun.build` at serve time behind one app shell,
|
|
3
|
+
// with no data path of its own. Every read and every write it makes is a door of the host or of a world, called from
|
|
4
|
+
// the browser. The host mounts it at `/-/console/` (the same origin as the doors: one origin, no CORS). It is the same
|
|
5
|
+
// page on a laptop, a self-hosted host and Volter's cloud, and carries nothing of orgs or billing: the platform's pages
|
|
6
|
+
// are an app of their own, which reads the kit's assets exported at the end of this module. `handle` answers a request
|
|
7
|
+
// under `base` or returns null when the path is not the dashboard's.
|
|
8
|
+
import { readFileSync } from 'node:fs';
|
|
9
|
+
import { createRequire } from 'node:module';
|
|
10
|
+
import { brandTokensResponse, bundleClient } from '@volter/world-core';
|
|
11
|
+
/** A file URL's path as the filesystem names it: decoded, and without the leading slash before a Windows drive (`/C:/…`). */
|
|
12
|
+
const pathOf = (url) => decodeURIComponent(url.pathname).replace(/^\/([A-Za-z]:)/, '$1');
|
|
13
|
+
const CLIENT_ENTRY = () => pathOf(new URL('../client/console.tsx', import.meta.url)); // lazy: never a top-level import.meta.url URL (workerd)
|
|
14
|
+
const CLIENT_CSS = () => pathOf(new URL('../client/console.css', import.meta.url));
|
|
15
|
+
const KIT_CSS = () => pathOf(new URL('../client/kit/kit.css', import.meta.url));
|
|
11
16
|
/** The brand's tokens and faces (company decision 0018), fetched at build into client/brand/ (gitignored). */
|
|
12
|
-
const BRAND_DIR = () => new URL('../client/brand', import.meta.url)
|
|
13
|
-
// The shell carries the base,
|
|
14
|
-
// console with neither (the person types a token); the platform serves it with a session token
|
|
15
|
-
// (skip the sign-in) and `managed` set (a world opens on its own host, never proxied through here).
|
|
17
|
+
const BRAND_DIR = () => pathOf(new URL('../client/brand', import.meta.url));
|
|
18
|
+
// The shell carries the base, where the Worlds are served, and whether it is a World's own origin.
|
|
16
19
|
const attr = (v) => v.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<');
|
|
17
20
|
/** Volter World's mark, served by the brand (brand.volter.ai): the favicon. */
|
|
18
21
|
const WORLD_LOGO = 'https://brand.volter.ai/logo/twin-world/svg?size=64&variant=mono';
|
|
19
22
|
const SHELL = (base, opts = {}) => `<!doctype html>
|
|
20
23
|
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
21
24
|
<title>Volter World</title><link rel="icon" type="image/svg+xml" href="${WORLD_LOGO}"><link rel="stylesheet" href="${base}/brand/tokens.css"><link rel="stylesheet" href="${base}/styles.css"></head>
|
|
22
|
-
<body><div id="root" data-base="${base}"${opts.worlds ? ` data-worlds="${attr(opts.worlds)}"` : ''}${opts.names?.length ? ` data-names="${attr(opts.names.join(','))}"` : ''}${opts.
|
|
25
|
+
<body><div id="root" data-base="${base}"${opts.worlds ? ` data-worlds="${attr(opts.worlds)}"` : ''}${opts.names?.length ? ` data-names="${attr(opts.names.join(','))}"` : ''}${opts.worldOrigin ? ' data-world-origin="1"' : ''}></div><script type="module" src="${base}/app.js"></script></body></html>`;
|
|
26
|
+
/** The dashboard's pages run only their own origin's scripts (a `javascript:` link or an injected script runs nothing) and
|
|
27
|
+
* are framed by nothing; frames and images stay open, since a console on its own origin frames the Worlds'. */
|
|
28
|
+
export const DASHBOARD_CSP = "script-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'";
|
|
23
29
|
/** The client, built once per process and kept (bundleClient: Bun.build under Bun, the prebuilt
|
|
24
30
|
* dist/client/console.bundle.js under Node, written by this package's build). */
|
|
25
31
|
export function buildConsoleClient() { return bundleClient(CLIENT_ENTRY()); }
|
|
26
|
-
/** The
|
|
27
|
-
*
|
|
28
|
-
* path (the client routes by path: `base/<org>/<world>`), or null for a path
|
|
32
|
+
/** The dashboard as a host mounts it: `handle(request, '/-/console')` answers the shell at `base/`, the bundle at
|
|
33
|
+
* `base/app.js`, the styles at `base/styles.css` (the kit's, then the dashboard's) over the brand's at `base/brand/`,
|
|
34
|
+
* and the shell again for any deeper path (the client routes by path: `base/<org>/<world>`), or null for a path
|
|
35
|
+
* outside `base`. */
|
|
29
36
|
export function createConsole() {
|
|
30
37
|
return {
|
|
31
38
|
async handle(request, base, opts = {}) {
|
|
@@ -42,16 +49,21 @@ export function createConsole() {
|
|
|
42
49
|
return new Response(String(error), { status: 500 });
|
|
43
50
|
}
|
|
44
51
|
}
|
|
52
|
+
// React Flow's stylesheet (the canvas of the vendors' screens), then the kit's, then the dashboard's, which themes both
|
|
45
53
|
if (path === `${base}/styles.css`)
|
|
46
|
-
return
|
|
54
|
+
return new Response(`${readFileSync(createRequire(import.meta.url).resolve('@xyflow/react/dist/style.css'), 'utf8')}\n${kitCss()}\n${readFileSync(CLIENT_CSS(), 'utf8')}`, { headers: { 'content-type': 'text/css; charset=utf-8', 'cache-control': 'no-cache' } });
|
|
47
55
|
if (path.startsWith(`${base}/brand/`))
|
|
48
|
-
return
|
|
56
|
+
return brandAsset(path.slice(`${base}/brand/`.length));
|
|
49
57
|
if (path === base)
|
|
50
58
|
return Response.redirect(`${base}/`, 302);
|
|
51
|
-
return new Response(SHELL(base, { ...(opts.worlds ? { worlds: opts.worlds } : {}), ...(opts.names?.length ? { names: opts.names } : {}) }), { headers: { 'content-type': 'text/html; charset=utf-8', 'cache-control': 'no-cache' } });
|
|
52
|
-
},
|
|
53
|
-
shell(base, opts) {
|
|
54
|
-
return new Response(SHELL(base, opts), { headers: { 'content-type': 'text/html; charset=utf-8', 'cache-control': 'no-cache' } });
|
|
59
|
+
return new Response(SHELL(base, { ...(opts.worlds ? { worlds: opts.worlds } : {}), ...(opts.names?.length ? { names: opts.names } : {}), ...(opts.worldOrigin ? { worldOrigin: true } : {}) }), { headers: { 'content-type': 'text/html; charset=utf-8', 'cache-control': 'no-cache', 'content-security-policy': DASHBOARD_CSP } });
|
|
55
60
|
},
|
|
56
61
|
};
|
|
57
62
|
}
|
|
63
|
+
/** The kit's stylesheet (client/kit/kit.css): the roles and pieces every Volter World page shares. The platform's
|
|
64
|
+
* pages serve it before their own sheet. */
|
|
65
|
+
export function kitCss() { return readFileSync(KIT_CSS(), 'utf8'); }
|
|
66
|
+
/** The brand's tokens and faces (client/brand/, fetched at build) under a mount's `brand/`; `rest` is the path after it. */
|
|
67
|
+
export function brandAsset(rest) { return brandTokensResponse(BRAND_DIR(), rest); }
|
|
68
|
+
/** The brand's mark, for a page's favicon and header. */
|
|
69
|
+
export { WORLD_LOGO };
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/world-console",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"description": "The
|
|
3
|
+
"version": "2.0.2",
|
|
4
|
+
"description": "The dashboard of Volter World: a World's pages, the same on a laptop, a self-hosted host and the hosted cloud — mounted by the host at /-/console/. A pure frontend over the World's own doors; its kit (./kit) is the pieces the platform's pages share.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
8
8
|
"types": "./dist/src/console.d.ts",
|
|
9
9
|
"default": "./dist/src/console.js"
|
|
10
|
-
}
|
|
10
|
+
},
|
|
11
|
+
"./kit": "./client/kit/kit.tsx"
|
|
11
12
|
},
|
|
12
13
|
"scripts": {
|
|
13
14
|
"test": "bun test src/*.uitest.ts",
|
|
@@ -17,12 +18,13 @@
|
|
|
17
18
|
"postpack": "node ../../scripts/publish/prepare-publish.mjs postpack"
|
|
18
19
|
},
|
|
19
20
|
"dependencies": {
|
|
21
|
+
"@xyflow/react": "^12.12.0",
|
|
20
22
|
"react": "^19.2.7",
|
|
21
23
|
"react-dom": "^19.2.7"
|
|
22
24
|
},
|
|
23
25
|
"devDependencies": {
|
|
24
|
-
"@volter/world-host": "2.0.
|
|
25
|
-
"@volter/world-runtime": "2.0.
|
|
26
|
+
"@volter/world-host": "2.0.2",
|
|
27
|
+
"@volter/world-runtime": "2.0.2",
|
|
26
28
|
"@volter/world-tooling": "0.1.0",
|
|
27
29
|
"@types/bun": "^1.2.20",
|
|
28
30
|
"@types/node": "^24.0.0",
|
|
@@ -47,7 +49,7 @@
|
|
|
47
49
|
],
|
|
48
50
|
"repository": {
|
|
49
51
|
"type": "git",
|
|
50
|
-
"url": "git+https://github.com/volter-ai/
|
|
52
|
+
"url": "git+https://github.com/volter-ai/twin.git",
|
|
51
53
|
"directory": "apps/console"
|
|
52
54
|
}
|
|
53
55
|
}
|
package/src/console.ts
CHANGED
|
@@ -1,44 +1,51 @@
|
|
|
1
|
-
// THE
|
|
2
|
-
// FRONTEND the way a pack's mirror is — a React client bundled by `Bun.build` at serve time behind
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
1
|
+
// THE DASHBOARD (apps/console/README.md; docs/contributing/architecture.md, "The hosted product"): a World's pages, a
|
|
2
|
+
// PURE FRONTEND the way a pack's mirror is — a React client bundled by `Bun.build` at serve time behind one app shell,
|
|
3
|
+
// with no data path of its own. Every read and every write it makes is a door of the host or of a world, called from
|
|
4
|
+
// the browser. The host mounts it at `/-/console/` (the same origin as the doors: one origin, no CORS). It is the same
|
|
5
|
+
// page on a laptop, a self-hosted host and Volter's cloud, and carries nothing of orgs or billing: the platform's pages
|
|
6
|
+
// are an app of their own, which reads the kit's assets exported at the end of this module. `handle` answers a request
|
|
7
|
+
// under `base` or returns null when the path is not the dashboard's.
|
|
8
8
|
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
import { readFileSync } from 'node:fs';
|
|
10
|
+
import { createRequire } from 'node:module';
|
|
11
|
+
import { brandTokensResponse, bundleClient } from '@volter/world-core';
|
|
12
|
+
/** A file URL's path as the filesystem names it: decoded, and without the leading slash before a Windows drive (`/C:/…`). */
|
|
13
|
+
const pathOf = (url: URL): string => decodeURIComponent(url.pathname).replace(/^\/([A-Za-z]:)/, '$1');
|
|
14
|
+
const CLIENT_ENTRY = () => pathOf(new URL('../client/console.tsx', import.meta.url)); // lazy: never a top-level import.meta.url URL (workerd)
|
|
15
|
+
const CLIENT_CSS = () => pathOf(new URL('../client/console.css', import.meta.url));
|
|
16
|
+
const KIT_CSS = () => pathOf(new URL('../client/kit/kit.css', import.meta.url));
|
|
12
17
|
/** The brand's tokens and faces (company decision 0018), fetched at build into client/brand/ (gitignored). */
|
|
13
|
-
const BRAND_DIR = () => new URL('../client/brand', import.meta.url)
|
|
18
|
+
const BRAND_DIR = () => pathOf(new URL('../client/brand', import.meta.url));
|
|
14
19
|
|
|
15
|
-
// The shell carries the base,
|
|
16
|
-
// console with neither (the person types a token); the platform serves it with a session token
|
|
17
|
-
// (skip the sign-in) and `managed` set (a world opens on its own host, never proxied through here).
|
|
20
|
+
// The shell carries the base, where the Worlds are served, and whether it is a World's own origin.
|
|
18
21
|
const attr = (v: string): string => v.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<');
|
|
19
22
|
/** Volter World's mark, served by the brand (brand.volter.ai): the favicon. */
|
|
20
23
|
const WORLD_LOGO = 'https://brand.volter.ai/logo/twin-world/svg?size=64&variant=mono';
|
|
21
|
-
const SHELL = (base: string, opts: {
|
|
24
|
+
const SHELL = (base: string, opts: { worlds?: string; names?: string[]; worldOrigin?: boolean } = {}): string => `<!doctype html>
|
|
22
25
|
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
23
26
|
<title>Volter World</title><link rel="icon" type="image/svg+xml" href="${WORLD_LOGO}"><link rel="stylesheet" href="${base}/brand/tokens.css"><link rel="stylesheet" href="${base}/styles.css"></head>
|
|
24
|
-
<body><div id="root" data-base="${base}"${opts.worlds ? ` data-worlds="${attr(opts.worlds)}"` : ''}${opts.names?.length ? ` data-names="${attr(opts.names.join(','))}"` : ''}${opts.
|
|
27
|
+
<body><div id="root" data-base="${base}"${opts.worlds ? ` data-worlds="${attr(opts.worlds)}"` : ''}${opts.names?.length ? ` data-names="${attr(opts.names.join(','))}"` : ''}${opts.worldOrigin ? ' data-world-origin="1"' : ''}></div><script type="module" src="${base}/app.js"></script></body></html>`;
|
|
28
|
+
|
|
29
|
+
/** The dashboard's pages run only their own origin's scripts (a `javascript:` link or an injected script runs nothing) and
|
|
30
|
+
* are framed by nothing; frames and images stay open, since a console on its own origin frames the Worlds'. */
|
|
31
|
+
export const DASHBOARD_CSP = "script-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'";
|
|
25
32
|
|
|
26
33
|
export type ConsoleMount = {
|
|
27
34
|
/** `worlds`: the origin the Worlds are served at, when the console has an origin of its own; `names`: the
|
|
28
|
-
* Worlds (`<org>/<world>`) a World token may open there, for a host that does not list its Worlds (a hosted one)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
shell: (base: string, opts: { token: string; managed: boolean; scripts?: string }) => Response;
|
|
35
|
+
* Worlds (`<org>/<world>`) a World token may open there, for a host that does not list its Worlds (a hosted one);
|
|
36
|
+
* `worldOrigin`: this page is served on a World's own origin, beside its twins and mirrors, so it keeps no token
|
|
37
|
+
* script can read. */
|
|
38
|
+
handle: (request: Request, base: string, opts?: { worlds?: string; names?: string[]; worldOrigin?: boolean }) => Promise<Response | null>;
|
|
33
39
|
};
|
|
34
40
|
|
|
35
41
|
/** The client, built once per process and kept (bundleClient: Bun.build under Bun, the prebuilt
|
|
36
42
|
* dist/client/console.bundle.js under Node, written by this package's build). */
|
|
37
43
|
export function buildConsoleClient(): Promise<string> { return bundleClient(CLIENT_ENTRY()); }
|
|
38
44
|
|
|
39
|
-
/** The
|
|
40
|
-
*
|
|
41
|
-
* path (the client routes by path: `base/<org>/<world>`), or null for a path
|
|
45
|
+
/** The dashboard as a host mounts it: `handle(request, '/-/console')` answers the shell at `base/`, the bundle at
|
|
46
|
+
* `base/app.js`, the styles at `base/styles.css` (the kit's, then the dashboard's) over the brand's at `base/brand/`,
|
|
47
|
+
* and the shell again for any deeper path (the client routes by path: `base/<org>/<world>`), or null for a path
|
|
48
|
+
* outside `base`. */
|
|
42
49
|
export function createConsole(): ConsoleMount {
|
|
43
50
|
return {
|
|
44
51
|
async handle(request, base, opts = {}) {
|
|
@@ -49,13 +56,19 @@ export function createConsole(): ConsoleMount {
|
|
|
49
56
|
try { return new Response(await buildConsoleClient(), { headers: { 'content-type': 'text/javascript; charset=utf-8', 'cache-control': 'no-cache' } }); }
|
|
50
57
|
catch (error) { return new Response(String(error), { status: 500 }); }
|
|
51
58
|
}
|
|
52
|
-
|
|
53
|
-
if (path
|
|
59
|
+
// React Flow's stylesheet (the canvas of the vendors' screens), then the kit's, then the dashboard's, which themes both
|
|
60
|
+
if (path === `${base}/styles.css`) return new Response(`${readFileSync(createRequire(import.meta.url).resolve('@xyflow/react/dist/style.css'), 'utf8')}\n${kitCss()}\n${readFileSync(CLIENT_CSS(), 'utf8')}`, { headers: { 'content-type': 'text/css; charset=utf-8', 'cache-control': 'no-cache' } });
|
|
61
|
+
if (path.startsWith(`${base}/brand/`)) return brandAsset(path.slice(`${base}/brand/`.length));
|
|
54
62
|
if (path === base) return Response.redirect(`${base}/`, 302);
|
|
55
|
-
return new Response(SHELL(base, { ...(opts.worlds ? { worlds: opts.worlds } : {}), ...(opts.names?.length ? { names: opts.names } : {}) }), { headers: { 'content-type': 'text/html; charset=utf-8', 'cache-control': 'no-cache' } });
|
|
56
|
-
},
|
|
57
|
-
shell(base, opts) {
|
|
58
|
-
return new Response(SHELL(base, opts), { headers: { 'content-type': 'text/html; charset=utf-8', 'cache-control': 'no-cache' } });
|
|
63
|
+
return new Response(SHELL(base, { ...(opts.worlds ? { worlds: opts.worlds } : {}), ...(opts.names?.length ? { names: opts.names } : {}), ...(opts.worldOrigin ? { worldOrigin: true } : {}) }), { headers: { 'content-type': 'text/html; charset=utf-8', 'cache-control': 'no-cache', 'content-security-policy': DASHBOARD_CSP } });
|
|
59
64
|
},
|
|
60
65
|
};
|
|
61
66
|
}
|
|
67
|
+
|
|
68
|
+
/** The kit's stylesheet (client/kit/kit.css): the roles and pieces every Volter World page shares. The platform's
|
|
69
|
+
* pages serve it before their own sheet. */
|
|
70
|
+
export function kitCss(): string { return readFileSync(KIT_CSS(), 'utf8'); }
|
|
71
|
+
/** The brand's tokens and faces (client/brand/, fetched at build) under a mount's `brand/`; `rest` is the path after it. */
|
|
72
|
+
export function brandAsset(rest: string): Response { return brandTokensResponse(BRAND_DIR(), rest); }
|
|
73
|
+
/** The brand's mark, for a page's favicon and header. */
|
|
74
|
+
export { WORLD_LOGO };
|