diff --git a/package.json b/package.json index 6389c4a9bd..6857f41e92 100644 --- a/package.json +++ b/package.json @@ -41,17 +41,16 @@ "tslib": "^2.6.2", "typescript": "^5.2.2", "vite": "^4.4.9", + "vite-plugin-dynamic-import": "^1.5.0", "vitest": "^0.32.4" }, "type": "module", "dependencies": { - "@apidevtools/swagger-parser": "^10.1.0", "@appwrite.io/pink": "0.0.7-sl10.0", - "@appwrite.io/repo": "github:appwrite/appwrite", + "@appwrite.io/pink-icons": "0.0.7-sl10.0", "@fontsource/inter": "^5.0.8", "highlight.js": "^11.8.0", "markdown-it": "^13.0.1", - "motion": "^10.16.2", - "vite-plugin-dynamic-import": "^1.5.0" + "motion": "^10.16.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4c3edb9fec..c758bb7d62 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,15 +5,12 @@ settings: excludeLinksFromLockfile: false dependencies: - '@apidevtools/swagger-parser': - specifier: ^10.1.0 - version: 10.1.0(openapi-types@12.1.3) '@appwrite.io/pink': specifier: 0.0.7-sl10.0 version: 0.0.7-sl10.0 - '@appwrite.io/repo': - specifier: github:appwrite/appwrite - version: github.com/appwrite/appwrite/ddb73eb4f60aa807fd0bfe8622da32a69738077a + '@appwrite.io/pink-icons': + specifier: 0.0.7-sl10.0 + version: 0.0.7-sl10.0 '@fontsource/inter': specifier: ^5.0.8 version: 5.0.8 @@ -26,9 +23,6 @@ dependencies: motion: specifier: ^10.16.2 version: 10.16.2 - vite-plugin-dynamic-import: - specifier: ^1.5.0 - version: 1.5.0 devDependencies: '@melt-ui/pp': @@ -102,7 +96,10 @@ devDependencies: version: 5.2.2 vite: specifier: ^4.4.9 - version: 4.4.9(@types/node@20.6.0)(sass@1.66.1) + version: 4.4.9(@types/node@20.5.0)(sass@1.66.1) + vite-plugin-dynamic-import: + specifier: ^1.5.0 + version: 1.5.0 vitest: specifier: ^0.32.4 version: 0.32.4(sass@1.66.1) @@ -122,38 +119,6 @@ packages: '@jridgewell/trace-mapping': 0.3.19 dev: true - /@apidevtools/json-schema-ref-parser@9.0.6: - resolution: {integrity: sha512-M3YgsLjI0lZxvrpeGVk9Ap032W6TPQkH6pRAZz81Ac3WUNF79VQooAFnp8umjvVzUmD93NkogxEwbSce7qMsUg==} - dependencies: - '@jsdevtools/ono': 7.1.3 - call-me-maybe: 1.0.2 - js-yaml: 3.14.1 - dev: false - - /@apidevtools/openapi-schemas@2.1.0: - resolution: {integrity: sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==} - engines: {node: '>=10'} - dev: false - - /@apidevtools/swagger-methods@3.0.2: - resolution: {integrity: sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==} - dev: false - - /@apidevtools/swagger-parser@10.1.0(openapi-types@12.1.3): - resolution: {integrity: sha512-9Kt7EuS/7WbMAUv2gSziqjvxwDbFSg3Xeyfuj5laUODX8o/k/CpsAKiQ8W7/R88eXFTMbJYg6+7uAmOWNKmwnw==} - peerDependencies: - openapi-types: '>=7' - dependencies: - '@apidevtools/json-schema-ref-parser': 9.0.6 - '@apidevtools/openapi-schemas': 2.1.0 - '@apidevtools/swagger-methods': 3.0.2 - '@jsdevtools/ono': 7.1.3 - ajv: 8.12.0 - ajv-draft-04: 1.0.0(ajv@8.12.0) - call-me-maybe: 1.0.2 - openapi-types: 12.1.3 - dev: false - /@appwrite.io/pink-icons@0.0.7-sl10.0: resolution: {integrity: sha512-lEC79/0YEWVbwtIFgwONbBelNX07I2d3q2fmzub3X3DR/0ZB4JMy5zyO0h8EMbOB00DxkI8rW7KlwDSstQ3fGw==} dev: false @@ -868,6 +833,7 @@ packages: /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true /@jridgewell/trace-mapping@0.3.19: resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==} @@ -876,10 +842,6 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true - /@jsdevtools/ono@7.1.3: - resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} - dev: false - /@markdoc/markdoc@0.3.2: resolution: {integrity: sha512-D0SaanaSkTIARvQu+zQqPEpKcvYUBR/mfac9e8JzS89P7eXhiNWPonUN7avRS1saZHpIQWIRote97qT+jGk5Gw==} engines: {node: '>=14.7.0'} @@ -986,10 +948,12 @@ packages: dependencies: '@nodelib/fs.stat': 2.0.5 run-parallel: 1.2.0 + dev: true /@nodelib/fs.stat@2.0.5: resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} + dev: true /@nodelib/fs.walk@1.2.8: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} @@ -997,6 +961,7 @@ packages: dependencies: '@nodelib/fs.scandir': 2.1.5 fastq: 1.15.0 + dev: true /@npmcli/fs@3.1.0: resolution: {integrity: sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==} @@ -1552,6 +1517,7 @@ packages: resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} engines: {node: '>=0.4.0'} hasBin: true + dev: true /agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} @@ -1577,17 +1543,6 @@ packages: indent-string: 4.0.0 dev: true - /ajv-draft-04@1.0.0(ajv@8.12.0): - resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} - peerDependencies: - ajv: ^8.5.0 - peerDependenciesMeta: - ajv: - optional: true - dependencies: - ajv: 8.12.0 - dev: false - /ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} dependencies: @@ -1597,15 +1552,6 @@ packages: uri-js: 4.4.1 dev: true - /ajv@8.12.0: - resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} - dependencies: - fast-deep-equal: 3.1.3 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - uri-js: 4.4.1 - dev: false - /ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -1666,12 +1612,6 @@ packages: readable-stream: 3.6.2 dev: true - /argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - dependencies: - sprintf-js: 1.0.3 - dev: false - /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -1820,6 +1760,7 @@ packages: engines: {node: '>=8'} dependencies: fill-range: 7.0.1 + dev: true /buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} @@ -1889,10 +1830,6 @@ packages: unset-value: 1.0.0 dev: true - /call-me-maybe@1.0.2: - resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} - dev: false - /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -2366,7 +2303,7 @@ packages: /es-module-lexer@1.3.1: resolution: {integrity: sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==} - dev: false + dev: true /es6-promise@3.3.1: resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==} @@ -2529,12 +2466,6 @@ packages: eslint-visitor-keys: 3.4.3 dev: true - /esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - dev: false - /esquery@1.5.0: resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} engines: {node: '>=0.10'} @@ -2630,6 +2561,7 @@ packages: /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true /fast-glob@3.3.1: resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} @@ -2640,6 +2572,7 @@ packages: glob-parent: 5.1.2 merge2: 1.4.1 micromatch: 4.0.5 + dev: true /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} @@ -2653,6 +2586,7 @@ packages: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} dependencies: reusify: 1.0.4 + dev: true /file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} @@ -2695,6 +2629,7 @@ packages: engines: {node: '>=8'} dependencies: to-regex-range: 5.0.1 + dev: true /find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} @@ -2826,6 +2761,7 @@ packages: engines: {node: '>= 6'} dependencies: is-glob: 4.0.3 + dev: true /glob-parent@6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} @@ -3168,6 +3104,7 @@ packages: /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + dev: true /is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} @@ -3183,6 +3120,7 @@ packages: engines: {node: '>=0.10.0'} dependencies: is-extglob: 2.1.1 + dev: true /is-lambda@1.0.1: resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} @@ -3198,6 +3136,7 @@ packages: /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + dev: true /is-path-cwd@2.2.0: resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} @@ -3286,14 +3225,6 @@ packages: resolution: {integrity: sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==} dev: true - /js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - dev: false - /js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true @@ -3309,10 +3240,6 @@ packages: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} dev: true - /json-schema-traverse@1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - dev: false - /json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} dev: true @@ -3477,6 +3404,7 @@ packages: engines: {node: '>=12'} dependencies: '@jridgewell/sourcemap-codec': 1.4.15 + dev: true /make-fetch-happen@11.1.1: resolution: {integrity: sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==} @@ -3552,6 +3480,7 @@ packages: /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + dev: true /microbuffer@1.0.0: resolution: {integrity: sha512-O/SUXauVN4x6RaEJFqSPcXNtLFL+QzJHKZlyDVYFwcDDRVca3Fa/37QXXC+4zAGGa4YhHrHxKXuuHvLDIQECtA==} @@ -3584,6 +3513,7 @@ packages: dependencies: braces: 3.0.2 picomatch: 2.3.1 + dev: true /mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} @@ -3942,6 +3872,7 @@ packages: /openapi-types@12.1.3: resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} + dev: true /optionator@0.9.3: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} @@ -4129,6 +4060,7 @@ packages: /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + dev: true /pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} @@ -4285,9 +4217,11 @@ packages: /punycode@2.3.0: resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} engines: {node: '>=6'} + dev: true /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true /react-is@18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} @@ -4370,11 +4304,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} - dev: false - /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -4398,6 +4327,7 @@ packages: /reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true /rimraf@2.7.1: resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} @@ -4425,6 +4355,7 @@ packages: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: queue-microtask: 1.2.3 + dev: true /sade@1.8.1: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} @@ -4646,10 +4577,6 @@ packages: through2: 2.0.5 dev: true - /sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - dev: false - /ssri@10.0.5: resolution: {integrity: sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -5083,6 +5010,7 @@ packages: engines: {node: '>=8.0'} dependencies: is-number: 7.0.0 + dev: true /to-regex@3.0.2: resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} @@ -5243,6 +5171,7 @@ packages: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: punycode: 2.3.0 + dev: true /urix@0.1.0: resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} @@ -5297,8 +5226,8 @@ packages: acorn: 8.10.0 es-module-lexer: 1.3.1 fast-glob: 3.3.1 - magic-string: 0.30.3 - dev: false + magic-string: 0.30.2 + dev: true /vite@4.4.9(@types/node@20.6.0)(sass@1.66.1): resolution: {integrity: sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==} diff --git a/src/app.html b/src/app.html index 7354bb1147..07adef7519 100644 --- a/src/app.html +++ b/src/app.html @@ -3,13 +3,16 @@ - Appwrite Next %sveltekit.head% +
diff --git a/src/lib/animations/AutoBox.svelte b/src/lib/animations/AutoBox.svelte new file mode 100644 index 0000000000..7b7a7b14bc --- /dev/null +++ b/src/lib/animations/AutoBox.svelte @@ -0,0 +1,34 @@ + + +
+
+
+ +
+
+ + diff --git a/src/lib/animations/CodeWindow/Code.svelte b/src/lib/animations/CodeWindow/Code.svelte new file mode 100644 index 0000000000..8e6dea4510 --- /dev/null +++ b/src/lib/animations/CodeWindow/Code.svelte @@ -0,0 +1,11 @@ + + + +{@html codeHtml} diff --git a/src/lib/animations/CodeWindow/CodeWindow.svelte b/src/lib/animations/CodeWindow/CodeWindow.svelte new file mode 100644 index 0000000000..611d2fd69e --- /dev/null +++ b/src/lib/animations/CodeWindow/CodeWindow.svelte @@ -0,0 +1,94 @@ + + +
+
+
+
+
+
+
+ + + +
+
+
+ + diff --git a/src/lib/animations/OpenSource.svelte b/src/lib/animations/OpenSource.svelte index adaa79012d..65f87efb3b 100644 --- a/src/lib/animations/OpenSource.svelte +++ b/src/lib/animations/OpenSource.svelte @@ -22,7 +22,7 @@ { mobile: { main: animation('#oss-discord', { x: 0, y: 0, rotate: 1 }, animationOptions), - reversed: animation('#oss-discord', { x: -1200, y: 0, rotate: 1 }, animationOptions) + reversed: animation('#oss-discord', { y: 1200, x: 0, rotate: 1 }, animationOptions) }, desktop: { main: animation('#oss-discord', { x: 20, y: '-80vh', rotate: 15 }, animationOptions), @@ -32,7 +32,7 @@ { mobile: { main: animation('#oss-github', { x: 0, y: -10, rotate: -2 }, animationOptions), - reversed: animation('#oss-github', { x: -1200, y: 10, rotate: -2 }, animationOptions) + reversed: animation('#oss-github', { y: 1200, x: 10, rotate: -2 }, animationOptions) }, desktop: { main: animation('#oss-github', { x: -100, y: '-55vh', rotate: 6.26 }, animationOptions), @@ -42,7 +42,7 @@ { mobile: { main: animation('#oss-twitter', { x: 0, y: 10, rotate: -3 }, animationOptions), - reversed: animation('#oss-twitter', { x: -1200, y: -10, rotate: -3 }, animationOptions) + reversed: animation('#oss-twitter', { y: 1200, x: -10, rotate: -3 }, animationOptions) }, desktop: { main: animation('#oss-twitter', { x: 100, y: '-70vh', rotate: -15 }, animationOptions), @@ -52,7 +52,7 @@ { mobile: { main: animation('#oss-youtube', { x: 0, y: 5, rotate: 2 }, animationOptions), - reversed: animation('#oss-youtube', { x: -1200, y: -5, rotate: 2 }, animationOptions) + reversed: animation('#oss-youtube', { y: 1200, x: -5, rotate: 2 }, animationOptions) }, desktop: { main: animation('#oss-youtube', { x: -100, y: '-55vh', rotate: -3.77 }, animationOptions), @@ -62,7 +62,7 @@ { mobile: { main: animation('#oss-commits', { x: 0, y: -4, rotate: -1 }, animationOptions), - reversed: animation('#oss-commits', { x: -1200, y: 4, rotate: -1 }, animationOptions) + reversed: animation('#oss-commits', { y: 1200, x: 4, rotate: -1 }, animationOptions) }, desktop: { main: animation('#oss-commits', { x: 100, y: '-80vh', rotate: -10.2 }, animationOptions), @@ -72,7 +72,7 @@ ]; const animScale: Scale = [0, animations.length - 1]; - const percentScale: Scale = [0.1, 0.8]; + const percentScale: Scale = [0.1, 0.9]; const scrollHandler = createScrollHandler( animations.map(({ mobile, desktop }, i) => { @@ -115,27 +115,30 @@

-
-
125k+ Discord Members
+
17k+ Discord Members
-
32k+ GitHub Stars
-
+ -
@@ -143,27 +146,25 @@
125k+ Twitter Followers
-
+ - -
15k+ Code Commits
-
+
@@ -246,6 +247,10 @@ height: var(--h); text-align: left; + display: flex; + flex-direction: column; + justify-content: space-between; + position: absolute; left: calc(50% - calc(var(--w) / 2)); transform: translateX(-1200px); diff --git a/src/lib/animations/Phone.svelte b/src/lib/animations/Phone.svelte new file mode 100644 index 0000000000..16fc2a840a --- /dev/null +++ b/src/lib/animations/Phone.svelte @@ -0,0 +1,9 @@ + + +
+
+ +
+
diff --git a/src/lib/animations/Products.svelte b/src/lib/animations/Products.svelte deleted file mode 100644 index 374af87f67..0000000000 --- a/src/lib/animations/Products.svelte +++ /dev/null @@ -1,303 +0,0 @@ - - -
{ - const { percentage } = detail; - scrollInfo = detail; - }} -> -
-
- {#if scrollInfo.percentage > 0} - Products_ - {/if} - {#if scrollInfo.percentage > 0.075} -

- Your backend, minus the hassle -

- {/if} - {#if scrollInfo.percentage > 0.15} -

- Build secure and scalable applications faster with Appwrite's core backend products and - spend more time building the best products. -

- {/if} -
- - {#if scrollInfo.percentage > 0.25} -
-
- -
    -
  • -

    - - Auth -

    -

    Secure login for all your users

    -

    Sign in users with multiple OAuth providers and multi factor authentication.

    -
      -
    • Two-Factor Authentication support
    • -
    • 30+ login methods
    • -
    • State-of-the-art password hashing support
    • -
    -
  • -
-
- -
-

Create an Account

-

Please enter your details

-
-
- - -
-
- - -
-
- - -
-
- -
-
-
- {/if} -
-
- - diff --git a/src/lib/animations/Products/AnimatedBox.svelte b/src/lib/animations/Products/AnimatedBox.svelte new file mode 100644 index 0000000000..0b3a4c84eb --- /dev/null +++ b/src/lib/animations/Products/AnimatedBox.svelte @@ -0,0 +1,53 @@ + + +
+
+
+ + + +
+
+ + diff --git a/src/lib/animations/Products/Products.svelte b/src/lib/animations/Products/Products.svelte new file mode 100644 index 0000000000..36968604fa --- /dev/null +++ b/src/lib/animations/Products/Products.svelte @@ -0,0 +1,641 @@ + + + + +
{ + scrollInfo = detail; + }} +> +
+ + + {#if scrollInfo.percentage < 0.1} +
+ {#if scrollInfo.percentage > 0} + Products_ + +

+ Your backend, minus the hassle +

+

+ Build secure and scalable applications faster with Appwrite's core backend products and + spend more time building the best products. +

+ {/if} +
+ {:else} +
0.1 ? '' : undefined} + > +
+ +
    + {#each products as product} + {@const copy = infos[product]} + {@const isActive = active.product === product} + + {#if copy} +
  • +

    + + {copy.title} +

    + {#if isActive} +
    +

    {copy.subtitle}

    +

    + {copy.description} +

    +
      + {#each copy.features as feature} +
    • {feature}
    • + {/each} +
    +
    + {/if} +
  • + {/if} + {/each} +
+
+ +
+
+ +
+

+ {#if active.product === 'auth'} + Users + {:else if active.product === 'databases'} + Tasks + {:else if active.product === 'storage'} + Files + {:else if active.product === 'functions'} + + {:else if active.product === 'realtime'} + Realtime + {/if} +

+
+ + {#if active.product === 'auth'} + + {:else if active.product === 'databases'} + + {:else if active.product === 'storage'} + + {/if} +
+
+ +
+ + {#if active.product === 'auth'} + + {:else if active.product === 'databases'} + + {:else if active.product === 'storage'} + + {:else if active.product === 'functions'} + + {/if} + +
+ + {#if active.product === 'auth'} +
+ +
+ {/if} +
+ +
+
+ {#if active.product === 'auth'} + + {:else if active.product === 'databases'} + + {:else if active.product === 'storage'} + + {:else if active.product === 'functions'} + + {:else if !['auth', 'databases', 'storage', 'functions'].includes(anyify(active.product))} + + {/if} +
+
+ + {#if !['auth', 'databases', 'storage', 'functions', 'realtime'].includes(anyify(active.product))} + + {/if} +
+ {/if} +
+
+ + diff --git a/src/lib/animations/Products/ProductsMobile.svelte b/src/lib/animations/Products/ProductsMobile.svelte new file mode 100644 index 0000000000..84d6ace6b9 --- /dev/null +++ b/src/lib/animations/Products/ProductsMobile.svelte @@ -0,0 +1,202 @@ + + +
+ Products_ + +

+ Your backend, minus the hassle +

+ +

+ Build secure and scalable applications faster with Appwrite's core backend products and spend + more time building the best products. +

+ +
+ {#each objectKeys(infos) as prod} + {@const info = infos[prod]} + + {#if info} +
+

+ + {info.title} +

+ +

{info.subtitle}

+

+ {info.description} +

+
    + {#each info.features as feature} +
  • {feature}
  • + {/each} +
+ + {#if info.shot} + + {/if} +
+ {/if} + {/each} +
+ +
+ +
+ +

See your products grow

+

+ Keep track of your projects progress and see them grow into products users love and use every + day. +

+
+
+ + diff --git a/src/lib/animations/Products/TaskCheckbox.svelte b/src/lib/animations/Products/TaskCheckbox.svelte new file mode 100644 index 0000000000..22560340e4 --- /dev/null +++ b/src/lib/animations/Products/TaskCheckbox.svelte @@ -0,0 +1,61 @@ + + +
+ +
+ + diff --git a/src/lib/animations/Products/auth/box.svelte b/src/lib/animations/Products/auth/box.svelte new file mode 100644 index 0000000000..73885d25e1 --- /dev/null +++ b/src/lib/animations/Products/auth/box.svelte @@ -0,0 +1,64 @@ + + +
+
+ Name + Identifier +
+ {#each authData as user (user.id)} +
+
+
{user.avatar}
+ {user.name} +
+ {user.email} +
+ {/each} +
diff --git a/src/lib/animations/Products/auth/code.svelte b/src/lib/animations/Products/auth/code.svelte new file mode 100644 index 0000000000..9ac922cb92 --- /dev/null +++ b/src/lib/animations/Products/auth/code.svelte @@ -0,0 +1,16 @@ + + + diff --git a/src/lib/animations/Products/auth/controls.svelte b/src/lib/animations/Products/auth/controls.svelte new file mode 100644 index 0000000000..d1d84fd1eb --- /dev/null +++ b/src/lib/animations/Products/auth/controls.svelte @@ -0,0 +1,77 @@ + + +
+ {#each objectKeys($state.controls) as provider, i} + {@const isLast = i === objectKeys($state.controls).length - 1} +
+ + {provider} + +
+ {#if !isLast} +
+ {/if} + {/each} +
+ + diff --git a/src/lib/animations/Products/auth/index.ts b/src/lib/animations/Products/auth/index.ts new file mode 100644 index 0000000000..e6435600a2 --- /dev/null +++ b/src/lib/animations/Products/auth/index.ts @@ -0,0 +1,95 @@ +import Box from './box.svelte'; +import Code from './code.svelte'; +import Controls from './controls.svelte'; +import Phone from './phone.svelte'; + +export const Auth = { + Phone, + Box, + Code, + Controls +}; + +import { safeAnimate, sleep, write } from '$lib/animations'; +import { createResettable } from '$lib/utils/resettable'; +import { getElSelector } from '../Products.svelte'; + +type State = { + email: string; + password: string; + name: string; + + showControls: boolean; + submitted: boolean; + controls: { + GitHub: boolean; + Google: boolean; + Apple: boolean; + Microsoft: boolean; + }; +}; + +const state = createResettable({ + email: '', + password: '', + name: "Walter O'Brian", + showControls: false, + submitted: false, + controls: { + GitHub: true, + Google: false, + Apple: false, + Microsoft: false + } +}); + +const emailToSet = 'walterobrian@example.com'; +const passwordToSet = 'password'; + +const execute = async () => { + const phone = getElSelector('phone'); + const box = getElSelector('box'); + const code = getElSelector('code'); + const controls = getElSelector('controls'); + + // Reset + const { update } = state.reset(); + + await Promise.all([ + safeAnimate(box, { x: 310, y: 32, opacity: 0 }, { duration: 0.5 })?.finished, + safeAnimate(code, { x: 200, y: 460, opacity: 0 }, { duration: 0.5 })?.finished, + safeAnimate(phone, { x: 0, y: 0 }, { duration: 0.5 })?.finished, + safeAnimate(controls, { x: 420, y: 0, opacity: 0 }, { duration: 0.5 })?.finished + ]); + + // Start + await safeAnimate(box, { y: [48, 32], opacity: 1 }, { duration: 0.25, delay: 1 })?.finished; + + await sleep(150); + + await write(emailToSet, (v) => update((p) => ({ ...p, email: v })), 300); + await sleep(150); + + await write(passwordToSet, (v) => update((p) => ({ ...p, password: v })), 300); + await sleep(500); + + await safeAnimate( + code, + { x: [200, 200], y: [460 + 16, 460], opacity: [0, 1] }, + { duration: 0.25 } + )?.finished; + + await sleep(500); + + update((p) => ({ ...p, submitted: true })); + + await sleep(1000); + + update((p) => ({ ...p, showControls: true })); + safeAnimate(controls, { x: [420, 420], y: [16, 0], opacity: 1 }, { duration: 0.5 }); +}; + +export const authController = { + execute, + state +}; diff --git a/src/lib/animations/Products/auth/phone.svelte b/src/lib/animations/Products/auth/phone.svelte new file mode 100644 index 0000000000..e8446c2c8d --- /dev/null +++ b/src/lib/animations/Products/auth/phone.svelte @@ -0,0 +1,211 @@ + + +
+

Create an Account

+

Please enter your details

+
+
+ + +
+
+ + +
+
+ + +
+
+ + {#if controlsEnabled} + or sign up with +
+ {#each objectKeys($state.controls).filter((p) => $state.controls[p]) as provider (provider)} + + {/each} +
+ {/if} +
+ + diff --git a/src/lib/animations/Products/databases/box.svelte b/src/lib/animations/Products/databases/box.svelte new file mode 100644 index 0000000000..52c243e5c8 --- /dev/null +++ b/src/lib/animations/Products/databases/box.svelte @@ -0,0 +1,54 @@ + + +
+
+ Document ID + Task +
+ {#each $state.tasks.slice(0, $state.tableSlice) as task (task.id)} +
+
+ + {task.id} +
+ {task.title} +
+ {/each} +
+ + diff --git a/src/lib/animations/Products/databases/code.svelte b/src/lib/animations/Products/databases/code.svelte new file mode 100644 index 0000000000..81f85193e0 --- /dev/null +++ b/src/lib/animations/Products/databases/code.svelte @@ -0,0 +1,16 @@ + + + diff --git a/src/lib/animations/Products/databases/index.ts b/src/lib/animations/Products/databases/index.ts new file mode 100644 index 0000000000..40c112fd99 --- /dev/null +++ b/src/lib/animations/Products/databases/index.ts @@ -0,0 +1,94 @@ +import Box from './box.svelte'; +import Code from './code.svelte'; +import Phone from './phone.svelte'; + +import { safeAnimate, sleep } from '$lib/animations'; +import { createResettable } from '$lib/utils/resettable'; +import { getElSelector } from '../Products.svelte'; + +type Task = { + id: string; + title: string; + checked: boolean; +}; + +type State = { + tasks: Task[]; + tableSlice: number; +}; + +const state = createResettable({ + tasks: [ + { + id: '3397fecdedb13397fecdedb1', + title: 'Research user needs', + checked: true + } + ], + tableSlice: 1 +}); + +const execute = async () => { + const phone = getElSelector('phone'); + const box = getElSelector('box'); + const code = getElSelector('code'); + const { update } = state.reset(); + + await Promise.all([ + safeAnimate(phone, { x: 390, y: 0 }, { duration: 0.5 })?.finished, + safeAnimate(box, { x: 0, y: 32, opacity: 1 }, { duration: 0.5 })?.finished, + safeAnimate(code, { x: 80, y: 460, opacity: 1 }, { duration: 0.5 })?.finished + ]); + + await sleep(1000); + + update((p) => ({ + ...p, + tasks: [ + ...p.tasks, + { + id: '3397fecdedb13397fecdedb2', + title: 'Create wireframes', + checked: false + } + ] + })); + await sleep(500); + + update((p) => ({ + ...p, + tableSlice: p.tableSlice + 1 + })); + + await sleep(500); + + update((p) => ({ + ...p, + tasks: [ + ...p.tasks, + { + id: '3397fecdedb13397fecdedb3', + title: 'Create visual design', + checked: false + } + ] + })); + + await sleep(500); + + update((p) => ({ + ...p, + tableSlice: p.tableSlice + 1 + })); +}; + +export const databasesController = { + execute, + state +}; + +export const Databases = { + Phone, + Box, + Code +}; diff --git a/src/lib/animations/Products/databases/phone.svelte b/src/lib/animations/Products/databases/phone.svelte new file mode 100644 index 0000000000..624e8026fa --- /dev/null +++ b/src/lib/animations/Products/databases/phone.svelte @@ -0,0 +1,127 @@ + + +
+
+

Your tasks

+ +
+ +
Today
+
+ {#each $state.tasks as task (task.id)} +
+ + {task.title} +
+ {/each} +
+ + +
+ + diff --git a/src/lib/animations/Products/functions/code.svelte b/src/lib/animations/Products/functions/code.svelte new file mode 100644 index 0000000000..5afa78799a --- /dev/null +++ b/src/lib/animations/Products/functions/code.svelte @@ -0,0 +1,56 @@ + + + + +
+ {#if $state.submit !== 'idle'} + + {/if} + {#if $state.submit === 'loading'} + Pushing to GitHub... +
+ {:else if $state.submit === 'success'} + Deployed to GitHub + + {/if} +
+ + diff --git a/src/lib/animations/Products/functions/index.ts b/src/lib/animations/Products/functions/index.ts new file mode 100644 index 0000000000..48f0e640bf --- /dev/null +++ b/src/lib/animations/Products/functions/index.ts @@ -0,0 +1,58 @@ +import Code from './code.svelte'; +import Phone from './phone.svelte'; + +import { safeAnimate, sleep } from '$lib/animations'; +import { createResettable } from '$lib/utils/resettable'; +import { getElSelector } from '../Products.svelte'; + +type State = { + submit: 'idle' | 'loading' | 'success'; +}; + +const state = createResettable({ + submit: 'idle' +}); + +const execute = async () => { + const phone = getElSelector('phone'); + const box = getElSelector('box'); + const code = getElSelector('code'); + + const { update } = state.reset(); + + await Promise.all([ + safeAnimate(phone, { x: 460, y: 0, width: '275px' }, { duration: 0.5 })?.finished, + safeAnimate(code, { x: 0, y: 200, opacity: 0 }, { duration: 0.5 })?.finished, + safeAnimate(box, { opacity: 0 }, { duration: 0.5 })?.finished + ]); + + await sleep(500); + + await safeAnimate(code, { zIndex: 0 }, { duration: 0 })?.finished; + await safeAnimate(code, { y: [200 - 16, 200], opacity: 1 }, { duration: 0.5 })?.finished; + + await sleep(500); + + update((p) => ({ + ...p, + submit: 'loading' + })); + + await sleep(1500); + + update((p) => ({ + ...p, + submit: 'success' + })); +}; + +export const functionsController = { + execute, + state +}; + +export const Functions = { + Phone, + + Code +}; diff --git a/src/lib/animations/Products/functions/phone.svelte b/src/lib/animations/Products/functions/phone.svelte new file mode 100644 index 0000000000..bcd1ecd36c --- /dev/null +++ b/src/lib/animations/Products/functions/phone.svelte @@ -0,0 +1,325 @@ + + +
+
+

Upgrade plan

+ +
+ +
+

Premium plan

+
+

$20

+

/month

+
+
    +
  • Premium plan
  • +
  • Premium plan
  • +
  • Premium plan
  • +
+
+ +
    + {#each methods as method, i (method.label)} +
  • + +

    {method.label}

    +
  • + {/each} +
+ + {#if $state.submit !== 'success'} +
+

Card information

+
+
+

placeholder

+ + +
+
+

MM/YY

+

CVV

+
+
+
+ {/if} + + +
+ + diff --git a/src/lib/animations/Products/post/index.ts b/src/lib/animations/Products/post/index.ts new file mode 100644 index 0000000000..9a823e0bce --- /dev/null +++ b/src/lib/animations/Products/post/index.ts @@ -0,0 +1,53 @@ +import { safeAnimate, sleep } from '$lib/animations'; +import { createResettable } from '$lib/utils/resettable'; +import { animate } from 'motion'; +import { getElSelector } from '../Products.svelte'; + +const requests = createResettable(0); +const databases = createResettable(0); +const authentication = createResettable(0); +const storage = createResettable(0); +const bandwidth = createResettable(0); +const executions = createResettable(0); +const realtime = createResettable(0); + +const execute = async () => { + const phone = getElSelector('phone'); + const pd = getElSelector('pd'); + + const graphBox = getElSelector('graph-box'); + + const boxesAndStates = [ + { box: getElSelector('post-auth'), state: authentication.reset() }, + { box: getElSelector('post-storage'), state: storage.reset() }, + { box: getElSelector('post-bandwidth'), state: bandwidth.reset() }, + { box: getElSelector('post-functions'), state: executions.reset() }, + { box: getElSelector('post-databases'), state: databases.reset() }, + { box: getElSelector('post-realtime'), state: realtime.reset() }, + { box: getElSelector('post-requests'), state: requests.reset() } + ]; + + await Promise.all([ + safeAnimate(pd, { opacity: 0, y: -16 }, { duration: 0.5 })?.finished, + safeAnimate(graphBox, { opacity: 0, visibility: 'hidden' }, { duration: 0.5 })?.finished, + safeAnimate(phone, { x: '-50%', width: '660px' }, { duration: 1, delay: 0.5 })?.finished + ]); + + boxesAndStates.forEach(({ box, state }, i) => { + safeAnimate(box, { opacity: 1, y: [1200, 0] }, { duration: 0.5, delay: i * 0.1 })?.finished; + animate(state.set, { duration: 2, delay: (i + 1) * 0.25 }); + }); +}; + +export const postController = { + execute, + state: { + requests, + databases, + authentication, + storage, + bandwidth, + executions, + realtime + } +}; diff --git a/src/lib/animations/Products/post/post.svelte b/src/lib/animations/Products/post/post.svelte new file mode 100644 index 0000000000..e1b54e2c3a --- /dev/null +++ b/src/lib/animations/Products/post/post.svelte @@ -0,0 +1,292 @@ + + +
+
+

+

Authentication

+
+

{formatK(toScale($authentication, [0, 1], [0, 4000]))}

+
+

Users

+

Sessions: 20K

+
+
+ +
+
+

+

Storage

+
+

+ {toScale($storage, [0, 1], [0, 8]).toFixed(1)} GB +

+
+

Storage

+

Buckets: 44

+
+
+ +
+

+ {toScale($bandwidth, [0, 1], [0, 1.2]).toFixed(2)} GB +

+

Bandwidth

+ +
+ +
+
+

+

Functions

+
+

{toScale($executions, [0, 1], [0, 846]).toFixed(0)}

+
+

Executions

+
+
+ +
+
+

+

Databases

+
+

{toScale($databases, [0, 1], [0, 8]).toFixed(0)}

+
+

Databases

+

Documents: 20

+
+
+ +
+

{formatK(toScale($requests, [0, 1], [0, 6849]))}

+

Requests

+ +
+ +
+

{formatK(toScale($realtime, [0, 1], [0, 100000]))}

+

Realtime connections

+ +
+ +
+

See your products grow

+

+ Keep track of your projects progress and see them grow into products users love and use every + day. +

+
+ + diff --git a/src/lib/animations/Products/realtime/index.ts b/src/lib/animations/Products/realtime/index.ts new file mode 100644 index 0000000000..a3386303da --- /dev/null +++ b/src/lib/animations/Products/realtime/index.ts @@ -0,0 +1,234 @@ +import Phone from './phone.svelte'; + +import { safeAnimate, sleep } from '$lib/animations'; +import { createResettable } from '$lib/utils/resettable'; +import { getElSelector } from '../Products.svelte'; +import { animate } from 'motion'; + +type Task = { + title: string; + tags: string[]; + images?: string[]; +}; + +type User = { + name: string; + color: string; +}; + +type State = { + tasks: { + todo: Task[]; + doing: Task[]; + done: Task[]; + }; + users: User[]; +}; + +const state = createResettable({ + tasks: { + todo: [ + { + title: 'Edit images for website', + tags: ['design', 'content'], + images: ['./images/animations/storage-2.png', './images/animations/storage-3.png'] + } + ], + doing: [ + { + title: 'Handoff meet', + tags: ['design', 'dev'] + } + ], + done: [] + }, + users: [] +}); + +export const connectionsProg = createResettable(0); + +const addUser = (update: typeof state.update, user: User) => { + update((p) => ({ + ...p, + users: [...p.users, user] + })); +}; + +const addTask = (update: typeof state.update, group: keyof State['tasks'], task: Task) => { + update((p) => ({ + ...p, + tasks: { + ...p.tasks, + [group]: [task, ...p.tasks[group]] + } + })); +}; + +const execute = async () => { + const phone = getElSelector('phone'); + const code = getElSelector('code'); + + const walter = getElSelector('user-Walter'); + const aditya = getElSelector('user-Aditya'); + const sara = getElSelector('user-Sara'); + + const addTodo = getElSelector('add-todo'); + const addDoing = getElSelector('add-doing'); + const addDone = getElSelector('add-done'); + + const graphBox = getElSelector('graph-box'); + + const pd = getElSelector('pd'); + + const { update } = state.reset(); + const { set: setConn } = connectionsProg.reset(); + + await Promise.all([ + safeAnimate(phone, { x: 0, y: 0, width: '660px' }, { duration: 0.5 })?.finished, + safeAnimate(code, { opacity: 0 }, { duration: 0.5 })?.finished, + safeAnimate(graphBox, { opacity: 0, x: 0, y: 0, visibility: 'visible' }, { duration: 0 }) + ?.finished, + safeAnimate(pd, { opacity: 1, y: 0 }, { duration: 0.5 })?.finished + ]); + + // Graphbox + sleep(1250).then(async () => { + await safeAnimate(graphBox, { opacity: 1 }, { duration: 0.5 })?.finished; + + animate( + (y) => { + setConn(y); + }, + { duration: 2.5, easing: 'ease-in' } + ); + }); + + // Walter + sleep(500).then(async () => { + addUser(update, { name: 'Walter', color: '#fd366e' }); + await sleep(500); + await safeAnimate(walter, { x: -200, y: -100, scale: 1 }, { duration: 0.5 })?.finished; + await Promise.all([ + safeAnimate(walter, { scale: [1, 0.9, 1] }, { duration: 0.25 })?.finished, + safeAnimate(addTodo, { scale: [1, 0.9, 1] }, { duration: 0.25 })?.finished + ]); + + addTask(update, 'todo', { + title: 'Handoff meet', + tags: ['design', 'dev'] + }); + + await safeAnimate(walter, { scale: 1, x: -180, y: -160 }, { duration: 0.75, delay: 0.5 }) + ?.finished; + + await sleep(500); + + await safeAnimate(walter, { x: 210, y: -100, scale: 1 }, { duration: 0.5 })?.finished; + + await Promise.all([ + safeAnimate(walter, { scale: [1, 0.9, 1] }, { duration: 0.25 })?.finished, + safeAnimate(addDone, { scale: [1, 0.9, 1] }, { duration: 0.25 })?.finished + ]); + + addTask(update, 'done', { + title: 'Create migrations script', + tags: ['Dev'] + }); + + safeAnimate(walter, { scale: 1, x: 230, y: -20 }, { duration: 0.75, delay: 0.5 }); + + await sleep(750); + + await safeAnimate(walter, { x: -10, y: -100, scale: 1 }, { duration: 0.5 })?.finished; + + await Promise.all([ + safeAnimate(walter, { scale: [1, 0.9, 1] }, { duration: 0.25 })?.finished, + safeAnimate(addDoing, { scale: [1, 0.9, 1] }, { duration: 0.25 })?.finished + ]); + + addTask(update, 'doing', { + title: 'Configure blog SEO', + tags: ['dev', 'content'] + }); + + await safeAnimate(walter, { scale: 1, x: -70, y: 80 }, { duration: 0.75, delay: 0.25 }); + }); + + // Aditya + sleep(1500).then(async () => { + addUser(update, { name: 'Aditya', color: 'rgba(124, 103, 254, 1)' }); + await sleep(500); + await safeAnimate(aditya, { x: 200, y: -100, scale: 1 }, { duration: 0.5 })?.finished; + await Promise.all([ + safeAnimate(aditya, { scale: [1, 0.9, 1] }, { duration: 0.25 })?.finished, + safeAnimate(addDone, { scale: [1, 0.9, 1] }, { duration: 0.25 })?.finished + ]); + + addTask(update, 'done', { + title: 'Write up briefing', + tags: ['dev-rel'] + }); + + await safeAnimate(aditya, { scale: 1, x: 180, y: 60 }, { duration: 0.75, delay: 0.5 }) + ?.finished; + + await sleep(750); + + await safeAnimate(aditya, { x: -210, y: -100, scale: 1 }, { duration: 0.5 })?.finished; + + await Promise.all([ + safeAnimate(aditya, { scale: [1, 0.9, 1] }, { duration: 0.25 })?.finished, + safeAnimate(addTodo, { scale: [1, 0.9, 1] }, { duration: 0.25 })?.finished + ]); + + addTask(update, 'todo', { + title: 'Review branding blog post', + tags: ['dev-rel'] + }); + + await safeAnimate(aditya, { scale: 1, x: 70, y: -220 }, { duration: 0.75, delay: 0.5 }) + ?.finished; + }); + + // Sara + sleep(2500).then(async () => { + addUser(update, { name: 'Sara', color: 'rgba(103, 163, 254, 1)' }); + await sleep(500); + await safeAnimate(sara, { x: 0, y: -100, scale: 1 }, { duration: 0.5 })?.finished; + await Promise.all([ + safeAnimate(sara, { scale: [1, 0.9, 1] }, { duration: 0.25 })?.finished, + safeAnimate(addDoing, { scale: [1, 0.9, 1] }, { duration: 0.25 })?.finished + ]); + + addTask(update, 'doing', { + title: 'Prepare design system presentation', + tags: ['design'] + }); + + await safeAnimate(sara, { scale: 1, y: 60, x: -50 }, { duration: 0.75, delay: 0.5 })?.finished; + await sleep(250); + + await safeAnimate(sara, { x: 200, y: -100, scale: 1 }, { duration: 0.5 })?.finished; + + await Promise.all([ + safeAnimate(sara, { scale: [1, 0.9, 1] }, { duration: 0.25 })?.finished, + safeAnimate(addDone, { scale: [1, 0.9, 1] }, { duration: 0.25 })?.finished + ]); + + addTask(update, 'done', { + title: 'QA branding animations', + tags: ['Dev'] + }); + + await safeAnimate(sara, { scale: 1, x: 180, y: 60 }, { duration: 0.75, delay: 0.5 })?.finished; + }); +}; + +export const realtimeController = { + execute, + state +}; + +export const Realtime = { + Phone +}; diff --git a/src/lib/animations/Products/realtime/phone.svelte b/src/lib/animations/Products/realtime/phone.svelte new file mode 100644 index 0000000000..4fefa0398a --- /dev/null +++ b/src/lib/animations/Products/realtime/phone.svelte @@ -0,0 +1,647 @@ + + +
+
+
+
+

My Team's tasks

+
+
+ {#each $state.users as user} +
+ {getInitial(user.name)} +
+ {/each} +
+
+ +
+
+
+ +
+ + +
+
+
+ +
+ +
+ {#each objectKeys($state.tasks) as col, i} + {@const tasks = $state.tasks[col]} + {@const isLast = i === objectKeys($state.tasks).length - 1} +
+
+ {col} + {tasks.length} + +
+
+ + {#each tasks as task (task.title)} +
+ {#if task.images} +
    + {#each task.images as image} + + {/each} +
+ {/if} +

{task.title}

+
    + {#each task.tags as tag} +
  • {tag}
  • + {/each} +
+
+ {/each} +
+
+ {#if !isLast} +
+ {/if} + {/each} +
+ + {#each $state.users as user} +
+ + + +

{user.name}

+
+ {/each} +
+ +
+

{formatNumber(connections)}

+

Realtime Connections

+ + + + + + + + + + + + + + + + + + + + + {#each progressedLines as line, i} + {@const x = 57 + i * 24} + {@const y = 124 - line} + {#if line > 3} + + + {/if} + {/each} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + diff --git a/src/lib/animations/Products/storage/box.svelte b/src/lib/animations/Products/storage/box.svelte new file mode 100644 index 0000000000..69855d1f06 --- /dev/null +++ b/src/lib/animations/Products/storage/box.svelte @@ -0,0 +1,39 @@ + + +
+
+ Filename + Type + Size +
+ {#each $state.files as file (file.src)} +
+
+ + {file.filename} +
+ {file.type} + {file.size} +
+ {/each} +
+ + diff --git a/src/lib/animations/Products/storage/code.svelte b/src/lib/animations/Products/storage/code.svelte new file mode 100644 index 0000000000..e01ca0a178 --- /dev/null +++ b/src/lib/animations/Products/storage/code.svelte @@ -0,0 +1,12 @@ + + + diff --git a/src/lib/animations/Products/storage/index.ts b/src/lib/animations/Products/storage/index.ts new file mode 100644 index 0000000000..28c13e9697 --- /dev/null +++ b/src/lib/animations/Products/storage/index.ts @@ -0,0 +1,136 @@ +import Box from './box.svelte'; +import Code from './code.svelte'; +import Phone from './phone.svelte'; + +import { safeAnimate, sleep } from '$lib/animations'; +import { createResettable } from '$lib/utils/resettable'; +import { getElSelector } from '../Products.svelte'; + +type File = { + src: string; + filename: string; + type: string; + size: string; +}; + +type State = { + files: File[]; +}; + +const state = createResettable({ + files: [] +}); + +const execute = async () => { + const phone = getElSelector('phone'); + const box = getElSelector('box'); + const code = getElSelector('code'); + const overlay = getElSelector('overlay'); + const drawer = getElSelector('drawer'); + const upload = getElSelector('upload'); + const uploadBtn = getElSelector('upload-btn'); + const uploadImg = getElSelector('upload-img'); + const uploadLoading = getElSelector('upload-loading'); + const uploadText = getElSelector('upload-text'); + + const { update } = state.reset(); + + await Promise.all([ + safeAnimate(phone, { x: 0, y: 0 }, { duration: 0.5 })?.finished, + safeAnimate(box, { opacity: 0 }, { duration: 0.5 })?.finished, + safeAnimate(code, { opacity: 0 }, { duration: 0.5 })?.finished, + safeAnimate(uploadLoading, { opacity: 0 }, { duration: 0 })?.finished + ]); + + await safeAnimate(code, { zIndex: 20 }, { duration: 0 })?.finished; + + update((p) => ({ + ...p, + files: [ + ...p.files, + { + src: '/images/animations/storage-1.png', + filename: 'Profile.png', + type: 'image/png', + size: '362.6 KB' + } + ] + })); + + await sleep(1000); + + await Promise.all([ + safeAnimate(overlay, { opacity: 1 }, { duration: 0.25 })?.finished, + safeAnimate(drawer, { y: [128, 0], opacity: 1 }, { duration: 0.5 })?.finished + ]); + + await sleep(1000); + + await safeAnimate(uploadBtn, { scale: [1, 0.9, 1] }, { duration: 0.25 })?.finished; + + await safeAnimate(code, { x: 300, y: 32 }, { duration: 0 })?.finished; + + await Promise.all([ + safeAnimate(code, { y: [32 - 16, 32], opacity: 1 }, { duration: 0.5 })?.finished, + safeAnimate(upload, { y: [-16, 0], opacity: 1 }, { duration: 0.5 })?.finished + ]); + + await sleep(500); + + await safeAnimate(box, { x: 300, y: 300 }, { duration: 0 })?.finished; + + await Promise.all([ + safeAnimate(uploadImg, { x: [64, 48], y: [80, 64], opacity: 1 }, { duration: 0.5 })?.finished, + safeAnimate(box, { y: [300 - 16, 300], opacity: 1 }, { duration: 1 })?.finished + ]); + + await sleep(500); + + await Promise.all([ + safeAnimate(uploadText, { opacity: 0 }, { duration: 0.5 })?.finished, + safeAnimate(uploadLoading, { opacity: 1 }, { duration: 0.5 })?.finished, + safeAnimate(uploadImg, { opacity: 0, y: 64 + 8 }, { duration: 0.5 })?.finished + ]); + await sleep(500); + + await safeAnimate(upload, { opacity: 0, y: 48 }, { duration: 0.5 })?.finished; + + update((p) => ({ + ...p, + files: [ + ...p.files, + { + src: '/images/animations/storage-2.png', + filename: 'Vector.svg', + type: 'vector/svg', + size: '1.5 KB' + } + ] + })); + + await sleep(1000); + + update((p) => ({ + ...p, + files: [ + ...p.files, + { + src: '/images/animations/storage-3.png', + filename: 'img2.webp', + type: 'image/webp', + size: '3.2 MB' + } + ] + })); +}; + +export const storageController = { + execute, + state +}; + +export const Storage = { + Phone, + Box, + Code +}; diff --git a/src/lib/animations/Products/storage/phone.svelte b/src/lib/animations/Products/storage/phone.svelte new file mode 100644 index 0000000000..5d74c28fed --- /dev/null +++ b/src/lib/animations/Products/storage/phone.svelte @@ -0,0 +1,284 @@ + + +
+
+

Your tasks

+ +
+ +
Today
+
+ {#each fixedTasks as task (task.id)} +
+ + {task.title} +
+ {/each} +
+ + + +
+
+

Edit images for website

+

Edit the attached images to use in the website

+ +
Upload media...
+
+ {#each $state.files.slice(1) as file} + + {/each} +
+
+
+
+
+

Upload media

+
+ Drop media here +
+
+
+
+ +
+ + diff --git a/src/lib/animations/index.ts b/src/lib/animations/index.ts index a97cfd2001..0ec36716fd 100644 --- a/src/lib/animations/index.ts +++ b/src/lib/animations/index.ts @@ -3,7 +3,8 @@ import { animate as motionAnimate, type ElementOrSelector, type MotionKeyframesDefinition, - type AnimationOptionsWithOverrides + type AnimationOptionsWithOverrides, + animate } from 'motion'; export function animation( @@ -34,6 +35,18 @@ export function animation( export type Animation = ReturnType; +export const safeAnimate = ( + elementOrSelector: ElementOrSelector, + keyframes: MotionKeyframesDefinition, + options?: AnimationOptionsWithOverrides +) => { + try { + return animate(elementOrSelector, keyframes, options); + } catch { + // do nothing lol + } +}; + type Unsubscriber = () => void; type PreviousScroll = 'before' | 'after' | undefined; @@ -131,6 +144,9 @@ export const scroll: Action< ); }; + handleScroll(); + handleResize(); + window.addEventListener('scroll', handleScroll); window.addEventListener('resize', handleResize); @@ -141,3 +157,91 @@ export const scroll: Action< } }; }; + +type TimelineEvent = { + at: number; + callback: () => void; +}; + +export function createTimeline(events: TimelineEvent[]) { + let timeoutIds: NodeJS.Timeout[] = []; + + const play = () => { + events.forEach((event) => { + const timeoutId = setTimeout(event.callback, event.at); + timeoutIds.push(timeoutId); + }); + }; + + const cancel = () => { + timeoutIds.forEach(clearTimeout); + timeoutIds = []; + }; + + return { play, cancel }; +} + +type ProgressEvent = { + percentage: number; + callback: () => void; +}; + +/** + * Given a list of events, create a sequence of events that will be executed + * when a given percentage is greater than the event percentage, and before + * the next event percentage. + * e.g. const handler = createProgressSequence(events) // where there's an event for each 0.1 percentage + * handler(0.45) // will execute the event with percentage 0.4. + */ +export function createProgressSequence(events: ProgressEvent[]) { + // Sort from highest to lowest percentage + const sortedEvents = [...events].sort((a, b) => b.percentage - a.percentage); + + let lastEventIdx = -1; + + const handler = (percentage: number) => { + const idx = sortedEvents.findIndex((event) => event.percentage <= percentage); + if (idx === lastEventIdx) { + return; + } + const event = sortedEvents[idx]; + event?.callback(); + lastEventIdx = idx; + }; + + handler.resetLastEventIdx = () => { + lastEventIdx = -1; + }; + + return handler; +} + +export type ProgressSequence = ReturnType; + +export function write(text: string, cb: (v: string) => void, duration = 500) { + const step = duration / text.length; + let i = 0; + return new Promise((resolve) => { + const interval = setInterval(() => { + cb(text.slice(0, ++i)); + if (i === text.length) { + clearInterval(interval); + resolve(undefined); + } + }, step); + }); +} + +export function sleep(duration: number) { + return new Promise((resolve) => { + setTimeout(resolve, duration); + }); +} + +export function getInitials(name: string) { + return name + .split(' ') + .map((word) => word?.[0]?.toUpperCase() ?? '') + .join('') + .slice(0, 2); +} diff --git a/src/lib/animations/scroll-indicator.svelte b/src/lib/animations/scroll-indicator.svelte index 0f286b4674..5791b9d6f2 100644 --- a/src/lib/animations/scroll-indicator.svelte +++ b/src/lib/animations/scroll-indicator.svelte @@ -1,7 +1,6 @@ - -
-
- -
-
- - diff --git a/src/lib/components/Spline.svelte b/src/lib/components/Spline.svelte new file mode 100644 index 0000000000..2e8d7c26ef --- /dev/null +++ b/src/lib/components/Spline.svelte @@ -0,0 +1,52 @@ + + + diff --git a/src/lib/components/Switch.svelte b/src/lib/components/Switch.svelte new file mode 100644 index 0000000000..c19ed4f68f --- /dev/null +++ b/src/lib/components/Switch.svelte @@ -0,0 +1,68 @@ + + +
+ +
+ + diff --git a/src/lib/components/index.ts b/src/lib/components/index.ts index 6d13e00cee..b0477c4aa2 100644 --- a/src/lib/components/index.ts +++ b/src/lib/components/index.ts @@ -2,7 +2,8 @@ export { default as FooterNav } from './FooterNav.svelte'; export { default as MainFooter } from './MainFooter.svelte'; export { default as PreFooter } from './PreFooter.svelte'; export { default as MobileNav } from './MobileNav.svelte'; -export { default as Phone } from './Phone.svelte'; + +export { default as Switch } from './Switch.svelte'; export { default as Newsletter } from './Newsletter.svelte'; export { default as Tooltip } from './Tooltip.svelte'; -export { default as Article } from './Article.svelte'; +export {default as Spline} from './Spline.svelte'; diff --git a/src/lib/layouts/Docs.svelte b/src/lib/layouts/Docs.svelte index 0c421cf4d1..e150c66f2d 100644 --- a/src/lib/layouts/Docs.svelte +++ b/src/lib/layouts/Docs.svelte @@ -29,7 +29,7 @@ export let variant: DocsLayoutVariant = 'default'; const variantClasses: Record = { - default: 'aw-grid-side-nav aw-container', + default: 'aw-grid-side-nav aw-container u-padding-inline-0', expanded: 'aw-grid-huge-navs', 'two-side-navs': 'aw-grid-two-side-navs' }; diff --git a/src/lib/layouts/Main.svelte b/src/lib/layouts/Main.svelte index 0b539ffdc2..b92a0192a1 100644 --- a/src/lib/layouts/Main.svelte +++ b/src/lib/layouts/Main.svelte @@ -9,6 +9,7 @@ import { browser } from '$app/environment'; import { MobileNav } from '$lib/components'; import { isVisible } from '$lib/utils/isVisible'; + import { createScrollInfo } from '$lib/utils/scroll'; import { addEventListener } from '@melt-ui/svelte/internal/helpers'; import { onMount } from 'svelte'; @@ -45,11 +46,12 @@ function getVisibleTheme() { const themes = Array.from(document.querySelectorAll('.theme-dark, .theme-light')).filter( (element) => { - const { classList } = element; + const { classList, dataset } = element as HTMLElement; if ( classList.contains('aw-mobile-header') || classList.contains('aw-main-header') || - element === document.body + element === document.body || + typeof dataset['themeIgnore'] === 'string' ) { return false; } @@ -96,12 +98,26 @@ ]; $: resolvedTheme = isMobileNavOpen ? 'dark' : theme; + + const scrollInfo = createScrollInfo(); + + $: isHeaderHidden = (() => { + if ($scrollInfo.top < 250) { + return false; + } + if ($scrollInfo.direction === 'down') { + return true; + } + + return $scrollInfo.deltaDirChange < 200; + })(); +
diff --git a/src/lib/utils/chain.ts b/src/lib/utils/chain.ts new file mode 100644 index 0000000000..3bd81da47e --- /dev/null +++ b/src/lib/utils/chain.ts @@ -0,0 +1,152 @@ +/* eslint-disable @typescript-eslint/ban-types */ +type Cancel = () => void; +type Promised = T extends Promise ? U : T; + +type Args = { + returned: Promised; + cancel: Cancel; +}; + +export type Chain = { + execute: () => Promise; + cancel: Cancel; +}; + +interface ChainFn { + (fn1: (args: Args) => A): Chain; + (fn1: (args: Args) => A, fn2: (args: Args) => B): Chain; + ( + fn1: (args: Args) => A, + fn2: (args: Args) => B, + fn3: (args: Args) => C + ): Chain; + ( + fn1: (args: Args) => A, + fn2: (args: Args) => B, + fn3: (args: Args) => C, + fn4: (args: Args) => D + ): Chain; + ( + fn1: (args: Args) => A, + fn2: (args: Args) => B, + fn3: (args: Args) => C, + fn4: (args: Args) => D, + fn5: (args: Args) => E + ): Chain; + ( + fn1: (args: Args) => A, + fn2: (args: Args) => B, + fn3: (args: Args) => C, + fn4: (args: Args) => D, + fn5: (args: Args) => E, + fn6: (args: Args) => F + ): Chain; + ( + fn1: (args: Args) => A, + fn2: (args: Args) => B, + fn3: (args: Args) => C, + fn4: (args: Args) => D, + fn5: (args: Args) => E, + fn6: (args: Args) => F, + fn7: (args: Args) => G + ): Chain; + ( + fn1: (args: Args) => A, + fn2: (args: Args) => B, + fn3: (args: Args) => C, + fn4: (args: Args) => D, + fn5: (args: Args) => E, + fn6: (args: Args) => F, + fn7: (args: Args) => G, + fn8: (args: Args) => H + ): Chain; + ( + fn1: (args: Args) => A, + fn2: (args: Args) => B, + fn3: (args: Args) => C, + fn4: (args: Args) => D, + fn5: (args: Args) => E, + fn6: (args: Args) => F, + fn7: (args: Args) => G, + fn8: (args: Args) => H, + fn9: (args: Args) => I + ): Chain; + ( + fn1: (args: Args) => A, + fn2: (args: Args) => B, + fn3: (args: Args) => C, + fn4: (args: Args) => D, + fn5: (args: Args) => E, + fn6: (args: Args) => F, + fn7: (args: Args) => G, + fn8: (args: Args) => H, + fn9: (args: Args) => I, + fn10: (args: Args) => J + ): Chain; + ( + fn1: (args: Args) => A, + fn2: (args: Args) => B, + fn3: (args: Args) => C, + fn4: (args: Args) => D, + fn5: (args: Args) => E, + fn6: (args: Args) => F, + fn7: (args: Args) => G, + fn8: (args: Args) => H, + fn9: (args: Args) => I, + fn10: (args: Args) => J, + fn11: (args: Args) => K + ): Chain; + ( + fn1: (args: Args) => A, + fn2: (args: Args) => B, + fn3: (args: Args) => C, + fn4: (args: Args) => D, + fn5: (args: Args) => E, + fn6: (args: Args) => F, + fn7: (args: Args) => G, + fn8: (args: Args) => H, + fn9: (args: Args) => I, + fn10: (args: Args) => J, + fn11: (args: Args) => K, + fn12: (args: Args) => L + ): Chain; + // So on... +} + +/** + * Method that accepts an array of async callbacks. + * It returns an execute and cancel method. + * The execute method will execute the callbacks in order. + * The cancel method will cancel the execution of the remaining callbacks. + */ +export const chain: ChainFn = (...fns: Function[]) => { + const cancelled = {} as Record; + + const cancel = () => { + Object.keys(cancelled).forEach((key) => (cancelled[key] = true)); + }; + + let lastRes: any = undefined; + + const execute = async () => { + const executionId = stupidId(); + cancelled[executionId] = false; + + for (let i = 0; i < fns.length; i++) { + const fn = fns[i]; + if (cancelled[executionId]) { + delete cancelled[executionId]; + return; + } + + lastRes = await fn({ returned: lastRes, cancel }); + } + + delete cancelled[executionId]; + }; + + return { execute, cancel }; +}; + +// Stupid way of generating unique id +const stupidId = () => Math.random().toString(36).substr(2, 9); diff --git a/src/lib/utils/code.ts b/src/lib/utils/code.ts index 083e6802e6..1e575cf3ce 100644 --- a/src/lib/utils/code.ts +++ b/src/lib/utils/code.ts @@ -1,36 +1,20 @@ import type { LanguageFn } from 'highlight.js'; import hljs from 'highlight.js/lib/core'; import dart from 'highlight.js/lib/languages/dart'; +import diff from 'highlight.js/lib/languages/diff'; import javascript from 'highlight.js/lib/languages/javascript'; -import typescript from 'highlight.js/lib/languages/typescript'; -import xml from 'highlight.js/lib/languages/xml'; -import shell from 'highlight.js/lib/languages/shell'; -import markdown from 'highlight.js/lib/languages/markdown'; import json from 'highlight.js/lib/languages/json'; -import swift from 'highlight.js/lib/languages/swift'; +import markdown from 'highlight.js/lib/languages/markdown'; import php from 'highlight.js/lib/languages/php'; -import python from 'highlight.js/lib/languages/python'; -import diff from 'highlight.js/lib/languages/diff'; -import ruby from 'highlight.js/lib/languages/ruby'; -import csharp from 'highlight.js/lib/languages/csharp'; -import kotlin from 'highlight.js/lib/languages/kotlin'; -import java from 'highlight.js/lib/languages/java'; -import cpp from 'highlight.js/lib/languages/cpp'; -import bash from 'highlight.js/lib/languages/bash'; -import powershell from 'highlight.js/lib/languages/powershell'; -import dos from 'highlight.js/lib/languages/dos'; -import yaml from 'highlight.js/lib/languages/yaml'; -import plaintext from 'highlight.js/lib/languages/plaintext'; -import graphql from 'highlight.js/lib/languages/graphql'; -import http from 'highlight.js/lib/languages/http'; -import css from 'highlight.js/lib/languages/css'; -import { Platform } from './references'; +import shell from 'highlight.js/lib/languages/shell'; +import swift from 'highlight.js/lib/languages/swift'; +import typescript from 'highlight.js/lib/languages/typescript'; +import xml from 'highlight.js/lib/languages/xml'; const languages = { js: javascript, dart: dart, ts: typescript, - deno: typescript, xml: xml, html: xml, sh: shell, @@ -38,72 +22,26 @@ const languages = { json: json, swift: swift, php: php, - diff: diff, - python: python, - ruby: ruby, - csharp: csharp, - kotlin: kotlin, - java: java, - cpp: cpp, - bash: bash, - powershell: powershell, - cmd: dos, - yaml: yaml, - text: plaintext, - graphql: graphql, - http: http, - py: python, - rb: ruby, - cs: csharp, - css: css, + diff: diff } as const satisfies Record; +export type Language = keyof typeof languages; -const platformAliases: Record = { - [Platform.ClientWeb]: 'js', - [Platform.ClientFlutter]: 'dart', - [Platform.ClientAndroidJava]: 'java', - [Platform.ClientAndroidKotlin]: 'kotlin', - [Platform.ClientApple]: 'swift', - [Platform.ClientGraphql]: 'graphql', - [Platform.ClientRest]: 'http', - [Platform.ServerDart]: 'dart', - [Platform.ServerDeno]: 'ts', - [Platform.ServerDotNet]: 'cs', - [Platform.ServerNodeJs]: 'js', - [Platform.ServerPhp]: 'php', - [Platform.ServerPython]: 'py', - [Platform.ServerRuby]: 'rb', - [Platform.ServerSwift]: 'swift' -}; - -Object.entries(languages).forEach(([key, value]) => { - hljs.registerLanguage(key, value); -}); - -Object.entries(platformAliases).forEach(([key, value]) => { - hljs.registerAliases(key, { - languageName: value +const registerLanguages = () => { + Object.entries(languages).forEach(([key, value]) => { + hljs.registerLanguage(key, value); }); -}); - -export type Language = keyof typeof languages | Platform; +}; type Args = { content: string; language?: Language; - withLineNumbers?: boolean; }; export const getCodeHtml = (args: Args) => { - const { content, language, withLineNumbers } = args; + registerLanguages(); + + const { content, language } = args; const res = hljs.highlight(content, { language: language ?? 'sh' }).value; - const lines = res.split(/\n/g).slice(0, -1); - const final = lines.reduce((carry, line) => { - carry += `${line}\n`; - return carry; - }, ''); - return `
${final}
`; + return `
${res}
`; }; diff --git a/src/lib/utils/flip.ts b/src/lib/utils/flip.ts new file mode 100644 index 0000000000..71791dc0b9 --- /dev/null +++ b/src/lib/utils/flip.ts @@ -0,0 +1,59 @@ +import type { AnimationConfig, FlipParams } from 'svelte/animate'; +import { cubicOut } from 'svelte/easing'; + +// eslint-disable-next-line @typescript-eslint/ban-types +export function is_function(thing: unknown): thing is Function { + return typeof thing === 'function'; +} + +type Params = FlipParams & { + scale?: boolean; +}; + +/** + * The flip function calculates the start and end position of an element and animates between them, translating the x and y values. + * `flip` stands for [First, Last, Invert, Play](https://aerotwist.com/blog/flip-your-animations/). + * + * https://svelte.dev/docs/svelte-animate#flip + */ +export function flip( + node: HTMLElement, + { from, to }: { from: DOMRect; to: DOMRect }, + params: Params = {} +): AnimationConfig { + const style = getComputedStyle(node); + const transform = style.transform === 'none' ? '' : style.transform; + const [ox, oy] = style.transformOrigin.split(' ').map(parseFloat); + const dx = from.left + (from.width * ox) / to.width - (to.left + ox); + const dy = from.top + (from.height * oy) / to.height - (to.top + oy); + + const { + delay = 0, + duration = (d) => Math.sqrt(d) * 120, + easing = cubicOut, + scale = true + } = params; + return { + delay, + duration: is_function(duration) ? duration(Math.sqrt(dx * dx + dy * dy)) : duration, + easing, + css: (t, u) => { + const x = u * dx; + const y = u * dy; + const sx = scale ? t + (u * from.width) / to.width : 1; + const sy = scale ? t + (u * from.height) / to.height : 1; + return `transform: ${transform} translate(${x}px, ${y}px) scale(${sx}, ${sy}); + + `; + }, + tick(t, u) { + const sx = scale ? t + (u * from.width) / to.width : 1; + const sy = scale ? t + (u * from.height) / to.height : 1; + const inverse_sx = scale ? 1 / sx : 1; + const inverse_sy = scale ? 1 / sy : 1; + + node.style.setProperty('--inverse-sx', inverse_sx.toString()); + node.style.setProperty('--inverse-sy', inverse_sy.toString()); + } + }; +} diff --git a/src/lib/utils/object.ts b/src/lib/utils/object.ts new file mode 100644 index 0000000000..3da9c2f8c6 --- /dev/null +++ b/src/lib/utils/object.ts @@ -0,0 +1,3 @@ +export function objectKeys(obj: T): Array { + return Object.keys(obj) as Array; +} diff --git a/src/lib/utils/resettable.ts b/src/lib/utils/resettable.ts new file mode 100644 index 0000000000..138db43f5c --- /dev/null +++ b/src/lib/utils/resettable.ts @@ -0,0 +1,58 @@ +const braindeadUUID = () => { + return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); +}; + +const deepClone = (v: any) => { + return JSON.parse(JSON.stringify(v)); +}; + +export const createResettable = (defaultValue: Value) => { + type GlobalState = Record; + type SubscribeCallback = (v: Value) => void; + let subscribeCallbacks: SubscribeCallback[] = []; + + const d = deepClone(defaultValue); + + let currUuid = braindeadUUID(); + const state: GlobalState = { + [currUuid]: deepClone(d) + }; + + const subscribe = (cb: SubscribeCallback) => { + subscribeCallbacks.push(cb); + cb(state[currUuid]); + + return () => { + subscribeCallbacks = subscribeCallbacks.filter((c) => c !== cb); + }; + }; + + const reset = () => { + currUuid = braindeadUUID(); + const fixedId = currUuid; + const set = (v: Value) => { + state[fixedId] = v; + subscribeCallbacks.forEach((cb) => cb(state[currUuid])); + }; + + const update = (fn: (v: Value) => Value) => { + set(fn(state[fixedId])); + }; + + set(deepClone(d)); + return { set, update }; + }; + + return { + subscribe, + reset, + set: (v: Value) => { + state[currUuid] = v; + subscribeCallbacks.forEach((cb) => cb(state[currUuid])); + }, + update: (fn: (v: Value) => Value) => { + state[currUuid] = fn(state[currUuid]); + subscribeCallbacks.forEach((cb) => cb(state[currUuid])); + } + }; +}; diff --git a/src/lib/utils/scroll.ts b/src/lib/utils/scroll.ts new file mode 100644 index 0000000000..fa9d77bb33 --- /dev/null +++ b/src/lib/utils/scroll.ts @@ -0,0 +1,47 @@ +import { prev } from '@melt-ui/svelte/internal/helpers'; +import { onMount } from 'svelte'; +import { writable } from 'svelte/store'; + +type ScrollInfo = { + direction: 'up' | 'down'; + top: number; + /* the amount of pixels the user has scrolled since changing directions */ + deltaDirChange: number; +}; + +export const createScrollInfo = () => { + const scrollInfo = writable({ + direction: 'down', + top: 0, + deltaDirChange: 0 + }); + + let lastDirChange = 0; + + onMount(() => { + const handleScroll = () => { + scrollInfo.update((p) => { + const top = window.scrollY; + const direction = top > p.top ? 'down' : 'up'; + if (p.direction !== direction) { + lastDirChange = top; + } + const deltaDirChange = Math.abs(top - lastDirChange); + + return { + direction, + top, + deltaDirChange + }; + }); + }; + + window.addEventListener('scroll', handleScroll); + + return () => { + window.removeEventListener('scroll', handleScroll); + }; + }); + + return scrollInfo; +}; diff --git a/src/lib/utils/specs.ts b/src/lib/utils/specs.ts index f7308fe640..30e833345f 100644 --- a/src/lib/utils/specs.ts +++ b/src/lib/utils/specs.ts @@ -1,4 +1,3 @@ -import SwaggerParser from '@apidevtools/swagger-parser'; import { OpenAPIV3 } from 'openapi-types'; import { Platform, type Service } from './references'; @@ -17,13 +16,15 @@ type SDKMethod = { responses: Array<{ code: number; contentType?: string; - model?: { - id: string; - name: string; - }; + models?: SDKMethodModel[]; }>; }; +type SDKMethodModel = { + id: string; + name: string; +}; + type AppwriteOperationObject = OpenAPIV3.OperationObject & { 'x-appwrite': { method: string; @@ -41,7 +42,7 @@ type AppwriteOperationObject = OpenAPIV3.OperationObject & { }; }; -type AppwriteSchemaObject = OpenAPIV3.SchemaObject & { +export type AppwriteSchemaObject = OpenAPIV3.SchemaObject & { 'x-example': string; }; @@ -141,20 +142,24 @@ export function getSchema(id: string, api: OpenAPIV3.Document): OpenAPIV3.Schema throw new Error("Schema doesn't exist"); } -const specs = import.meta.glob('$appwrite/app/config/specs/open-api3*-(client|server).json'); +const specs = import.meta.glob( + '$appwrite/app/config/specs/open-api3*-(client|server|console).json', + { + as: 'raw' + } +); async function getSpec(version: string, platform: string) { + const isClient = platform.startsWith('client-'); const isServer = platform.startsWith('server-'); const target = `/node_modules/@appwrite.io/repo/app/config/specs/open-api3-${version}-${ - isServer ? 'server' : 'client' + isServer ? 'server' : isClient ? 'client' : 'console' }.json`; return specs[target](); } export async function getApi(version: string, platform: string): Promise { - const spec = await getSpec(version, platform); - const parser = new SwaggerParser(); - const api = (await parser.bundle(spec as unknown as OpenAPIV3.Document)) as OpenAPIV3.Document; - + const raw = await getSpec(version, platform); + const api = JSON.parse(raw); return api; } @@ -198,28 +203,41 @@ export async function getService( const responses: SDKMethod['responses'] = Object.entries(operation.responses ?? {}).map( (tuple) => { const [code, response] = tuple as [string, OpenAPIV3.ResponseObject]; - const id = ( - response?.content?.['application/json']?.schema as OpenAPIV3.ReferenceObject - )?.$ref - ?.split('/') - .pop(); - const schema = id ? getSchema(id, api) : undefined; + const models: SDKMethodModel[] = []; + const schemas = response?.content?.['application/json']?.schema as OpenAPIV3.SchemaObject; + if (code !== '204') { + if (schemas?.oneOf) { + schemas.oneOf.forEach((ref) => { + const schema = resolveReference(ref as OpenAPIV3.ReferenceObject, api); + models.push({ + id: getIdFromReference(ref as OpenAPIV3.ReferenceObject), + name: schema.description ?? '' + }); + }); + } else { + if (schemas) { + const id = getIdFromReference(schemas as OpenAPIV3.ReferenceObject); + const schema = resolveReference(schemas as OpenAPIV3.ReferenceObject, api); + models.push({ + id, + name: schema?.description ?? '' + }); + } + } + } return { code: Number(code), contentType: response?.content ? Object.keys(response.content)[0] : undefined, - model: id - ? { - id, - name: schema?.description ?? '' - } - : undefined + models }; } ); const path = isAndroid - ? `/node_modules/@appwrite.io/repo/docs/examples/${version}/client-android/${isAndroidJava ? 'java' : 'kotlin'}/${operation['x-appwrite'].demo}` + ? `/node_modules/@appwrite.io/repo/docs/examples/${version}/client-android/${ + isAndroidJava ? 'java' : 'kotlin' + }/${operation['x-appwrite'].demo}` : `/node_modules/@appwrite.io/repo/docs/examples/${version}/${platform}/examples/${operation['x-appwrite'].demo}`; if (!(path in examples)) { continue; @@ -236,3 +254,26 @@ export async function getService( return data; } + +export function getIdFromReference(reference: OpenAPIV3.ReferenceObject) { + const id = reference?.$ref?.split('/')?.pop(); + if (!id) { + throw new Error('Invalid reference'); + } + return id; +} + +export function resolveReference( + reference: OpenAPIV3.ReferenceObject, + api: OpenAPIV3.Document +): AppwriteSchemaObject { + const id = reference.$ref.split('/').pop(); + if (!id) { + throw new Error('Invalid reference'); + } + const schema = api.components?.schemas?.[id] as AppwriteSchemaObject; + if (schema) { + return schema; + } + throw new Error("Schema doesn't exist"); +} diff --git a/src/markdoc/layouts/Article.svelte b/src/markdoc/layouts/Article.svelte index fcebf66c00..3a84dce191 100644 --- a/src/markdoc/layouts/Article.svelte +++ b/src/markdoc/layouts/Article.svelte @@ -21,8 +21,8 @@ export let title: string; export let description: string; - export let difficulty: string; - export let readtime: string; + export let difficulty: string = ''; + export let readtime: string = ''; setContext('headings', writable({})); diff --git a/src/markdoc/layouts/Tutorial.svelte b/src/markdoc/layouts/Tutorial.svelte index 6eda2c2dc5..b402595de5 100644 --- a/src/markdoc/layouts/Tutorial.svelte +++ b/src/markdoc/layouts/Tutorial.svelte @@ -8,7 +8,7 @@ {#if insideMultiCode} {#if $selected === language} + {@html result} {/if} {:else} @@ -82,6 +80,7 @@
+ {@html result}
diff --git a/src/partials/account-vs-user.md b/src/partials/account-vs-user.md new file mode 100644 index 0000000000..638d806300 --- /dev/null +++ b/src/partials/account-vs-user.md @@ -0,0 +1,21 @@ + +{% info title="Account vs Users API" %} +Appwrite provides two APIs to manager user accounts. + +The Account API is the API you should use in your **client applications** like web, Flutter, mobile, and native apps. +Account API creates sessions, which represent an authenticated user and is attached to a user's [account](/docs/products/auth/account). +Sessions respect [permissions](/docs/advanced/platform/permissions), which means users can only access resources if they have been granted the correct permissions. + +You'll notice that the Account API doesn't allow you to view or make changes to other users. +This is by design and for **security reasons**. + +[Account API references](/docs/references/cloud/client-web/account) + +The Users API is a dedicated API for managing users from an admin's perspective. **Do not use the Users API on client applications**. +It should be used with backend or server-side applications with the [Server SDK](#). + +Users API uses API keys instead of sessions. +This means they're not resticted by permissions, but by the scopes granted to the API key used. + +[Users API references](/docs/references/cloud/server-nodejs/users) +{% /info %} \ No newline at end of file diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 1804869c0e..a2306a3695 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -9,6 +9,7 @@ import '@fontsource/inter/800.css'; import '@fontsource/inter/900.css'; import '$scss/index.scss'; + import '@appwrite.io/pink-icons'; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 0fef7c07c8..df79675f9f 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -6,7 +6,9 @@ import { Tabs } from '$lib/UI'; import PreFooter from '$lib/components/PreFooter.svelte'; import OpenSource from '$lib/animations/OpenSource.svelte'; - import Products from '$lib/animations/Products.svelte'; + import Products from '$lib/animations/Products/Products.svelte'; + import ProductsMobile from '$lib/animations/Products/ProductsMobile.svelte'; + import { Spline } from '$lib/components'; + + + + + + + + + + +``` +{% /tabsitem %} + +{% tabsitem #linux title="Linux" %} + +Add your app **name** and **package name**. +Your package name is generally the **name** in your [pubspec.yaml](https://github.com/appwrite/playground-for-flutter/blob/master/pubspec.yaml#L1) file. +If you cannot find the correct package name, run the application in Linux and make any request with proper exception handling. +You should get the application ID needed to add in the received error message. + +{% /tabsitem %} + +{% tabsitem #macos title="macOS" %} + +Add your app **name** and **Bundle ID**. You can find your **Bundle Identifier** in the **General** tab for your app's primary target in XCode. + +The Appwrite SDK uses `ASWebAuthenticationSession` on macOS 10.15+ to allow OAuth authentication. You have to change your macOS **Deployment Target** in XCode to be macOS >= 10.15 to be able to build your app for macOS. + +In order to capture the Appwrite OAuth 2 callback url, the following URL scheme needs to added to your `Info.plist`. + +```xml +CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + io.appwrite + CFBundleURLSchemes + + appwrite-callback-[PROJECT_ID] + + + +``` +{% /tabsitem %} + +{% tabsitem #windows title="Windows" %} + +For **Windows**, add your app *name* and *package name*. +Your package name is generally the **name** in your [pubspec.yaml](https://github.com/appwrite/playground-for-flutter/blob/master/pubspec.yaml#L1) file. +If you cannot find the correct package name, run the application in Windows, and make any request with proper exception handling. You should get the application ID needed to add in the received error message. +{% /tabsitem %} + +{% /tabs %} + +![Add a platform](/images/docs/databases/quick-start/add-platform.png) + +You can skip optional steps. + +{% /section %} +{% section #step-2 step=2 title="Create Flutter project" %} +Create a Flutter project. + +```sh +flutter create my_app && cd my_app +``` +{% /section %} + +{% section #step-3 step=3 title="Install Appwrite" %} +Install the Appwrite SDK for Flutter. + +```sh +flutter pub add appwrite +``` + +{% /section %} + +{% section #step-4 step=4 title="Import Appwrite" %} +Find your project's ID in the **Settings** page. + +![Settings page in Appwrite Console.](/images/docs/databases/quick-start/project-id.png) + +Create a new file `lib/appwrite.dart` and add the following code to it, replace `` with your project ID. + +```dart +import 'package:appwrite/appwrite.dart'; + +class Appwrite { + static final Appwrite instance = Appwrite._internal(); + + late final Client client; + late final Account account; + factory Appwrite._() { + return instance; + } + + Appwrite._internal() { + client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject(""); + account = Account(client); + } +} +``` +{% /section %} +{% section #step-5 step=5 title="Create a login page" %} +Add the following code to `src/App.jsx`. +import 'package:appwrite/appwrite.dart'; + +```dart +import 'package:flutter/material.dart'; +import 'package:appwrite/appwrite.dart'; +import 'package:appwrite/models.dart' as models; + +import 'package:my_app/appwrite.dart'; + +void main() { + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + appBar: AppBar(title: const Text('My App')), + body: Padding( + padding: const EdgeInsets.all(16.0), + child: MyForm(), + ), + ), + ); + } +} + +class MyForm extends StatefulWidget { + @override + MyFormState createState() { + return MyFormState(); + } +} + +class MyFormState extends State { + models.User? loggedInUser; + final TextEditingController emailController = TextEditingController(); + final TextEditingController passwordController = TextEditingController(); + final TextEditingController nameController = TextEditingController(); + + Future login(String email, String password) async { + await Appwrite.instance.account + .createEmailSession(email: email, password: password); + final user = await Appwrite.instance.account.get(); + setState(() { + loggedInUser = user; + }); + } + + Future register(String email, String password, String name) async { + await Appwrite.instance.account.create( + userId: ID.unique(), email: email, password: password, name: name); + await login(email, password); + } + + Future logout() async { + await Appwrite.instance.account.deleteSession(sessionId: 'current'); + setState(() { + loggedInUser = null; + }); + } + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(loggedInUser != null + ? 'Logged in as ${loggedInUser!.name}' + : 'Not logged in'), + SizedBox(height: 16.0), + TextField( + controller: emailController, + decoration: InputDecoration(labelText: 'Email'), + ), + SizedBox(height: 16.0), + TextField( + controller: passwordController, + decoration: InputDecoration(labelText: 'Password'), + obscureText: true, + ), + SizedBox(height: 16.0), + TextField( + controller: nameController, + decoration: InputDecoration(labelText: 'Name'), + ), + SizedBox(height: 16.0), + ElevatedButton( + onPressed: () { + login(emailController.text, passwordController.text); + }, + child: Text('Login'), + ), + ElevatedButton( + onPressed: () { + register(emailController.text, passwordController.text, + nameController.text); + }, + child: Text('Register'), + ), + ElevatedButton( + onPressed: () { + logout(); + }, + child: Text('Logout'), + ), + ], + ); + } +} +``` +{% /section %} + +{% section #step-6 step=6 title="Checkout what you've built" %} +Run your project with `flutter run` and select a browser, platform, or emulator to run your project. +{% /section %} \ No newline at end of file diff --git a/src/routes/docs/quick-starts/react/+page.markdoc b/src/routes/docs/quick-starts/react/+page.markdoc index cd35a56637..9859409d62 100644 --- a/src/routes/docs/quick-starts/react/+page.markdoc +++ b/src/routes/docs/quick-starts/react/+page.markdoc @@ -14,7 +14,7 @@ Head to the [Appwrite Console](https://cloud.appwrite.io/console). If this is your first time using Appwrite, create an accout and create your first project. -Then, under **Add a platform**, add a **Web app**. The **Hostname** should be localhost. +Then, under **Add a platform**, add a **Web app**. The **Hostname** should be `localhost`. ![Add a platform](/images/docs/databases/quick-start/add-platform.png) @@ -59,55 +59,64 @@ export { ID } from 'appwrite'; {% section #step-5 step=5 title="Create a login page" %} Add the following code to `src/App.jsx`. -```html - - - +export default App; ``` {% /section %} {% section #step-6 step=6 title="Checkout what you've built" %} -Run your project with `npm run dev` and open [http://localhost:3000](http://localhost:3000) in your browser. +Run your project with `npm run dev -- --open --port 3000` and open [http://localhost:3000](http://localhost:3000) in your browser. {% /section %} \ No newline at end of file diff --git a/src/routes/docs/quick-starts/sveltekit/+page.markdoc b/src/routes/docs/quick-starts/sveltekit/+page.markdoc index d767b33166..2208fab870 100644 --- a/src/routes/docs/quick-starts/sveltekit/+page.markdoc +++ b/src/routes/docs/quick-starts/sveltekit/+page.markdoc @@ -11,7 +11,7 @@ Head to the [Appwrite Console](https://cloud.appwrite.io/console). If this is your first time using Appwrite, create an accout and create your first project. -Then, under **Add a platform**, add a **Web app**. The **Hostname** should be localhost. +Then, under **Add a platform**, add a **Web app**. The **Hostname** should be `localhost`. ![Add a platform](/images/docs/databases/quick-start/add-platform.png) @@ -100,7 +100,7 @@ Create a new file `src/routes/index.svelte` and add the following code to it. {% /section %} {% section #step-6 step=6 title="Checkout what you've built" %} -Run your project with `npm run dev` and open [http://localhost:3000](http://localhost:3000) in your browser. +Run your project with `npm run dev -- --open --port 3000` and open [http://localhost:3000](http://localhost:3000) in your browser. {% /section %} diff --git a/src/routes/docs/quick-starts/vuejs/+page.markdoc b/src/routes/docs/quick-starts/vuejs/+page.markdoc index 39da5bfe12..5c8bf345c9 100644 --- a/src/routes/docs/quick-starts/vuejs/+page.markdoc +++ b/src/routes/docs/quick-starts/vuejs/+page.markdoc @@ -14,7 +14,7 @@ Head to the [Appwrite Console](https://cloud.appwrite.io/console). If this is your first time using Appwrite, create an accout and create your first project. -Then, under **Add a platform**, add a **Web app**. The **Hostname** should be localhost. +Then, under **Add a platform**, add a **Web app**. The **Hostname** should be `localhost`. ![Add a platform](/images/docs/databases/quick-start/add-platform.png) @@ -109,5 +109,5 @@ const logout = async () => { {% /section %} {% section #step-6 step=6 title="Checkout what you've built" %} -Run your project with `npm run dev` and open [http://localhost:3000](http://localhost:3000) in your browser. +Run your project with `npm run dev -- --open --port 3000` and open [http://localhost:3000](http://localhost:3000) in your browser. {% /section %} diff --git a/src/routes/docs/references/+page.svelte b/src/routes/docs/references/+page.svelte index b3a425249b..049f67759c 100644 --- a/src/routes/docs/references/+page.svelte +++ b/src/routes/docs/references/+page.svelte @@ -1 +1,5 @@ -placeholder \ No newline at end of file + + +placeholder diff --git a/src/routes/docs/references/+layout.svelte b/src/routes/docs/references/Layout.svelte similarity index 95% rename from src/routes/docs/references/+layout.svelte rename to src/routes/docs/references/Layout.svelte index 5bbfbe54c9..65bd07f068 100644 --- a/src/routes/docs/references/+layout.svelte +++ b/src/routes/docs/references/Layout.svelte @@ -4,7 +4,8 @@ import Sidebar, { type NavParent, type NavTree } from '$lib/layouts/Sidebar.svelte'; import { preferredPlatform, preferredVersion } from '$lib/utils/references'; - $: expandable = $page.url.pathname.startsWith('/docs/references/'); + export let expandable = false; + $: prefix = `/docs/references/${$preferredVersion ?? $page.params?.version ?? 'cloud'}/${ $preferredPlatform ?? $page.params?.platform ?? 'client-web' }`; diff --git a/src/routes/docs/references/[version]/[platform]/[service]/+layout.svelte b/src/routes/docs/references/[version]/[platform]/[service]/+layout.svelte new file mode 100644 index 0000000000..c72730eac7 --- /dev/null +++ b/src/routes/docs/references/[version]/[platform]/[service]/+layout.svelte @@ -0,0 +1,7 @@ + + + + + diff --git a/src/routes/docs/references/[version]/[platform]/[service]/+page.svelte b/src/routes/docs/references/[version]/[platform]/[service]/+page.svelte index ac5545dc85..6475e58ae0 100644 --- a/src/routes/docs/references/[version]/[platform]/[service]/+page.svelte +++ b/src/routes/docs/references/[version]/[platform]/[service]/+page.svelte @@ -181,19 +181,30 @@ diff --git a/src/routes/docs/references/[version]/models/[model]/+layout.svelte b/src/routes/docs/references/[version]/models/[model]/+layout.svelte new file mode 100644 index 0000000000..bd34eeff26 --- /dev/null +++ b/src/routes/docs/references/[version]/models/[model]/+layout.svelte @@ -0,0 +1,7 @@ + + + + + diff --git a/src/routes/docs/references/[version]/models/[model]/+page.server.ts b/src/routes/docs/references/[version]/models/[model]/+page.server.ts new file mode 100644 index 0000000000..a85a55f2ea --- /dev/null +++ b/src/routes/docs/references/[version]/models/[model]/+page.server.ts @@ -0,0 +1,88 @@ +import type { EntryGenerator, PageServerLoad } from './$types'; +import { + getApi, + getSchema, + getService, + type AppwriteSchemaObject, + getIdFromReference, + resolveReference +} from '$lib/utils/specs'; +import { Platform, Service, versions } from '$lib/utils/references'; +import { error } from '@sveltejs/kit'; +import type { OpenAPIV3 } from 'openapi-types'; + +// export const entries: EntryGenerator = () => { +// return ['cloud', ...(versions as string[])].flatMap((version) => { +// return platforms.flatMap((platform) => { +// return services.map((service) => { +// return { service, version, platform }; +// }); +// }); +// }); +// }; + +type Model = { + title: string; + properties: Array<{ + name: string; + type: string; + description: string; + example: string | boolean | number | object | Array; + items?: Array; + }>; +}; + +export const load: PageServerLoad = async ({ params }) => { + const version = params.version === 'cloud' ? '1.4.x' : params.version; + const api = await getApi(version, 'console-web'); + const schema = getSchema(params.model, api); + const props = Object.entries(schema.properties ?? {}); + const model: Model = { + title: schema.description as string, + properties: props.map(([name, data]) => { + const property = data as AppwriteSchemaObject; + switch (property.type) { + case 'array': { + const items = []; + const propItems = property.items as AppwriteSchemaObject; + if (Array.isArray(propItems.anyOf)) { + items.push( + ...propItems.anyOf.map((ref) => getIdFromReference(ref as OpenAPIV3.ReferenceObject)) + ); + } else { + // items.push(getIdFromReference(propItems as unknown as OpenAPIV3.ReferenceObject)); + } + return { + name, + type: property.type as string, + description: property.description as string, + example: '', + items: + (property.items as AppwriteSchemaObject)?.anyOf?.map((ref) => { + const item = getIdFromReference(ref as OpenAPIV3.ReferenceObject); + return item; + }) ?? [] + }; + } + + default: + return { + name, + type: property.type as string, + description: property.description as string, + example: property['x-example'] + }; + } + }) + }; + + const example = model.properties.reduce>((carry, property) => { + carry[property.name] = property.example; + + return carry; + }, {}); + return { + model, + example + }; +}; diff --git a/src/routes/docs/references/[version]/models/[model]/+page.svelte b/src/routes/docs/references/[version]/models/[model]/+page.svelte new file mode 100644 index 0000000000..607e1d4471 --- /dev/null +++ b/src/routes/docs/references/[version]/models/[model]/+page.svelte @@ -0,0 +1,38 @@ + + +
+
+ Properties + + + + + + + + + + {#each data.model.properties as property} + + + + + + {/each} + +
+ NAME + + TYPE + + DESCRIPTION +
{property.name}{property.type}{property.description}
+ Example + +
+
diff --git a/src/routes/docs/sdks/+page.markdoc b/src/routes/docs/sdks/+page.markdoc index 2a225437f6..298b39bf20 100644 --- a/src/routes/docs/sdks/+page.markdoc +++ b/src/routes/docs/sdks/+page.markdoc @@ -13,7 +13,7 @@ We're always working on improving and extending the current stack of available p Client libraries for integrating with Appwrite to build client-based applications and websites. Read one of the many [quick starts](/docs/quick-starts) guides for your framework of choice to start building your first application. {% table %} -*   {% width=80 %} +*   {% width=48 %} * Platform * GitHub Repository *   {% width=80 %} @@ -48,7 +48,7 @@ Client libraries for integrating with Appwrite to build client-based application Server libraries for integrating with Appwrite to build server side integrations or use inside your [Appwrite Functions](/docs/products/functions). Read one of the many [quick starts](/docs/quick-starts) guides for your language/runtime of choice to start building your first server integration. {% table %} -*   {% width=80 %} +*   {% width=48 %} * Platform * GitHub Repository *   {% width=80 %} diff --git a/src/routes/docs/tutorials/react/+layout.svelte b/src/routes/docs/tutorials/react/+layout.svelte new file mode 100644 index 0000000000..fb9fb3980f --- /dev/null +++ b/src/routes/docs/tutorials/react/+layout.svelte @@ -0,0 +1,10 @@ + + + diff --git a/src/routes/docs/tutorials/react/+layout.ts b/src/routes/docs/tutorials/react/+layout.ts new file mode 100644 index 0000000000..562b11506f --- /dev/null +++ b/src/routes/docs/tutorials/react/+layout.ts @@ -0,0 +1,11 @@ +import type { LayoutLoad } from './$types'; + +export const load: LayoutLoad = ({ url }) => { + const tutorials = import.meta.glob('./**/*.markdoc', { + eager: true + }); + return { + tutorials, + pathname: url.pathname + }; +}; diff --git a/src/routes/docs/tutorials/react/+page.ts b/src/routes/docs/tutorials/react/+page.ts new file mode 100644 index 0000000000..c026e98b75 --- /dev/null +++ b/src/routes/docs/tutorials/react/+page.ts @@ -0,0 +1,6 @@ +import { redirect } from '@sveltejs/kit'; +import type { PageLoad } from './$types'; + +export const load: PageLoad = async () => { + throw redirect(303, '/docs/tutorials/react/step-1'); +}; diff --git a/src/routes/docs/tutorials/react/step-1/+page.markdoc b/src/routes/docs/tutorials/react/step-1/+page.markdoc new file mode 100644 index 0000000000..3a46e1177d --- /dev/null +++ b/src/routes/docs/tutorials/react/step-1/+page.markdoc @@ -0,0 +1,31 @@ +--- +layout: tutorial +title: Introduction +description: This is the description used for SEO. +step: 1 +difficulty: easy +readtime: 10 +--- + +**Idea Tracker**: an app to track all the side project ideas that you'll start, but probably never finish. +In this tutorial, you will build Idea Tracker with Appwrite and React. + +[TODO: Image] + +You can follow along with a fresh repo or [clone the project on GitHub](#). + +## Concepts {% #concepts %} + +This tutorial will introduce the following concepts: + +1. Setting up your first project +2. Authentication +3. Databases and collections +4. Queries and pagination +5. Storage + + +## Prerequisites {% #prerequisites %} + +1. Basic knowledge of JavaScript and React. +2. Have [Node.js](#) and [NPM](#) installed on your computer \ No newline at end of file diff --git a/src/routes/docs/tutorials/react/step-2/+page.markdoc b/src/routes/docs/tutorials/react/step-2/+page.markdoc new file mode 100644 index 0000000000..d166dfceb0 --- /dev/null +++ b/src/routes/docs/tutorials/react/step-2/+page.markdoc @@ -0,0 +1,28 @@ +--- +layout: tutorial +title: Create app +description: This is the description used for SEO. +step: 2 +--- + +## Create React project {% #create-react-project %} + +Create a React app with the `npm create` command. + +```sh +npm create vite@latest --template react ideas-tracker && cd ideas-tracker +``` + +## Add dependencies {% #add-dependencies %} + +Install the JavaScript Appwrite SDK. + +```sh +npm install appwrite +``` + +You can start the development server to watch your app update in the browser as you make changes. + +```sh +npm run dev -- --open --port 3000 +``` \ No newline at end of file diff --git a/src/routes/docs/tutorials/react/step-3/+page.markdoc b/src/routes/docs/tutorials/react/step-3/+page.markdoc new file mode 100644 index 0000000000..50c9fa0f4c --- /dev/null +++ b/src/routes/docs/tutorials/react/step-3/+page.markdoc @@ -0,0 +1,42 @@ +--- +layout: tutorial +title: Set up Appwrite +description: This is the description used for SEO. +step: 3 +--- + +## Create project {% #create-project %} + +Head to the [Appwrite Console](https://cloud.appwrite.io/console). + +![Create project screen](/images/docs/databases/quick-start/create-project.png) + +If this is your first time using Appwrite, create an account and create your first project. + +Then, under **Add a platform**, add a **Web app**. The **Hostname** should be localhost. + +![Add a platform](/images/docs/databases/quick-start/add-platform.png) + +You can skip optional steps. + +## Initialize Appwrite SDK {% #init-sdk %} + +To use Appwrite in our Svelte app, we'll need to find our project ID. Find your project's ID in the **Settings** page. + +![Settings page in Appwrite Console.](/images/docs/databases/quick-start/project-id.png) + +Create a new file `src/lib/appwrite.js` to hold our Appwrite related code. +Only one instance of the `Client()` class should be created per app. +Add the following code to it, replacing `` with your project ID. + +```js +import { Client } from "appwrite"; + +const client = new Client(); +client + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject(""); // Replace with your project IDxw + +export const account = new Account(client); +export const database = new Database(client); +``` \ No newline at end of file diff --git a/src/routes/docs/tutorials/react/step-4/+page.markdoc b/src/routes/docs/tutorials/react/step-4/+page.markdoc new file mode 100644 index 0000000000..5551c802b2 --- /dev/null +++ b/src/routes/docs/tutorials/react/step-4/+page.markdoc @@ -0,0 +1,185 @@ +--- +layout: tutorial +title: Add authentication +description: This is the description used for SEO. +step: 4 +--- + +## User context + +In React, you can use [context](https://reactjs.org/docs/context.html) to share data between components. +We'll use context and a custom hook to manage our user's data. + +Create a new file `src/lib/context/user.jsx` and add the following code to it. + +```js +import { createContext, useContext, useEffect, useState } from "react"; +import { account } from "../appwrite"; + +const UserContext = createContext(); + +export function useUser() { + return useContext(UserContext); +} + +export function UserProvider(props) { + const [user, setUser] = useState(null); + + async function login(email, password) { + const loggedIn = await account.createEmailSession(email, password); + setUser(loggedIn); + } + + async function logout() { + await account.deleteSession("current"); + setUser(null); + } + + async function register(email, password) { + await account.create(email, password); + await login(email, password); + } + + async function init() { + try { + const loggedIn = await account.get(); + setUser(loggedIn); + } catch (err) { + setUser(null); + } + } + + useEffect(() => { + init(); + }, []); + + return ( + + {props.children} + + ); +} +``` + +Now, we can use the `useUser` hook to access the user's data from any component. However, we first need to wrap our app with the `UserProvider`. + +## Basic routing + +First, wrap the `main` element with the `UserProvider` component. + +Update `src/App.jsx` to the following code. + +```jsx +import { Home } from "./pages/Home"; +import { UserProvider } from "./lib/context/user"; + +function App() { + const isLoginPage = window.location.pathname === "/login"; + + return ( +
+ +
Home page
+
+
+ ); +} + +export default App; +``` + +Then, optionally render the `Login` component if the path is `/login`, otherwise render the `Home` component. + +Update `src/App.jsx` to the following code. + +```jsx +import { Login } from "./pages/Login"; +import { Home } from "./pages/Home"; +import { UserProvider } from "./lib/context/user"; + +function App() { + const isLoginPage = window.location.pathname === "/login"; + + return ( +
+ +
{isLoginPage ? : }
+
+
+ ); +} + +export default App; +``` + +## Home page + +Create a new file `src/pages/Home.jsx` and add the following stub code to it. + +```jsx +// We'll complete this component later +export function Home() { + return ( +

I'm the home page

+ ); +} +``` + +## Login page + +Finally, we are able to create the login page. Users will be able to login or register from this page, so we'll need to add two buttons. + +Create a new file `src/pages/Login.jsx` and add the following code to it. + +```jsx +import { useState } from "react"; +import { useUser } from "../lib/context/user"; + +export function Login() { + const user = useUser(); + + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + + return ( +
+

Login or register

+
+ { + setEmail(event.target.value); + }} + /> + { + setPassword(event.target.value); + }} + /> +
+ + +
+
+
+ ); +} +``` + diff --git a/src/routes/docs/tutorials/react/step-5/+page.markdoc b/src/routes/docs/tutorials/react/step-5/+page.markdoc new file mode 100644 index 0000000000..709163abc2 --- /dev/null +++ b/src/routes/docs/tutorials/react/step-5/+page.markdoc @@ -0,0 +1,57 @@ +--- +layout: tutorial +title: Add navigation +description: This is the description used for SEO. +step: 5 +difficulty: easy +readtime: 10 +--- + +In our app we want to have a navigation bar that is always visible. We will add it to the `App` component and use the `useUser` hook to show either: +- a logout button if the user is logged in. +- a login button if the user is not logged in. + +Update the App componenent in `src/App.jsx`: + +```jsx +import { Login } from "./pages/Login"; +import { Home } from "./pages/Home"; +import { UserProvider, useUser } from "./lib/context/user"; + +function App() { + const isLoginPage = window.location.pathname === "/login"; + + return ( +
+ + {/* Add the navbar before page content */} +
{isLoginPage ? : }
+
+
+ ); +} + +function Navbar() { + const user = useUser(); + + return ( + + ); +} + +export default App; +``` diff --git a/src/routes/docs/tutorials/react/step-6/+page.markdoc b/src/routes/docs/tutorials/react/step-6/+page.markdoc new file mode 100644 index 0000000000..fc1783ea81 --- /dev/null +++ b/src/routes/docs/tutorials/react/step-6/+page.markdoc @@ -0,0 +1,79 @@ +--- +layout: tutorial +title: Add database +description: This is the description used for SEO. +step: 6 +difficulty: easy +readtime: 10 +--- +## Create collection +In Appwrite, data is stored as a collection of documents. Create a collection in the [Appwrite Console](https://cloud.appwrite.io/) to store our ideas. + +![Create collection screen](#TODO update me) + +Create a new collection with the following attributes: +| Field | Type | Required | +|-------------|--------|----------| +| userId | String | Yes | +| title | String | Yes | +| description | String | No | + +## Ideas context + +Now that you have a collection to hold ideas, we can read and write to it from our app. Like we did with the user data, we will create a React context to hold our ideas. +Create a new file `src/lib/context/ideas.jsx` and add the following code to it. + +```js +import { createContext, useContext, useEffect, useState } from "react"; +import { databases } from "../appwrite"; +import { ID, Query } from "appwrite"; + +export const IDEAS_DATABASE_ID = ""; // Replace with your database ID +export const IDEAS_COLLECTION_ID = ""; // Replace with your collection ID + +const IdeasContext = createContext(); + +export function useIdeas() { + return useContext(IdeasContext); +} + +export function IdeasProvider(props) { + const [ideas, setIdeas] = useState([]); + + async function add(idea) { + const response = await databases.createDocument( + IDEAS_DATABASE_ID, + IDEAS_COLLECTION_ID, + ID.unique(), + idea + ); + setIdeas((ideas) => [response.$id, ...ideas].slice(0, 10)); + } + + async function remove(id) { + await databases.deleteDocument(IDEAS_DATABASE_ID, IDEAS_COLLECTION_ID, id); + setIdeas((ideas) => ideas.filter((idea) => idea.$id !== id)); + await init(); // Refetch ideas to ensure we have 10 items + } + + async function init() { + const response = await databases.listDocuments( + IDEAS_DATABASE_ID, + IDEAS_COLLECTION_ID, + [Query.orderDesc("$createdAt"), Query.limit(10)] + ); + setIdeas(response.documents); + } + + useEffect(() => { + init(); + }, []); + + return ( + + {props.children} + + ); +} +``` + diff --git a/src/routes/docs/tutorials/react/step-7/+page.markdoc b/src/routes/docs/tutorials/react/step-7/+page.markdoc new file mode 100644 index 0000000000..fa6db81157 --- /dev/null +++ b/src/routes/docs/tutorials/react/step-7/+page.markdoc @@ -0,0 +1,83 @@ +--- +layout: tutorial +title: Create ideas page +description: This is the description used for SEO. +step: 7 +difficulty: easy +readtime: 10 +--- + +Using the `useIdeas` hook we can now display the ideas on the page. We will also add a form to submit new ideas. + +Overwrite the contents of `src/pages/Home.jsx` with the following: + +```jsx +import { useState } from "react"; +import { useUser } from "../lib/context/user"; +import { useIdeas } from "../lib/context/ideas"; + +export function Home() { + const user = useUser(); + const ideas = useIdeas(); + + const [title, setTitle] = useState(""); + const [description, setDescription] = useState(""); + + return ( + <> + {/* Show the submit form to logged in users. */} + {user.current ? ( +
+

Submit Idea

+
+ { + setTitle(event.target.value); + }} + /> + + +
+
+

Please login to submit an idea.

+ +
+

Latest Ideas

+
    +
  • + {{ idea.title }} +

    {{ idea.description }}

    + +
  • +
+
+ +``` \ No newline at end of file diff --git a/src/routes/docs/tutorials/vue/step-8/+page.markdoc b/src/routes/docs/tutorials/vue/step-8/+page.markdoc new file mode 100644 index 0000000000..9c5af3c44c --- /dev/null +++ b/src/routes/docs/tutorials/vue/step-8/+page.markdoc @@ -0,0 +1,14 @@ +--- +layout: tutorial +title: Next steps +description: This is the description used for SEO. +step: 8 +difficulty: easy +readtime: 10 +--- + +## Test your project {% #test-project %} +Run your project with `npm run dev -- --open --port 3000` and open [http://localhost:3000](http://localhost:3000) in your browser. + +## Add style {% #add-style %} +If you want to see a version of this project, complete with CSS styles, clone [this GitHub repository](). \ No newline at end of file diff --git a/src/routes/kitchensink/+page.svelte b/src/routes/kitchensink/+page.svelte index 380c281090..8074011045 100644 --- a/src/routes/kitchensink/+page.svelte +++ b/src/routes/kitchensink/+page.svelte @@ -73,27 +73,6 @@
  • item



  • -
      -
    • - - - item -
    • -
    • - - - item -
    • -
    • - - - item -
    • -
    -


    @@ -245,8 +224,8 @@
    @@ -284,7 +263,7 @@
    - + + import { page } from '$app/stores'; + import { Docs } from '$lib/layouts'; + import Sidebar from '$routes/docs/Sidebar.svelte'; + + + + + +
    +
    +
    + 404_ +

    + Page not found +

    +

    + Sorry, it seems that the page you are looking for does not exist. Feel free to use our navigation menu or the button below to explore more of Appwrite’s documentation. +

    + +
    +
    +
    + + diff --git a/src/routes/privacy/+page.svelte b/src/routes/privacy/+page.svelte index 24cd965009..02b30cf0ce 100644 --- a/src/routes/privacy/+page.svelte +++ b/src/routes/privacy/+page.svelte @@ -1013,26 +1013,26 @@ In addition to the recipients described above, we may share your Personal Data as follows:

    -

    +

    With our business partners with whom we jointly offer products or services. We may also share Personal Data with our affiliated companies.

    -

    +

    To the extent necessary, with regulators, courts or competent authorities, to comply with applicable laws, regulations and rules (including, without limitation, federal, state or local laws), and requests of law enforcement, regulatory and other governmental agencies or if required to do so by court order;

    -

    +

    If, in the future, we sell or transfer, or we consider selling or transferring, some or all of our business, shares or assets to a third party, we will disclose your Personal Data to such third party (whether actual or potential) in connection with the foregoing events;

    -

    +

    In the event that we are acquired by, or merged with, a third party entity, or in the event of bankruptcy or a comparable event, we reserve the right to transfer, @@ -1041,7 +1041,7 @@ company assets, consolidation or restructuring, financing, or acquisition of all or a portion of our business by or to another company; and/or

    -

    +

    Where you have provided your consent to us sharing or transferring your Personal Data (e.g., where you provide us with marketing consents or opt-in to optional @@ -1126,7 +1126,7 @@ -

    +

    You can exercise your rights by contacting us at privacy@appwrite.io. You may use an authorized agent to submit a request on your behalf if you provide the authorized @@ -1145,7 +1145,7 @@ the maximum extent possible, all in accordance with applicable law.

    -

    +

    Deleting your account: Should you ever decide to delete your account, you may do so by emailing privacy@appwrite.io. If you terminate your account, any association diff --git a/src/scss/1-css-variables/_fonts.scss b/src/scss/1-css-variables/_fonts.scss index b6e83d8b69..cfb175fd8d 100644 --- a/src/scss/1-css-variables/_fonts.scss +++ b/src/scss/1-css-variables/_fonts.scss @@ -11,7 +11,8 @@ --aw-font-size-medium: #{pxToRem(18)}; --aw-font-size-large: #{pxToRem(20)}; --aw-font-size-xl: #{pxToRem(24)}; - --aw-font-size-xxl: #{pxToRem(40)}; + --aw-font-size-xxl: #{pxToRem(32)}; + --aw-font-size-xxxl: #{pxToRem(40)}; --aw-font-size-big: #{pxToRem(48)}; --aw-font-size-huge: #{pxToRem(56)}; --aw-font-size-super: #{pxToRem(64)}; diff --git a/src/scss/6-elements/_button.scss b/src/scss/6-elements/_button.scss index 53c2bb75d1..572b6ea140 100644 --- a/src/scss/6-elements/_button.scss +++ b/src/scss/6-elements/_button.scss @@ -6,11 +6,12 @@ background: linear-gradient(135deg, hsl(var(--aw-color-pink-500)) 0%, hsl(var(--aw-color-pink-500)) 61%, hsl(var(--aw-color-secondary-100)) 100%); background-origin: border-box; - display:flex; justify-content:center; align-items:center; gap:pxToRem(8); + display:flex; inline-size:fit-content; justify-content:center; align-items:center; gap:pxToRem(8); padding-inline:pxToRem(14); padding-block:pxToRem(7); min-block-size:pxToRem(40); border-radius:var(--m-border-radius); border:solid var(--m-border-size) transparent; text-align:center; transition:var(--transition); user-select:none; color:hsl(var(--aw-color-white)); font-weight: 500; + [class*="icon"] { line-height:1; } .#{$p}-inline-tag { margin-inline-end:pxToRem(-2); background:rgba(255, 255, 255, 0.24); } &:where(:hover):where(:not(#{$disabled})) { @@ -42,7 +43,7 @@ } - #{$theme-dark} & { + @mixin dark-mode { background: rgba(253, 54, 110, 0.04); color: hsl(var(--aw-color-greyscale-100)); box-shadow: 0px -6px 10px 0px rgba(253, 54, 110, 0.08) inset; @@ -97,8 +98,9 @@ box-shadow: 0px 0px 0px 4px rgba(253, 54, 110, 0.16), 0px -6px 10px 0px rgba(253, 54, 110, 0.08) inset; } } + - #{$theme-light} & { + @mixin light-mode { background: rgba(253, 54, 110, 0.08); box-shadow: none; color: hsl(var(--aw-color-accent-click)); @@ -129,6 +131,17 @@ box-shadow: 0px 0px 0px 4px rgba(253, 54, 110, 0.24); } } + @include light-mode; + + #{$theme-dark} & { + @include dark-mode; + } + + #{$theme-light} & { + @include light-mode; + } + + } &.is-transparent { background: rgba(237, 237, 240, 0.16); border-width:0; diff --git a/src/scss/6-elements/_container.scss b/src/scss/6-elements/_container.scss index 316e6423ba..70ad51c9d5 100644 --- a/src/scss/6-elements/_container.scss +++ b/src/scss/6-elements/_container.scss @@ -6,6 +6,7 @@ max-inline-size: var(--p-container-size); padding-inline: pxToRem(32); margin-inline: auto; + @media #{$break1} { padding-inline: pxToRem(20); } } .#{$p}-main-section { diff --git a/src/scss/6-elements/_hero-banner-button.scss b/src/scss/6-elements/_hero-banner-button.scss index f340067a81..9ee8b74327 100644 --- a/src/scss/6-elements/_hero-banner-button.scss +++ b/src/scss/6-elements/_hero-banner-button.scss @@ -1,6 +1,20 @@ @use '../abstract' as *; .#{$p}-hero-banner-button { + @include border-gradient; + --m-border-gradient-before: linear-gradient( + to bottom, + rgba(253, 54, 110, 0.48) 0%, + rgba(253, 54, 110, 0) 180% + ); + --m-border-gradient-after: radial-gradient( + 42.86% 42.86% at 50.55% -0%, + rgba(255, 255, 255, 0.2) 0%, + rgba(255, 255, 255, 0) 100% + ); + --m-border-radius: #{pxToRem(14)}; + + --p-hero-button-text-color: var(--p-hero-button-text-color-default); --p-hero-button-bg-color: var(--p-hero-button-bg-color-default); --p-hero-button-border-color: var(--p-hero-button-border-color-default); @@ -22,8 +36,8 @@ display:flex; align-items:baseline; gap:pxToRem(4); padding-block:pxToRem(4); padding-inline:pxToRem(8); background:hsl(var(--p-hero-button-bg-color)); - border:pxToRem(1) solid hsl(var(--p-hero-button-border-color)); - line-height:pxToRem(20); border-radius:pxToRem(14); + + line-height:pxToRem(20); color:hsl(var(--p-hero-button-text-color)); box-shadow:0 0 0 pxToRem(4) hsl(var(--p-hero-button-shadow-out-color)); diff --git a/src/scss/6-elements/_icon-button.scss b/src/scss/6-elements/_icon-button.scss index 0f22949e8d..673e91f28b 100644 --- a/src/scss/6-elements/_icon-button.scss +++ b/src/scss/6-elements/_icon-button.scss @@ -50,7 +50,7 @@ --p-icon-button-border-color: var(--p-icon-button-border-color-focus); --p-icon-button-shadow-color: var(--p-icon-button-shadow-color-focus); } - &:disabled { opacity:0.4; } + &:disabled { opacity:0.4; cursor:initial; } #{$theme-dark} & { @include dark-mode(); diff --git a/src/scss/6-elements/_inline-code.scss b/src/scss/6-elements/_inline-code.scss index bd14710d76..93eaa54b7d 100644 --- a/src/scss/6-elements/_inline-code.scss +++ b/src/scss/6-elements/_inline-code.scss @@ -7,5 +7,5 @@ color: hsl(var(--p-inline-code-text-color)); background-color: hsl(var(--p-inline-code-bg-color)); - display:inline-flex; padding-inline:pxToRem(4); padding-block:pxToRem(1); border-radius:pxToRem(4); font-family:var(--aw-font-family-aeonik-fono); + display:inline-flex; padding-inline:pxToRem(4); padding-block:pxToRem(1); border-radius:pxToRem(4); font-family:monospace; } \ No newline at end of file diff --git a/src/scss/6-elements/_media.scss b/src/scss/6-elements/_media.scss index ac91bc59ba..44986dc80d 100644 --- a/src/scss/6-elements/_media.scss +++ b/src/scss/6-elements/_media.scss @@ -1,17 +1,16 @@ @use '../abstract' as *; .#{$p}-media { - --p-media-border-color:var(--aw-color-border); - --p-media-bg: linear-gradient(143deg, #FFF 0%, rgba(255, 255, 255, 0.00) 100%); + @include border-gradient; + --m-border-gradient-before: linear-gradient(186deg, rgba(255, 255, 255, 0.16) -1.41%, rgba(255, 255, 255, 0.00) 104.86%); + --m-border-radius: #{pxToRem(16)}; + + --p-media-bg: linear-gradient(113deg, rgba(255, 255, 255, 0.10) -1.78%, rgba(255, 255, 255, 0.06) 62.5%, rgba(255, 255, 255, 0.10) 103.4%); background: var(--p-media-bg); padding:pxToRem(8); - border:solid pxToRem(1) hsl(var(--p-media-border-color)); - border-radius:pxToRem(16); - - -webkit-backdrop-filter: blur(pxToRem(30)); - backdrop-filter: blur(pxToRem(30)); - + + > * { display:block; border-radius:pxToRem(12); } #{$theme-dark} & { diff --git a/src/scss/6-elements/text-tokens/_title.scss b/src/scss/6-elements/text-tokens/_title.scss index 7dc2de499c..fb8a5a32f9 100644 --- a/src/scss/6-elements/text-tokens/_title.scss +++ b/src/scss/6-elements/text-tokens/_title.scss @@ -1,8 +1,8 @@ @use '../../abstract' as *; .#{$p}-title { --p-font-family: var(--aw-font-family-aeonik-pro); - --p-font-size: var(--aw-font-size-big); - --p-line-height: var(--aw-line-height-lg); + --p-font-size: var(--aw-font-size-xxl); + --p-line-height: var(--aw-line-height-big); --p-letter-spacing: var(--aw-letter-spacing-squeezed); --p-font-weight: var(--aw-font-weight-regular); @@ -14,6 +14,6 @@ @media #{$break3open} { --p-line-height: var(--aw-line-height-big); - --p-font-size: var(--aw-font-size-xxl); + --p-font-size: var(--aw-font-size-xxxl); } } \ No newline at end of file diff --git a/src/scss/7-components/_inline-info.scss b/src/scss/7-components/_inline-info.scss index 03b4d553c4..7acc0409a9 100644 --- a/src/scss/7-components/_inline-info.scss +++ b/src/scss/7-components/_inline-info.scss @@ -1,19 +1,24 @@ @use '../abstract' as *; .#{$p}-inline-info { + @include border-gradient; + --m-border-gradient-before: linear-gradient(0deg, #C3C3C6 0%, rgba(195, 195, 198, 0.20) 100%); + --m-border-radius: #{pxToRem(8)}; + >:last-child { margin-block-end:0!important;} --p-inline-info-bg-color: var(--aw-color-white) / 0.04; --p-inline-info-border-color: var(--aw-color-greyscale-250); background:hsl(var(--p-inline-info-bg-color)); - border:pxToRem(1) solid hsl(var(--p-inline-info-border-color)); + display:flex; flex-direction:column; gap:pxToRem(8); - padding:pxToRem(16); border-radius:pxToRem(8); + padding:pxToRem(16); [class*="icon"]:first-child { color:hsl(var(--aw-color-primary)); font-size:pxToRem(24)!important; } #{$theme-dark} & { --p-inline-info-bg-color: var(--aw-color-white) / 0.04; --p-inline-info-border-color: var(--aw-color-white) / 0.6; + --m-border-gradient-before: linear-gradient(180deg, rgba(255, 255, 255, 0.60) 0%, rgba(255, 255, 255, 0.20) 100%); } } \ No newline at end of file diff --git a/src/scss/7-components/_main-header.scss b/src/scss/7-components/_main-header.scss index eae967dd96..77debce907 100644 --- a/src/scss/7-components/_main-header.scss +++ b/src/scss/7-components/_main-header.scss @@ -1,8 +1,7 @@ @use '../abstract' as *; .#{$p}-main-header { - --p-main-header-padding-block: #{pxToRem(15)}; - --p-main-header-padding-inline: #{pxToRem(32)}; + --p-main-header-padding-block: #{pxToRem(16)}; --p-main-header-link-color: var(--aw-color-greyscale-900); --p-main-header-border-color: rgb(0,0,0, 0.1); @@ -49,4 +48,10 @@ @media #{$break1}, #{$break2}{ display:none; } + + + transition: transform 0.3s ease; + &.is-hidden { + transform: translateY(-100%); + } } \ No newline at end of file diff --git a/src/scss/7-components/_mobile-header.scss b/src/scss/7-components/_mobile-header.scss index 695eb7deeb..8dd8d97bad 100644 --- a/src/scss/7-components/_mobile-header.scss +++ b/src/scss/7-components/_mobile-header.scss @@ -22,4 +22,9 @@ &#{$theme-light} { --p-mobile-header-border-color: rgb(0,0,0, 0.1); } + + transition: transform 0.3s ease; + &.is-hidden { + transform: translateY(-100%); + } } \ No newline at end of file diff --git a/src/scss/7-components/_side-nav.scss b/src/scss/7-components/_side-nav.scss index b4fa4df757..b533118895 100644 --- a/src/scss/7-components/_side-nav.scss +++ b/src/scss/7-components/_side-nav.scss @@ -5,12 +5,13 @@ --p-side-nav-item-icon-color: var(--p-side-nav-icon-item-color-default); --p-side-nav-item-bg-color: var(--p-side-nav-item-bg-color-default); - --p-side-nav-text-item-color-default: var(--aw-color-greyscale-900); + --p-side-nav-text-item-color-default: var(--aw-color-secondary); --p-side-nav-icon-item-color-default: var(--aw-color-greyscale-250); --p-side-nav-item-bg-color-default: var(--transparent); --p-side-nav-item-bg-color-hover: var(--aw-color-greyscale-50); + --p-side-nav-item-text-color-selected: var(--aw-color-primary); --p-side-nav-item-icon-color-selected: linear-gradient( hsla(343, 98%, 60%, 1), hsla(22, 98%, 60%, 1) ); --p-side-nav-bg-color: var(--p-body-bg-color); @@ -30,7 +31,8 @@ &-parent { display:flex; align-items:baseline; padding-block-end:pxToRem(16); border-block-end:pxToRem(1) solid hsl(var(--aw-color-smooth)); - &-title { inline-size:100%; text-align:center; } + [class*="icon"]:first-child { flex-shrink:0; padding-inline:pxToRem(12); } + &-title { inline-size:100%; text-align:center; transition:var(--transition); } } } &-scroll { @@ -55,6 +57,7 @@ --p-side-nav-item-bg-color: var(--p-side-nav-item-bg-color-hover); } &.is-selected { + color: hsl(var(--p-side-nav-item-text-color-selected)); [class*="icon"]:first-child { background: var(--p-side-nav-item-icon-color-selected); -webkit-background-clip: text; @@ -87,7 +90,6 @@ } #{$theme-dark} & { - --p-side-nav-text-item-color-default: var(--aw-color-greyscale-100); --p-side-nav-item-bg-color-hover: var(--aw-color-white) / 0.08; } } \ No newline at end of file diff --git a/src/scss/7-components/_top-banner.scss b/src/scss/7-components/_top-banner.scss index 1779d7985b..b5b3f71a46 100644 --- a/src/scss/7-components/_top-banner.scss +++ b/src/scss/7-components/_top-banner.scss @@ -2,7 +2,7 @@ .#{$p}-top-banner { display:flex; justify-content:center; - padding-block:pxToRem(9); padding-inline:pxToRem(12); + padding-block:pxToRem(5); padding-inline:pxToRem(12); background: linear-gradient(94deg, rgba(253, 54, 110, 0.00) 0%, rgba(253, 54, 110, 0.50) 50.82%, rgba(253, 54, 110, 0.00) 100%); &-content { line-height:pxToRem(20); transition:var(--transition); } &-button { position:absolute; inset-inline-end:pxToRem(12); } diff --git a/src/scss/9-grids/_grid-huge-navs.scss b/src/scss/9-grids/_grid-huge-navs.scss index f1c6c3b583..94fdd77387 100644 --- a/src/scss/9-grids/_grid-huge-navs.scss +++ b/src/scss/9-grids/_grid-huge-navs.scss @@ -106,7 +106,12 @@ @media #{$break3}, #{$break4}, #{$break5} { .#{$p}-side-nav { max-inline-size:var(--p-grid-huge-navs-side-nav-width-closed); - &-wrapper { inline-size:var(--p-grid-huge-navs-side-nav-width-closed); max-inline-size:var(--p-grid-huge-navs-side-nav-width-closed); } + &-wrapper { + inline-size:var(--p-grid-huge-navs-side-nav-width-closed); max-inline-size:var(--p-grid-huge-navs-side-nav-width-closed); + &-parent { + &-title { opacity:0; } + } + } &-header { opacity:0; transition:var(--transition); } &-button { > *:not(:first-child) { opacity:0; transition:var(--transition); } @@ -114,7 +119,12 @@ } &.is-open { .#{$p}-side-nav { - &-wrapper { max-inline-size:var(--p-grid-huge-navs-side-nav-width-opened); inline-size:var(--p-grid-huge-navs-side-nav-width-opened); } + &-wrapper { + max-inline-size:var(--p-grid-huge-navs-side-nav-width-opened); inline-size:var(--p-grid-huge-navs-side-nav-width-opened); + &-parent { + &-title { opacity:1; } + } + } &-header { opacity:1; } &-button { > *:not(:first-child) { opacity:1; } diff --git a/src/scss/9-grids/_grid-two-side-navs.scss b/src/scss/9-grids/_grid-two-side-navs.scss index cf1b7fc257..edd99bd390 100644 --- a/src/scss/9-grids/_grid-two-side-navs.scss +++ b/src/scss/9-grids/_grid-two-side-navs.scss @@ -2,7 +2,7 @@ .#{$p}-grid-two-side-navs { --p-grid-huge-navs-padding-inline: #{pxToRem(28)}; - --p-grid-huge-navs-main-header-height: #{pxToRem(80)}; + --p-grid-huge-navs-main-header-height: #{pxToRem(73)}; --p-grid-huge-navs-secondary-header-height: #{pxToRem(116)}; --p-grid-huge-navs-secondary-sticky-position: #{pxToRem(120)}; --p-grid-huge-navs--margin-top-content-side-b: #{pxToRem(40)}; diff --git a/src/scss/_10-utilities.scss b/src/scss/_10-utilities.scss index 08b89e274b..f70539560f 100644 --- a/src/scss/_10-utilities.scss +++ b/src/scss/_10-utilities.scss @@ -3,6 +3,7 @@ .#{$p}-u-hide-mobile { @media #{$break1}{ display:none!important; } } .#{$p}-u-opacity-90 { opacity:0.9!important; } +.#{$p}-u-flex-vertical {display:flex!important; flex-direction:column!important; } .#{$p}-u-flex-vertical-reverse-mobile { @media #{$break1} { flex-direction:column-reverse!important; } } diff --git a/src/markdoc/nodes/Fence.css b/src/scss/hljs.css similarity index 100% rename from src/markdoc/nodes/Fence.css rename to src/scss/hljs.css diff --git a/static/icon-font/_variables.scss b/static/icon-font/_variables.scss index 39a107daf2..1dd80f8c19 100644 --- a/static/icon-font/_variables.scss +++ b/static/icon-font/_variables.scss @@ -1,32 +1,34 @@ -$aw-icon-arrow-down: "\ea01"; -$aw-icon-arrow-ext-link: "\ea02"; -$aw-icon-arrow-left: "\ea03"; -$aw-icon-arrow-right: "\ea04"; -$aw-icon-arrow-up: "\ea05"; -$aw-icon-calendar: "\ea06"; -$aw-icon-check: "\ea07"; -$aw-icon-chevron-down: "\ea08"; -$aw-icon-chevron-left: "\ea09"; -$aw-icon-chevron-right: "\ea0a"; -$aw-icon-chevron-up: "\ea0b"; -$aw-icon-close: "\ea0c"; -$aw-icon-copy: "\ea0d"; -$aw-icon-dark: "\ea0e"; -$aw-icon-discord: "\ea0f"; -$aw-icon-divider-vertical: "\ea10"; -$aw-icon-download: "\ea11"; -$aw-icon-github: "\ea12"; -$aw-icon-hamburger-menu: "\ea13"; -$aw-icon-light: "\ea14"; -$aw-icon-linkedin: "\ea15"; -$aw-icon-location: "\ea16"; -$aw-icon-logout-left: "\ea17"; -$aw-icon-logout-right: "\ea18"; -$aw-icon-minus: "\ea19"; -$aw-icon-plus: "\ea1a"; -$aw-icon-product-hunt: "\ea1b"; -$aw-icon-search: "\ea1c"; -$aw-icon-star: "\ea1d"; -$aw-icon-twitter: "\ea1e"; -$aw-icon-x: "\ea1f"; -$aw-icon-youtube: "\ea20"; +$aw-icon-apple: "\ea01"; +$aw-icon-arrow-down: "\ea02"; +$aw-icon-arrow-ext-link: "\ea03"; +$aw-icon-arrow-left: "\ea04"; +$aw-icon-arrow-right: "\ea05"; +$aw-icon-arrow-up: "\ea06"; +$aw-icon-calendar: "\ea07"; +$aw-icon-check: "\ea08"; +$aw-icon-chevron-down: "\ea09"; +$aw-icon-chevron-left: "\ea0a"; +$aw-icon-chevron-right: "\ea0b"; +$aw-icon-chevron-up: "\ea0c"; +$aw-icon-close: "\ea0d"; +$aw-icon-copy: "\ea0e"; +$aw-icon-dark: "\ea0f"; +$aw-icon-discord: "\ea10"; +$aw-icon-divider-vertical: "\ea11"; +$aw-icon-download: "\ea12"; +$aw-icon-github: "\ea13"; +$aw-icon-google: "\ea14"; +$aw-icon-hamburger-menu: "\ea15"; +$aw-icon-light: "\ea16"; +$aw-icon-linkedin: "\ea17"; +$aw-icon-location: "\ea18"; +$aw-icon-logout-left: "\ea19"; +$aw-icon-logout-right: "\ea1a"; +$aw-icon-microsoft: "\ea1b"; +$aw-icon-minus: "\ea1c"; +$aw-icon-plus: "\ea1d"; +$aw-icon-product-hunt: "\ea1e"; +$aw-icon-search: "\ea1f"; +$aw-icon-star: "\ea20"; +$aw-icon-twitter: "\ea21"; +$aw-icon-youtube: "\ea22"; diff --git a/static/icon-font/aw-icon.css b/static/icon-font/aw-icon.css index 7af35c544a..20c5917ec9 100644 --- a/static/icon-font/aw-icon.css +++ b/static/icon-font/aw-icon.css @@ -17,35 +17,37 @@ -moz-osx-font-smoothing: grayscale; } -.aw-icon-arrow-down:before { content: "\ea01"; } -.aw-icon-arrow-ext-link:before { content: "\ea02"; } -.aw-icon-arrow-left:before { content: "\ea03"; } -.aw-icon-arrow-right:before { content: "\ea04"; } -.aw-icon-arrow-up:before { content: "\ea05"; } -.aw-icon-calendar:before { content: "\ea06"; } -.aw-icon-check:before { content: "\ea07"; } -.aw-icon-chevron-down:before { content: "\ea08"; } -.aw-icon-chevron-left:before { content: "\ea09"; } -.aw-icon-chevron-right:before { content: "\ea0a"; } -.aw-icon-chevron-up:before { content: "\ea0b"; } -.aw-icon-close:before { content: "\ea0c"; } -.aw-icon-copy:before { content: "\ea0d"; } -.aw-icon-dark:before { content: "\ea0e"; } -.aw-icon-discord:before { content: "\ea0f"; } -.aw-icon-divider-vertical:before { content: "\ea10"; } -.aw-icon-download:before { content: "\ea11"; } -.aw-icon-github:before { content: "\ea12"; } -.aw-icon-hamburger-menu:before { content: "\ea13"; } -.aw-icon-light:before { content: "\ea14"; } -.aw-icon-linkedin:before { content: "\ea15"; } -.aw-icon-location:before { content: "\ea16"; } -.aw-icon-logout-left:before { content: "\ea17"; } -.aw-icon-logout-right:before { content: "\ea18"; } -.aw-icon-minus:before { content: "\ea19"; } -.aw-icon-plus:before { content: "\ea1a"; } -.aw-icon-product-hunt:before { content: "\ea1b"; } -.aw-icon-search:before { content: "\ea1c"; } -.aw-icon-star:before { content: "\ea1d"; } -.aw-icon-twitter:before { content: "\ea1e"; } -.aw-icon-x:before { content: "\ea1f"; } -.aw-icon-youtube:before { content: "\ea20"; } +.aw-icon-apple:before { content: "\ea01"; } +.aw-icon-arrow-down:before { content: "\ea02"; } +.aw-icon-arrow-ext-link:before { content: "\ea03"; } +.aw-icon-arrow-left:before { content: "\ea04"; } +.aw-icon-arrow-right:before { content: "\ea05"; } +.aw-icon-arrow-up:before { content: "\ea06"; } +.aw-icon-calendar:before { content: "\ea07"; } +.aw-icon-check:before { content: "\ea08"; } +.aw-icon-chevron-down:before { content: "\ea09"; } +.aw-icon-chevron-left:before { content: "\ea0a"; } +.aw-icon-chevron-right:before { content: "\ea0b"; } +.aw-icon-chevron-up:before { content: "\ea0c"; } +.aw-icon-close:before { content: "\ea0d"; } +.aw-icon-copy:before { content: "\ea0e"; } +.aw-icon-dark:before { content: "\ea0f"; } +.aw-icon-discord:before { content: "\ea10"; } +.aw-icon-divider-vertical:before { content: "\ea11"; } +.aw-icon-download:before { content: "\ea12"; } +.aw-icon-github:before { content: "\ea13"; } +.aw-icon-google:before { content: "\ea14"; } +.aw-icon-hamburger-menu:before { content: "\ea15"; } +.aw-icon-light:before { content: "\ea16"; } +.aw-icon-linkedin:before { content: "\ea17"; } +.aw-icon-location:before { content: "\ea18"; } +.aw-icon-logout-left:before { content: "\ea19"; } +.aw-icon-logout-right:before { content: "\ea1a"; } +.aw-icon-microsoft:before { content: "\ea1b"; } +.aw-icon-minus:before { content: "\ea1c"; } +.aw-icon-plus:before { content: "\ea1d"; } +.aw-icon-product-hunt:before { content: "\ea1e"; } +.aw-icon-search:before { content: "\ea1f"; } +.aw-icon-star:before { content: "\ea20"; } +.aw-icon-twitter:before { content: "\ea21"; } +.aw-icon-youtube:before { content: "\ea22"; } diff --git a/static/icon-font/aw-icon.scss b/static/icon-font/aw-icon.scss index fe28d699b5..228d7dd21e 100644 --- a/static/icon-font/aw-icon.scss +++ b/static/icon-font/aw-icon.scss @@ -16,68 +16,72 @@ -moz-osx-font-smoothing: grayscale; } -.aw-icon-arrow-down:before { content: "\ea01"; } -.aw-icon-arrow-ext-link:before { content: "\ea02"; } -.aw-icon-arrow-left:before { content: "\ea03"; } -.aw-icon-arrow-right:before { content: "\ea04"; } -.aw-icon-arrow-up:before { content: "\ea05"; } -.aw-icon-calendar:before { content: "\ea06"; } -.aw-icon-check:before { content: "\ea07"; } -.aw-icon-chevron-down:before { content: "\ea08"; } -.aw-icon-chevron-left:before { content: "\ea09"; } -.aw-icon-chevron-right:before { content: "\ea0a"; } -.aw-icon-chevron-up:before { content: "\ea0b"; } -.aw-icon-close:before { content: "\ea0c"; } -.aw-icon-copy:before { content: "\ea0d"; } -.aw-icon-dark:before { content: "\ea0e"; } -.aw-icon-discord:before { content: "\ea0f"; } -.aw-icon-divider-vertical:before { content: "\ea10"; } -.aw-icon-download:before { content: "\ea11"; } -.aw-icon-github:before { content: "\ea12"; } -.aw-icon-hamburger-menu:before { content: "\ea13"; } -.aw-icon-light:before { content: "\ea14"; } -.aw-icon-linkedin:before { content: "\ea15"; } -.aw-icon-location:before { content: "\ea16"; } -.aw-icon-logout-left:before { content: "\ea17"; } -.aw-icon-logout-right:before { content: "\ea18"; } -.aw-icon-minus:before { content: "\ea19"; } -.aw-icon-plus:before { content: "\ea1a"; } -.aw-icon-product-hunt:before { content: "\ea1b"; } -.aw-icon-search:before { content: "\ea1c"; } -.aw-icon-star:before { content: "\ea1d"; } -.aw-icon-twitter:before { content: "\ea1e"; } -.aw-icon-x:before { content: "\ea1f"; } -.aw-icon-youtube:before { content: "\ea20"; } +.aw-icon-apple:before { content: "\ea01"; } +.aw-icon-arrow-down:before { content: "\ea02"; } +.aw-icon-arrow-ext-link:before { content: "\ea03"; } +.aw-icon-arrow-left:before { content: "\ea04"; } +.aw-icon-arrow-right:before { content: "\ea05"; } +.aw-icon-arrow-up:before { content: "\ea06"; } +.aw-icon-calendar:before { content: "\ea07"; } +.aw-icon-check:before { content: "\ea08"; } +.aw-icon-chevron-down:before { content: "\ea09"; } +.aw-icon-chevron-left:before { content: "\ea0a"; } +.aw-icon-chevron-right:before { content: "\ea0b"; } +.aw-icon-chevron-up:before { content: "\ea0c"; } +.aw-icon-close:before { content: "\ea0d"; } +.aw-icon-copy:before { content: "\ea0e"; } +.aw-icon-dark:before { content: "\ea0f"; } +.aw-icon-discord:before { content: "\ea10"; } +.aw-icon-divider-vertical:before { content: "\ea11"; } +.aw-icon-download:before { content: "\ea12"; } +.aw-icon-github:before { content: "\ea13"; } +.aw-icon-google:before { content: "\ea14"; } +.aw-icon-hamburger-menu:before { content: "\ea15"; } +.aw-icon-light:before { content: "\ea16"; } +.aw-icon-linkedin:before { content: "\ea17"; } +.aw-icon-location:before { content: "\ea18"; } +.aw-icon-logout-left:before { content: "\ea19"; } +.aw-icon-logout-right:before { content: "\ea1a"; } +.aw-icon-microsoft:before { content: "\ea1b"; } +.aw-icon-minus:before { content: "\ea1c"; } +.aw-icon-plus:before { content: "\ea1d"; } +.aw-icon-product-hunt:before { content: "\ea1e"; } +.aw-icon-search:before { content: "\ea1f"; } +.aw-icon-star:before { content: "\ea20"; } +.aw-icon-twitter:before { content: "\ea21"; } +.aw-icon-youtube:before { content: "\ea22"; } -$aw-icon-arrow-down: "\ea01"; -$aw-icon-arrow-ext-link: "\ea02"; -$aw-icon-arrow-left: "\ea03"; -$aw-icon-arrow-right: "\ea04"; -$aw-icon-arrow-up: "\ea05"; -$aw-icon-calendar: "\ea06"; -$aw-icon-check: "\ea07"; -$aw-icon-chevron-down: "\ea08"; -$aw-icon-chevron-left: "\ea09"; -$aw-icon-chevron-right: "\ea0a"; -$aw-icon-chevron-up: "\ea0b"; -$aw-icon-close: "\ea0c"; -$aw-icon-copy: "\ea0d"; -$aw-icon-dark: "\ea0e"; -$aw-icon-discord: "\ea0f"; -$aw-icon-divider-vertical: "\ea10"; -$aw-icon-download: "\ea11"; -$aw-icon-github: "\ea12"; -$aw-icon-hamburger-menu: "\ea13"; -$aw-icon-light: "\ea14"; -$aw-icon-linkedin: "\ea15"; -$aw-icon-location: "\ea16"; -$aw-icon-logout-left: "\ea17"; -$aw-icon-logout-right: "\ea18"; -$aw-icon-minus: "\ea19"; -$aw-icon-plus: "\ea1a"; -$aw-icon-product-hunt: "\ea1b"; -$aw-icon-search: "\ea1c"; -$aw-icon-star: "\ea1d"; -$aw-icon-twitter: "\ea1e"; -$aw-icon-x: "\ea1f"; -$aw-icon-youtube: "\ea20"; +$aw-icon-apple: "\ea01"; +$aw-icon-arrow-down: "\ea02"; +$aw-icon-arrow-ext-link: "\ea03"; +$aw-icon-arrow-left: "\ea04"; +$aw-icon-arrow-right: "\ea05"; +$aw-icon-arrow-up: "\ea06"; +$aw-icon-calendar: "\ea07"; +$aw-icon-check: "\ea08"; +$aw-icon-chevron-down: "\ea09"; +$aw-icon-chevron-left: "\ea0a"; +$aw-icon-chevron-right: "\ea0b"; +$aw-icon-chevron-up: "\ea0c"; +$aw-icon-close: "\ea0d"; +$aw-icon-copy: "\ea0e"; +$aw-icon-dark: "\ea0f"; +$aw-icon-discord: "\ea10"; +$aw-icon-divider-vertical: "\ea11"; +$aw-icon-download: "\ea12"; +$aw-icon-github: "\ea13"; +$aw-icon-google: "\ea14"; +$aw-icon-hamburger-menu: "\ea15"; +$aw-icon-light: "\ea16"; +$aw-icon-linkedin: "\ea17"; +$aw-icon-location: "\ea18"; +$aw-icon-logout-left: "\ea19"; +$aw-icon-logout-right: "\ea1a"; +$aw-icon-microsoft: "\ea1b"; +$aw-icon-minus: "\ea1c"; +$aw-icon-plus: "\ea1d"; +$aw-icon-product-hunt: "\ea1e"; +$aw-icon-search: "\ea1f"; +$aw-icon-star: "\ea20"; +$aw-icon-twitter: "\ea21"; +$aw-icon-youtube: "\ea22"; diff --git a/static/icon-font/aw-icon.svg b/static/icon-font/aw-icon.svg index d3794b3aac..2e33a20028 100644 --- a/static/icon-font/aw-icon.svg +++ b/static/icon-font/aw-icon.svg @@ -7,102 +7,111 @@ units-per-em="1000" ascent="800" descent="200" /> - - + - + - + - + - + - + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + unicode="" + horiz-adv-x="1000" d="M445.5327546991673 746.4294681568039C416.9327546991673 743.3294681568038 369.6327546991673 731.7794681568039 343.0327546991673 721.3794681568039C305.2327546991673 706.6294681568039 249.9827546991673 675.1294681568039 220.5327546991674 651.4794681568038C204.4327546991673 638.5794681568038 159.5827546991674 593.7294681568038 146.6327546991673 577.5794681568038C111.0827546991673 533.2294681568038 81.6327546991673 473.7794681568038 66.4827546991673 415.7294681568038C40.2827546991673 315.4294681568038 47.4327546991673 218.9794681568039 88.1827546991673 123.0294681568039C125.4827546991673 35.2294681568038 196.3327546991673 -43.0205318431962 283.0327546991673 -92.1205318431962C330.1827546991673 -118.8205318431962 391.5327546991673 -138.7205318431961 446.5827546991673 -145.0705318431963C479.6327546991673 -148.9205318431962 546.5827546991673 -147.6205318431961 574.6827546991673 -142.5705318431962C645.5327546991673 -129.9205318431962 710.3327546991673 -102.2205318431961 765.5327546991673 -60.9205318431961C786.8327546991674 -45.0205318431962 831.2827546991672 -2.5705318431962 849.5327546991673 19.2794681568039C899.3327546991673 78.7794681568039 933.6827546991672 157.8794681568038 946.3827546991674 242.0794681568038C949.8327546991674 265.0294681568039 949.7827546991672 336.7794681568039 946.2827546991672 360.7294681568038C942.6327546991672 385.4294681568039 933.7827546991672 421.0794681568039 924.8327546991674 447.1794681568039C899.3827546991673 521.0794681568038 863.8327546991673 574.5294681568039 801.0327546991674 633.2294681568038C734.4827546991673 695.4794681568038 639.3827546991672 738.2294681568038 550.5327546991673 745.9294681568039C532.5827546991673 747.4794681568038 458.4327546991673 747.8294681568038 445.5327546991673 746.4294681568039M568.8827546991673 522.7794681568039L601.3827546991673 521.6294681568039L619.0327546991673 513.1794681568039C651.4327546991674 497.6794681568039 673.4327546991673 479.5794681568038 689.8827546991673 454.8794681568038C711.0327546991673 423.1294681568038 714.8327546991673 407.5794681568039 713.4827546991673 358.4294681568039C712.6827546991673 329.5294681568038 712.4827546991673 327.9294681568038 707.3327546991673 315.1794681568039C692.4827546991673 278.0294681568039 668.0327546991673 250.1294681568039 632.8327546991674 230.0294681568039C604.1327546991672 213.6294681568038 584.2827546991673 210.9794681568039 489.2827546991673 210.9294681568038L432.1827546991673 210.9294681568038L432.1827546991673 143.4294681568038L432.1827546991673 75.9294681568038L388.0327546991673 75.9294681568038L343.8827546991673 75.9294681568038L343.8827546991673 301.1794681568039L343.8827546991673 526.4794681568038L440.1327546991673 525.1794681568039C493.0327546991673 524.4794681568038 550.9827546991673 523.4294681568039 568.8827546991673 522.7794681568039M432.1827546991673 368.5794681568039L432.1827546991673 300.9294681568039L483.4327546991673 300.9294681568039C541.1827546991673 300.9794681568038 577.6827546991673 303.0294681568038 586.7327546991673 306.7794681568039C599.9827546991673 312.3294681568039 618.0327546991673 331.7794681568039 623.0327546991673 345.8794681568038C624.6327546991672 350.4294681568039 625.6327546991673 359.3294681568039 625.6827546991673 369.6794681568039C625.7827546991673 384.3794681568039 625.2827546991673 387.2794681568039 621.3327546991674 395.3294681568039C615.4327546991673 407.3794681568038 602.2827546991673 420.5794681568039 588.8827546991673 427.9794681568038L578.0327546991673 433.9294681568039L505.1327546991673 435.0794681568039L432.1827546991673 436.2794681568038L432.1827546991673 368.5794681568039" /> + unicode="" + horiz-adv-x="1000" d="M430.7197929920109 601.0363898787523C378.8697929920109 590.0363898787523 339.4697929920109 570.7363898787523 300.9197929920109 537.3863898787524C238.2197929920109 483.1363898787524 201.2697929920109 392.6363898787524 208.8697929920109 312.0863898787524C215.8697929920109 237.5863898787524 246.7197929920109 175.2863898787524 299.4697929920109 129.0863898787524C347.5697929920109 86.8863898787524 399.0697929920109 64.7863898787525 462.7697929920109 58.9363898787524C511.1697929920109 54.4863898787524 561.469792992011 65.5863898787524 614.669792992011 92.3863898787524L639.8697929920108 105.0863898787524L685.7697929920109 60.0363898787524C735.5197929920109 11.2363898787524 752.4697929920108 -3.6136101212476 760.2697929920109 -5.1636101212476C771.5697929920109 -7.4636101212475 788.6197929920108 5.8363898787523 791.5697929920109 19.2363898787524C794.3697929920108 32.0863898787524 788.0197929920109 40.6363898787524 733.1697929920108 97.4863898787524C712.3697929920108 119.0363898787524 693.5197929920109 139.0363898787524 691.2697929920109 141.9863898787524L687.1197929920108 147.2863898787524L700.3697929920108 166.1363898787524C707.6197929920108 176.4863898787524 717.0697929920109 191.0363898787524 721.3197929920109 198.4863898787524C730.8697929920108 215.1863898787524 744.7697929920109 249.8363898787524 750.2697929920109 270.8363898787524C754.219792992011 285.7863898787525 754.419792992011 289.1363898787524 754.5197929920109 331.6363898787524C754.6197929920108 381.5863898787524 754.219792992011 384.0363898787524 741.4197929920108 421.0363898787524C726.8197929920109 462.8863898787524 708.8697929920108 491.1863898787524 675.8197929920109 524.2863898787523C634.0697929920109 566.0363898787523 590.3197929920109 589.7863898787523 534.5197929920109 600.9363898787524C521.0697929920109 603.6363898787524 508.5697929920108 604.6863898787524 484.869792992011 605.1863898787524C455.0197929920109 605.7863898787523 451.9197929920109 605.5363898787523 430.7197929920109 601.0363898787523M510.6197929920109 543.2363898787523C538.719792992011 539.3363898787522 553.0197929920109 535.1363898787524 574.8697929920108 524.3363898787522C621.1197929920108 501.4863898787524 654.1697929920108 467.7363898787524 676.5197929920109 420.3863898787524C687.219792992011 397.7863898787524 692.0197929920109 379.4363898787524 694.219792992011 352.5363898787524C698.169792992011 303.7863898787524 689.3197929920109 264.5863898787524 665.1197929920108 223.6363898787524C633.7197929920108 170.5363898787524 582.8697929920108 134.4863898787524 521.1697929920108 121.5863898787524C503.7197929920109 117.9363898787523 464.3697929920109 117.9363898787523 444.8697929920109 121.5863898787524C385.3197929920109 132.7863898787524 336.2197929920109 166.0363898787524 303.019792992011 217.7863898787524C294.1197929920109 231.6363898787524 289.8197929920109 240.1363898787524 279.9197929920109 263.3363898787524L272.0697929920109 281.6363898787524L272.7197929920109 333.3363898787524C273.3197929920109 381.6863898787524 273.6197929920109 385.6863898787524 277.1197929920109 395.5863898787524C282.019792992011 409.4863898787524 295.8197929920109 436.9363898787525 305.269792992011 451.6363898787524C314.5197929920109 466.0363898787524 338.8697929920109 491.1863898787524 356.1197929920109 504.2363898787524C378.9197929920109 521.4863898787523 412.6197929920109 536.3863898787524 444.4697929920109 543.2863898787523C458.6197929920109 546.3863898787524 488.4197929920109 546.3363898787525 510.6197929920109 543.2363898787523" /> + unicode="" + horiz-adv-x="1000" d="M481.2594304095069 626.5289276285795C469.5594304095068 622.0289276285795 460.3594304095069 614.2789276285795 454.0094304095069 603.4789276285795C450.6594304095069 597.7789276285795 431.0594304095069 560.3789276285795 410.5094304095069 520.3289276285795C389.9594304095069 480.3289276285795 372.2594304095069 446.7789276285796 371.1094304095068 445.8789276285795C370.0094304095069 444.9289276285795 350.7094304095068 441.4289276285795 328.3094304095069 438.0789276285795C214.7094304095068 421.2289276285796 189.0594304095069 416.9789276285796 181.4594304095068 413.7289276285796C172.2594304095069 409.7289276285795 157.8094304095069 395.3289276285795 153.8094304095069 386.0789276285795C150.0594304095068 377.4289276285795 150.0094304095069 352.0289276285796 153.7094304095068 343.6289276285795C157.3094304095068 335.4789276285795 173.8094304095069 318.4789276285795 236.3594304095069 258.4789276285796C265.0594304095069 230.9289276285795 289.1594304095069 207.1789276285796 290.0094304095069 205.6789276285795C291.4594304095068 202.9289276285795 288.9094304095069 186.5789276285796 270.8094304095069 81.4789276285795C266.5094304095069 56.7289276285795 262.9594304095069 31.5789276285796 262.9094304095069 25.6289276285795C262.4594304095068 -5.2710723714205 285.5594304095069 -27.8710723714206 318.0594304095069 -28.3710723714205L330.2594304095069 -28.5210723714205L415.1594304095069 14.3789276285795L500.0594304095068 57.2789276285795L584.8594304095068 14.3789276285795L669.659430409507 -28.5210723714205L682.7594304095069 -28.4210723714206C699.2594304095069 -28.2710723714206 711.1094304095069 -23.0710723714205 722.4094304095069 -10.9710723714205C739.4594304095068 7.2289276285795 740.2594304095069 16.4289276285795 729.9594304095069 76.4789276285795C710.7594304095069 188.9789276285795 708.6094304095069 202.9789276285794 710.059430409507 205.6789276285795C710.8594304095069 207.2289276285795 735.7594304095069 231.7289276285796 765.3594304095069 260.1289276285795C850.909430409507 342.2789276285796 849.1594304095069 340.1289276285795 849.0094304095069 364.9789276285795C848.8594304095069 382.8789276285795 845.9594304095069 390.1289276285795 833.7594304095069 402.6289276285795C820.4594304095068 416.2789276285795 824.2094304095069 415.4789276285796 672.1594304095069 438.0289276285795C649.9594304095069 441.3289276285796 630.8094304095068 444.4289276285795 629.6594304095069 444.8789276285795C628.4594304095069 445.3289276285795 614.059430409507 472.1289276285795 597.6594304095069 504.4289276285795C562.4594304095069 573.6789276285795 546.0594304095068 604.5789276285795 540.809430409507 611.5789276285795C538.7094304095068 614.3789276285795 532.2094304095069 619.2289276285795 526.4094304095069 622.3289276285795C517.1594304095069 627.2789276285795 514.059430409507 628.0289276285795 501.6594304095069 628.4289276285795C492.3094304095068 628.7789276285795 485.4094304095069 628.1289276285795 481.2594304095069 626.5289276285795M536.0094304095069 491.8789276285795C573.3594304095069 418.1289276285795 582.4094304095069 402.9289276285795 594.0094304095069 394.2789276285795C603.0594304095068 387.5289276285795 608.4094304095069 386.4789276285796 706.2094304095069 372.3289276285795C744.5094304095069 366.7789276285796 777.2594304095069 361.6789276285795 778.9594304095069 360.9289276285795C781.5594304095068 359.8789276285796 776.059430409507 353.9289276285795 745.6094304095069 324.7789276285795C656.3094304095068 239.2789276285795 652.0094304095069 234.5289276285795 648.4594304095068 218.5789276285796C646.1594304095069 208.2789276285796 648.2594304095069 192.3789276285795 663.409430409507 106.3289276285794C669.9594304095068 69.1289276285795 674.8594304095069 38.2789276285795 674.309430409507 37.7289276285795C673.7594304095069 37.1789276285795 637.5094304095069 54.7789276285795 593.7594304095069 76.8289276285794C539.5094304095069 104.1789276285795 511.7094304095068 117.3289276285796 506.4094304095069 118.1289276285795C501.0594304095069 118.9289276285795 495.6094304095069 118.4289276285795 488.9094304095069 116.4789276285795C483.5594304095068 114.9289276285795 444.5094304095069 96.1289276285795 402.1094304095068 74.6789276285795C357.4094304095069 52.1289276285795 325.0094304095069 36.6289276285795 325.0094304095069 37.8789276285795C325.0094304095069 39.0789276285796 329.1594304095069 63.6289276285795 334.2594304095069 92.4289276285796C354.5094304095069 207.3789276285795 355.1094304095069 213.5789276285796 347.8094304095069 228.9789276285796C343.2094304095068 238.7289276285796 328.6594304095069 253.6289276285795 254.4094304095069 324.7789276285795C223.9594304095069 353.9289276285795 218.4594304095068 359.8789276285796 221.0594304095069 360.9289276285795C222.7594304095069 361.6789276285795 255.5094304095069 366.7789276285796 293.8094304095069 372.3289276285795C393.3094304095069 386.7289276285796 397.0094304095069 387.4789276285795 406.4094304095069 394.7789276285796C418.1094304095069 403.7789276285795 426.0094304095069 417.1289276285795 464.0094304095068 492.0289276285795C483.1594304095069 529.7289276285795 499.3594304095069 560.6289276285795 500.0094304095069 560.6289276285795C500.6594304095069 560.6289276285795 516.8594304095069 529.6789276285795 536.0094304095069 491.8789276285795" /> + unicode="" + horiz-adv-x="1000" d="M622.8457160720377 656.6773589952508C607.0457160720375 652.4773589952507 580.5457160720377 639.5773589952507 565.1457160720377 628.6273589952508C530.1957160720376 603.8273589952507 507.7957160720376 573.4273589952508 494.4457160720377 532.4773589952507C489.0457160720376 516.0773589952508 488.9957160720377 515.3273589952507 488.2457160720376 477.9273589952508L487.5457160720377 440.0273589952508L480.5957160720376 440.0273589952508C469.8957160720377 440.0273589952508 429.3957160720377 446.2773589952508 405.3457160720377 451.6273589952507C336.2457160720376 467.0273589952508 277.5957160720377 492.2273589952507 218.6957160720377 531.8773589952508C190.4957160720377 550.7773589952508 176.9957160720377 562.1273589952508 138.9957160720377 598.6273589952508C103.0957160720377 633.1773589952508 106.5457160720377 632.3773589952508 97.8457160720377 608.4773589952507C87.4457160720377 580.0273589952508 85.8457160720377 572.3273589952507 84.9457160720376 545.5773589952507C84.0457160720377 517.9273589952508 85.4457160720376 506.2773589952507 92.0957160720377 485.5773589952507C101.6957160720376 455.8773589952507 113.9457160720377 436.7773589952508 143.1457160720377 405.7773589952507C158.9957160720377 388.9773589952507 159.9957160720377 387.4773589952507 156.1457160720376 387.0273589952508C152.0457160720377 386.5273589952507 119.2457160720377 394.5773589952508 94.9957160720377 401.9773589952507C88.3457160720377 403.9773589952507 82.3957160720376 405.1273589952507 81.7457160720376 404.4773589952507C79.4957160720377 402.2273589952507 84.5957160720377 373.2273589952507 90.2957160720377 355.8773589952507C101.0457160720377 323.0273589952507 112.9457160720377 303.1273589952507 135.2457160720377 280.6273589952508C153.3957160720377 262.3273589952508 172.5957160720377 249.4773589952507 199.9957160720377 237.2773589952508C211.1457160720377 232.3273589952507 220.9457160720377 227.5773589952508 221.7457160720376 226.7773589952508C223.7457160720376 224.7773589952508 214.7957160720377 223.6773589952507 180.4457160720377 221.6273589952507C162.1957160720377 220.5273589952508 151.7457160720377 219.2273589952508 150.9457160720377 217.9773589952508C148.5457160720376 214.0773589952507 161.9457160720377 189.1773589952507 175.6957160720377 171.9773589952508C207.1457160720377 132.6773589952507 238.3457160720376 113.4773589952508 291.1957160720377 100.8273589952507C301.6957160720377 98.3273589952507 310.9457160720376 95.6773589952507 311.6957160720377 95.0273589952508C313.4957160720376 93.4273589952507 302.1957160720376 84.3773589952508 286.1457160720377 74.5273589952508C247.7457160720377 50.9273589952507 188.7457160720377 29.8773589952508 140.1457160720377 22.4773589952508C131.0957160720377 21.1273589952507 108.4457160720377 19.4773589952507 89.8457160720377 18.8773589952507C71.2457160720377 18.2773589952508 55.6957160720377 17.2273589952507 55.2457160720376 16.5273589952508C54.1957160720377 14.7773589952508 87.5457160720377 -2.8226410047493 112.8457160720376 -13.8226410047492C169.4457160720377 -38.4726410047494 228.3457160720377 -53.6226410047493 286.1957160720377 -58.4226410047494C314.9957160720376 -60.8226410047493 380.1457160720377 -59.4726410047492 406.1957160720376 -55.9226410047493C491.2957160720376 -44.3726410047492 574.6957160720376 -11.2726410047493 642.8457160720377 37.9773589952508C663.6457160720377 53.0273589952506 731.7457160720378 120.0773589952507 747.3457160720377 140.8273589952507C789.1457160720377 196.6773589952507 818.2457160720378 254.3773589952508 836.7957160720377 318.5273589952507C850.2457160720376 364.7773589952508 855.7957160720375 400.8273589952508 857.3457160720377 451.0773589952507L858.3457160720377 484.5773589952507L863.4957160720376 487.6273589952507C870.0457160720375 491.4273589952508 920.1457160720375 541.4773589952507 935.1457160720375 559.1273589952508C941.3457160720378 566.4773589952507 945.5957160720374 572.6773589952508 944.6457160720375 573.0273589952507C943.6957160720378 573.3273589952507 929.1957160720376 569.8273589952508 912.4457160720378 565.1773589952508C882.5457160720375 556.9273589952508 855.1457160720377 550.0273589952508 852.1957160720376 550.0273589952508C851.3457160720377 550.0273589952508 860.8957160720377 560.4773589952507 873.3957160720377 573.2273589952507C885.8957160720377 585.9773589952507 899.5457160720375 601.7273589952507 903.6957160720376 608.2273589952507C912.5957160720378 621.9273589952508 923.7457160720378 644.6773589952508 922.2957160720377 646.1273589952508C921.7457160720378 646.6773589952508 909.1457160720375 642.0273589952508 894.2457160720378 635.8273589952507C866.6957160720376 624.3273589952507 832.2457160720376 612.1773589952508 816.6957160720376 608.4773589952507L808.0457160720377 606.3773589952508L796.6957160720376 615.4273589952508C779.6457160720377 629.0773589952507 766.0457160720377 637.7273589952507 749.0457160720375 645.9273589952508C724.6457160720377 657.6273589952508 718.9957160720376 658.6273589952508 674.4957160720376 659.3773589952508C639.2957160720377 659.9773589952507 634.0957160720377 659.6773589952508 622.8457160720377 656.6773589952508" /> + unicode="" + horiz-adv-x="1000" d="" /> + unicode="" + horiz-adv-x="1000" d="M342.8248354863088 594.981218750014C215.2248354863089 592.5812187500142 174.5748354863088 588.3312187500142 147.8248354863088 574.5312187500142C122.7748354863088 561.5812187500142 106.2748354863089 540.5312187500142 96.3248354863088 508.6812187500141C81.4748354863088 461.2812187500141 74.6748354863088 396.7312187500141 74.7248354863088 302.5812187500142C74.7248354863088 238.0812187500141 76.5248354863088 202.6312187500141 82.0748354863088 156.9312187500141C90.8248354863088 85.0312187500142 103.3748354863088 56.0812187500141 135.7248354863089 33.3812187500142C161.3248354863088 15.3812187500141 201.5748354863089 8.4812187500141 301.1748354863089 4.9312187500141C363.3748354863089 2.6812187500141 682.0748354863089 3.9312187500141 724.4748354863088 6.5812187500141C835.7248354863087 13.4812187500142 852.424835486309 17.6812187500141 877.2248354863088 44.8312187500141C887.8748354863089 56.4812187500141 891.9248354863089 62.9312187500141 897.6248354863089 77.2312187500141C915.3248354863088 121.6812187500141 925.224835486309 199.4812187500141 925.2748354863088 295.0812187500141C925.374835486309 401.7312187500142 913.024835486309 492.0812187500141 892.5748354863089 534.7812187500142C878.4748354863088 564.2812187500142 846.2248354863088 582.981218750014 800.2248354863088 588.231218750014C742.4748354863088 594.8812187500141 515.3748354863088 598.231218750014 342.8248354863088 594.981218750014M543.2248354863088 362.3312187500141C606.6748354863089 328.3812187500141 637.9248354863089 309.6312187500141 636.1248354863088 306.6812187500141C634.0748354863089 303.3312187500141 569.6248354863088 268.9812187500141 458.2248354863088 211.8312187500141L415.3248354863089 189.7812187500142L415.3248354863089 309.2312187500141L415.3248354863089 428.6812187500141L461.5748354863088 404.9812187500141C487.0248354863088 391.9812187500141 523.7248354863088 372.7812187500142 543.2248354863088 362.3312187500141" /> diff --git a/static/icon-font/aw-icon.symbol.svg b/static/icon-font/aw-icon.symbol.svg index 82a56b0bbb..dc3eb05d79 100644 --- a/static/icon-font/aw-icon.symbol.svg +++ b/static/icon-font/aw-icon.symbol.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/static/icon-font/info.json b/static/icon-font/info.json index c9fce3dd89..5601527b9a 100644 --- a/static/icon-font/info.json +++ b/static/icon-font/info.json @@ -1,194 +1,206 @@ { - "arrow-down": { + "apple": { "encodedCode": "\\ea01", "prefix": "aw-icon", - "className": "aw-icon-arrow-down", + "className": "aw-icon-apple", "unicode": "" }, - "arrow-ext-link": { + "arrow-down": { "encodedCode": "\\ea02", "prefix": "aw-icon", - "className": "aw-icon-arrow-ext-link", + "className": "aw-icon-arrow-down", "unicode": "" }, - "arrow-left": { + "arrow-ext-link": { "encodedCode": "\\ea03", "prefix": "aw-icon", - "className": "aw-icon-arrow-left", + "className": "aw-icon-arrow-ext-link", "unicode": "" }, - "arrow-right": { + "arrow-left": { "encodedCode": "\\ea04", "prefix": "aw-icon", - "className": "aw-icon-arrow-right", + "className": "aw-icon-arrow-left", "unicode": "" }, - "arrow-up": { + "arrow-right": { "encodedCode": "\\ea05", "prefix": "aw-icon", - "className": "aw-icon-arrow-up", + "className": "aw-icon-arrow-right", "unicode": "" }, - "calendar": { + "arrow-up": { "encodedCode": "\\ea06", "prefix": "aw-icon", - "className": "aw-icon-calendar", + "className": "aw-icon-arrow-up", "unicode": "" }, - "check": { + "calendar": { "encodedCode": "\\ea07", "prefix": "aw-icon", - "className": "aw-icon-check", + "className": "aw-icon-calendar", "unicode": "" }, - "chevron-down": { + "check": { "encodedCode": "\\ea08", "prefix": "aw-icon", - "className": "aw-icon-chevron-down", + "className": "aw-icon-check", "unicode": "" }, - "chevron-left": { + "chevron-down": { "encodedCode": "\\ea09", "prefix": "aw-icon", - "className": "aw-icon-chevron-left", + "className": "aw-icon-chevron-down", "unicode": "" }, - "chevron-right": { + "chevron-left": { "encodedCode": "\\ea0a", "prefix": "aw-icon", - "className": "aw-icon-chevron-right", + "className": "aw-icon-chevron-left", "unicode": "" }, - "chevron-up": { + "chevron-right": { "encodedCode": "\\ea0b", "prefix": "aw-icon", - "className": "aw-icon-chevron-up", + "className": "aw-icon-chevron-right", "unicode": "" }, - "close": { + "chevron-up": { "encodedCode": "\\ea0c", "prefix": "aw-icon", - "className": "aw-icon-close", + "className": "aw-icon-chevron-up", "unicode": "" }, - "copy": { + "close": { "encodedCode": "\\ea0d", "prefix": "aw-icon", - "className": "aw-icon-copy", + "className": "aw-icon-close", "unicode": "" }, - "dark": { + "copy": { "encodedCode": "\\ea0e", "prefix": "aw-icon", - "className": "aw-icon-dark", + "className": "aw-icon-copy", "unicode": "" }, - "discord": { + "dark": { "encodedCode": "\\ea0f", "prefix": "aw-icon", - "className": "aw-icon-discord", + "className": "aw-icon-dark", "unicode": "" }, - "divider-vertical": { + "discord": { "encodedCode": "\\ea10", "prefix": "aw-icon", - "className": "aw-icon-divider-vertical", + "className": "aw-icon-discord", "unicode": "" }, - "download": { + "divider-vertical": { "encodedCode": "\\ea11", "prefix": "aw-icon", - "className": "aw-icon-download", + "className": "aw-icon-divider-vertical", "unicode": "" }, - "github": { + "download": { "encodedCode": "\\ea12", "prefix": "aw-icon", - "className": "aw-icon-github", + "className": "aw-icon-download", "unicode": "" }, - "hamburger-menu": { + "github": { "encodedCode": "\\ea13", "prefix": "aw-icon", - "className": "aw-icon-hamburger-menu", + "className": "aw-icon-github", "unicode": "" }, - "light": { + "google": { "encodedCode": "\\ea14", "prefix": "aw-icon", - "className": "aw-icon-light", + "className": "aw-icon-google", "unicode": "" }, - "linkedin": { + "hamburger-menu": { "encodedCode": "\\ea15", "prefix": "aw-icon", - "className": "aw-icon-linkedin", + "className": "aw-icon-hamburger-menu", "unicode": "" }, - "location": { + "light": { "encodedCode": "\\ea16", "prefix": "aw-icon", - "className": "aw-icon-location", + "className": "aw-icon-light", "unicode": "" }, - "logout-left": { + "linkedin": { "encodedCode": "\\ea17", "prefix": "aw-icon", - "className": "aw-icon-logout-left", + "className": "aw-icon-linkedin", "unicode": "" }, - "logout-right": { + "location": { "encodedCode": "\\ea18", "prefix": "aw-icon", - "className": "aw-icon-logout-right", + "className": "aw-icon-location", "unicode": "" }, - "minus": { + "logout-left": { "encodedCode": "\\ea19", "prefix": "aw-icon", - "className": "aw-icon-minus", + "className": "aw-icon-logout-left", "unicode": "" }, - "plus": { + "logout-right": { "encodedCode": "\\ea1a", "prefix": "aw-icon", - "className": "aw-icon-plus", + "className": "aw-icon-logout-right", "unicode": "" }, - "product-hunt": { + "microsoft": { "encodedCode": "\\ea1b", "prefix": "aw-icon", - "className": "aw-icon-product-hunt", + "className": "aw-icon-microsoft", "unicode": "" }, - "search": { + "minus": { "encodedCode": "\\ea1c", "prefix": "aw-icon", - "className": "aw-icon-search", + "className": "aw-icon-minus", "unicode": "" }, - "star": { + "plus": { "encodedCode": "\\ea1d", "prefix": "aw-icon", - "className": "aw-icon-star", + "className": "aw-icon-plus", "unicode": "" }, - "twitter": { + "product-hunt": { "encodedCode": "\\ea1e", "prefix": "aw-icon", - "className": "aw-icon-twitter", + "className": "aw-icon-product-hunt", "unicode": "" }, - "x": { + "search": { "encodedCode": "\\ea1f", "prefix": "aw-icon", - "className": "aw-icon-x", + "className": "aw-icon-search", "unicode": "" }, - "youtube": { + "star": { "encodedCode": "\\ea20", "prefix": "aw-icon", - "className": "aw-icon-youtube", + "className": "aw-icon-star", "unicode": "" + }, + "twitter": { + "encodedCode": "\\ea21", + "prefix": "aw-icon", + "className": "aw-icon-twitter", + "unicode": "" + }, + "youtube": { + "encodedCode": "\\ea22", + "prefix": "aw-icon", + "className": "aw-icon-youtube", + "unicode": "" } } diff --git a/static/images/animations/apple.svg b/static/images/animations/apple.svg new file mode 100644 index 0000000000..149a6be1fc --- /dev/null +++ b/static/images/animations/apple.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/static/images/animations/auth-shot.svg b/static/images/animations/auth-shot.svg new file mode 100644 index 0000000000..415e7cf338 --- /dev/null +++ b/static/images/animations/auth-shot.svg @@ -0,0 +1,384 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/animations/bandwidth-graph.svg b/static/images/animations/bandwidth-graph.svg new file mode 100644 index 0000000000..7abc58b8db --- /dev/null +++ b/static/images/animations/bandwidth-graph.svg @@ -0,0 +1,317 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/static/images/animations/check-circle.svg b/static/images/animations/check-circle.svg new file mode 100644 index 0000000000..f92de39f3c --- /dev/null +++ b/static/images/animations/check-circle.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/images/animations/credit-card.svg b/static/images/animations/credit-card.svg new file mode 100644 index 0000000000..b0d98b8c63 --- /dev/null +++ b/static/images/animations/credit-card.svg @@ -0,0 +1,4 @@ + + + + diff --git a/static/images/animations/mastercard.png b/static/images/animations/mastercard.png new file mode 100644 index 0000000000..3ac6949fc6 Binary files /dev/null and b/static/images/animations/mastercard.png differ diff --git a/static/images/animations/paypal.svg b/static/images/animations/paypal.svg new file mode 100644 index 0000000000..3a5f785ec8 --- /dev/null +++ b/static/images/animations/paypal.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/static/images/animations/realtime-graph.svg b/static/images/animations/realtime-graph.svg new file mode 100644 index 0000000000..ec08add960 --- /dev/null +++ b/static/images/animations/realtime-graph.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/animations/requests-graph.svg b/static/images/animations/requests-graph.svg new file mode 100644 index 0000000000..94ef92858b --- /dev/null +++ b/static/images/animations/requests-graph.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/static/images/animations/storage-1.png b/static/images/animations/storage-1.png new file mode 100644 index 0000000000..be243085e1 Binary files /dev/null and b/static/images/animations/storage-1.png differ diff --git a/static/images/animations/storage-2.png b/static/images/animations/storage-2.png new file mode 100644 index 0000000000..eaa2d97c5b Binary files /dev/null and b/static/images/animations/storage-2.png differ diff --git a/static/images/animations/storage-3.png b/static/images/animations/storage-3.png new file mode 100644 index 0000000000..1b006121c0 Binary files /dev/null and b/static/images/animations/storage-3.png differ diff --git a/static/images/animations/stripe.png b/static/images/animations/stripe.png new file mode 100644 index 0000000000..a50b7bee06 Binary files /dev/null and b/static/images/animations/stripe.png differ diff --git a/static/images/animations/tech.png b/static/images/animations/tech.png new file mode 100644 index 0000000000..c3290bb161 Binary files /dev/null and b/static/images/animations/tech.png differ diff --git a/static/images/animations/visa.png b/static/images/animations/visa.png new file mode 100644 index 0000000000..c664064945 Binary files /dev/null and b/static/images/animations/visa.png differ diff --git a/static/images/docs/databases/quick-start/project-id.png b/static/images/docs/databases/quick-start/project-id.png index 5f14d12ebe..1849efa695 100644 Binary files a/static/images/docs/databases/quick-start/project-id.png and b/static/images/docs/databases/quick-start/project-id.png differ diff --git a/static/images/icons/illustrated/auth-gray.svg b/static/images/icons/illustrated/auth-gray.svg deleted file mode 100644 index 0ec9191868..0000000000 --- a/static/images/icons/illustrated/auth-gray.svg +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/static/images/icons/illustrated/auth.svg b/static/images/icons/illustrated/auth.svg deleted file mode 100644 index a4df5e9a28..0000000000 --- a/static/images/icons/illustrated/auth.svg +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/static/images/icons/illustrated/dark/auth-transparent.png b/static/images/icons/illustrated/dark/auth-transparent.png new file mode 100644 index 0000000000..e451fb2435 Binary files /dev/null and b/static/images/icons/illustrated/dark/auth-transparent.png differ diff --git a/static/images/icons/illustrated/dark/auth.png b/static/images/icons/illustrated/dark/auth.png new file mode 100644 index 0000000000..65bab46b59 Binary files /dev/null and b/static/images/icons/illustrated/dark/auth.png differ diff --git a/static/images/icons/illustrated/dark/databases-transparent.png b/static/images/icons/illustrated/dark/databases-transparent.png new file mode 100644 index 0000000000..bc45f67808 Binary files /dev/null and b/static/images/icons/illustrated/dark/databases-transparent.png differ diff --git a/static/images/icons/illustrated/dark/databases.png b/static/images/icons/illustrated/dark/databases.png new file mode 100644 index 0000000000..87fe491a78 Binary files /dev/null and b/static/images/icons/illustrated/dark/databases.png differ diff --git a/static/images/icons/illustrated/dark/functions-transparent.png b/static/images/icons/illustrated/dark/functions-transparent.png new file mode 100644 index 0000000000..db96a0b06b Binary files /dev/null and b/static/images/icons/illustrated/dark/functions-transparent.png differ diff --git a/static/images/icons/illustrated/dark/functions.png b/static/images/icons/illustrated/dark/functions.png new file mode 100644 index 0000000000..c5892c17e7 Binary files /dev/null and b/static/images/icons/illustrated/dark/functions.png differ diff --git a/static/images/icons/illustrated/dark/realtime-transparent.png b/static/images/icons/illustrated/dark/realtime-transparent.png new file mode 100644 index 0000000000..2e1ff8aa9d Binary files /dev/null and b/static/images/icons/illustrated/dark/realtime-transparent.png differ diff --git a/static/images/icons/illustrated/dark/realtime.png b/static/images/icons/illustrated/dark/realtime.png new file mode 100644 index 0000000000..ab64b0b3bc Binary files /dev/null and b/static/images/icons/illustrated/dark/realtime.png differ diff --git a/static/images/icons/illustrated/dark/storage-transparent.png b/static/images/icons/illustrated/dark/storage-transparent.png new file mode 100644 index 0000000000..e193f325a1 Binary files /dev/null and b/static/images/icons/illustrated/dark/storage-transparent.png differ diff --git a/static/images/icons/illustrated/dark/storage.png b/static/images/icons/illustrated/dark/storage.png new file mode 100644 index 0000000000..92a299986a Binary files /dev/null and b/static/images/icons/illustrated/dark/storage.png differ diff --git a/static/images/icons/illustrated/databases-gray.svg b/static/images/icons/illustrated/databases-gray.svg deleted file mode 100644 index daee39e1fd..0000000000 --- a/static/images/icons/illustrated/databases-gray.svg +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/static/images/icons/illustrated/databases.svg b/static/images/icons/illustrated/databases.svg deleted file mode 100644 index c224f96e44..0000000000 --- a/static/images/icons/illustrated/databases.svg +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/static/images/icons/illustrated/functions-gray.svg b/static/images/icons/illustrated/functions-gray.svg deleted file mode 100644 index 2def6a7133..0000000000 --- a/static/images/icons/illustrated/functions-gray.svg +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/static/images/icons/illustrated/functions.svg b/static/images/icons/illustrated/functions.svg deleted file mode 100644 index 0e6702e509..0000000000 --- a/static/images/icons/illustrated/functions.svg +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/static/images/icons/illustrated/light/auth-transparent.png b/static/images/icons/illustrated/light/auth-transparent.png new file mode 100644 index 0000000000..67ff9023c3 Binary files /dev/null and b/static/images/icons/illustrated/light/auth-transparent.png differ diff --git a/static/images/icons/illustrated/light/auth.png b/static/images/icons/illustrated/light/auth.png new file mode 100644 index 0000000000..26713ca8a4 Binary files /dev/null and b/static/images/icons/illustrated/light/auth.png differ diff --git a/static/images/icons/illustrated/light/databases-transparent.png b/static/images/icons/illustrated/light/databases-transparent.png new file mode 100644 index 0000000000..8a9fcf1600 Binary files /dev/null and b/static/images/icons/illustrated/light/databases-transparent.png differ diff --git a/static/images/icons/illustrated/light/databases.png b/static/images/icons/illustrated/light/databases.png new file mode 100644 index 0000000000..88fcb91024 Binary files /dev/null and b/static/images/icons/illustrated/light/databases.png differ diff --git a/static/images/icons/illustrated/light/functions-transparent.png b/static/images/icons/illustrated/light/functions-transparent.png new file mode 100644 index 0000000000..9ee46afe05 Binary files /dev/null and b/static/images/icons/illustrated/light/functions-transparent.png differ diff --git a/static/images/icons/illustrated/light/functions.png b/static/images/icons/illustrated/light/functions.png new file mode 100644 index 0000000000..894d49f424 Binary files /dev/null and b/static/images/icons/illustrated/light/functions.png differ diff --git a/static/images/icons/illustrated/light/realtime-transparent.png b/static/images/icons/illustrated/light/realtime-transparent.png new file mode 100644 index 0000000000..b775ed08a1 Binary files /dev/null and b/static/images/icons/illustrated/light/realtime-transparent.png differ diff --git a/static/images/icons/illustrated/light/realtime.png b/static/images/icons/illustrated/light/realtime.png new file mode 100644 index 0000000000..5bd52c0188 Binary files /dev/null and b/static/images/icons/illustrated/light/realtime.png differ diff --git a/static/images/icons/illustrated/light/storage-transparent.png b/static/images/icons/illustrated/light/storage-transparent.png new file mode 100644 index 0000000000..d5279512a4 Binary files /dev/null and b/static/images/icons/illustrated/light/storage-transparent.png differ diff --git a/static/images/icons/illustrated/light/storage.png b/static/images/icons/illustrated/light/storage.png new file mode 100644 index 0000000000..342dbe37d4 Binary files /dev/null and b/static/images/icons/illustrated/light/storage.png differ diff --git a/static/images/icons/illustrated/messaging.svg b/static/images/icons/illustrated/messaging.svg deleted file mode 100644 index 40bb623d4c..0000000000 --- a/static/images/icons/illustrated/messaging.svg +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/static/images/icons/illustrated/realtime-gray.svg b/static/images/icons/illustrated/realtime-gray.svg deleted file mode 100644 index c5d3ac438e..0000000000 --- a/static/images/icons/illustrated/realtime-gray.svg +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/static/images/icons/illustrated/realtime.svg b/static/images/icons/illustrated/realtime.svg deleted file mode 100644 index 909ab58e19..0000000000 --- a/static/images/icons/illustrated/realtime.svg +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/static/images/icons/illustrated/storage-gray.svg b/static/images/icons/illustrated/storage-gray.svg deleted file mode 100644 index 39cac6d1b4..0000000000 --- a/static/images/icons/illustrated/storage-gray.svg +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/static/images/icons/illustrated/storage.svg b/static/images/icons/illustrated/storage.svg deleted file mode 100644 index 42e3ea2369..0000000000 --- a/static/images/icons/illustrated/storage.svg +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/static/images/products/Auth.svg b/static/images/products/Auth.svg new file mode 100644 index 0000000000..23711931eb --- /dev/null +++ b/static/images/products/Auth.svg @@ -0,0 +1,378 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/products/Databases.svg b/static/images/products/Databases.svg new file mode 100644 index 0000000000..3abe71b57c --- /dev/null +++ b/static/images/products/Databases.svg @@ -0,0 +1,340 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/products/Functions.svg b/static/images/products/Functions.svg new file mode 100644 index 0000000000..71b38af38e --- /dev/null +++ b/static/images/products/Functions.svg @@ -0,0 +1,231 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/products/Realtime.svg b/static/images/products/Realtime.svg new file mode 100644 index 0000000000..81dca8922e --- /dev/null +++ b/static/images/products/Realtime.svg @@ -0,0 +1,618 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/products/Storage.svg b/static/images/products/Storage.svg new file mode 100644 index 0000000000..e2007f8d1b --- /dev/null +++ b/static/images/products/Storage.svg @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/products/post.png b/static/images/products/post.png new file mode 100644 index 0000000000..dab89a1f6f Binary files /dev/null and b/static/images/products/post.png differ