@batijs/cli 0.0.282 → 0.0.287

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/dist/boilerplates/@batijs/auth0/files/$.env.js +10 -5
  2. package/dist/boilerplates/@batijs/auth0/files/$README.md.js +8 -3
  3. package/dist/boilerplates/@batijs/authjs/files/$package.json.js +12 -10
  4. package/dist/boilerplates/@batijs/authjs/files/global.d.ts +11 -0
  5. package/dist/boilerplates/@batijs/aws/files/$README.md.js +8 -3
  6. package/dist/boilerplates/@batijs/aws/files/$package.json.js +14 -9
  7. package/dist/boilerplates/@batijs/aws/files/$tsconfig.json.js +8 -3
  8. package/dist/boilerplates/@batijs/aws/files/cdk/$stack-name-suffix.json.js +3 -1
  9. package/dist/boilerplates/@batijs/biome/files/$package.json.js +12 -8
  10. package/dist/boilerplates/@batijs/cloudflare/files/$package.json.js +29 -17
  11. package/dist/boilerplates/@batijs/cloudflare/files/$tsconfig.json.js +8 -3
  12. package/dist/boilerplates/@batijs/cloudflare/files/$vite.config.ts.js +10 -4
  13. package/dist/boilerplates/@batijs/compiled/files/$package.json.js +10 -7
  14. package/dist/boilerplates/@batijs/compiled/files/$vite.config.ts.js +10 -4
  15. package/dist/boilerplates/@batijs/d1/files/$README.md.js +8 -3
  16. package/dist/boilerplates/@batijs/d1/files/$package.json.js +10 -7
  17. package/dist/boilerplates/@batijs/d1/files/$tsconfig.json.js +8 -3
  18. package/dist/boilerplates/@batijs/d1/files/$wrangler.toml.js +5 -2
  19. package/dist/boilerplates/@batijs/d1-sqlite/files/$package.json.js +8 -3
  20. package/dist/boilerplates/@batijs/d1-sqlite/files/database/d1/queries/lucia-auth.ts +1 -0
  21. package/dist/boilerplates/@batijs/drizzle/files/$.env.js +8 -3
  22. package/dist/boilerplates/@batijs/drizzle/files/$README.md.js +8 -3
  23. package/dist/boilerplates/@batijs/drizzle/files/$package.json.js +18 -9
  24. package/dist/boilerplates/@batijs/drizzle/files/drizzle.config.ts +1 -0
  25. package/dist/boilerplates/@batijs/drizzle/types/drizzle.config.d.ts +1 -0
  26. package/dist/boilerplates/@batijs/edgedb/files/$README.md.js +8 -3
  27. package/dist/boilerplates/@batijs/edgedb/files/$package.json.js +10 -7
  28. package/dist/boilerplates/@batijs/eslint/files/$package.json.js +16 -12
  29. package/dist/boilerplates/@batijs/express/files/$package.json.js +14 -16
  30. package/dist/boilerplates/@batijs/fastify/files/$package.json.js +15 -12
  31. package/dist/boilerplates/@batijs/fastify/files/global.d.ts +0 -11
  32. package/dist/boilerplates/@batijs/firebase-auth/files/$.env.js +8 -3
  33. package/dist/boilerplates/@batijs/firebase-auth/files/$README.md.js +8 -3
  34. package/dist/boilerplates/@batijs/firebase-auth/files/$package.json.js +12 -9
  35. package/dist/boilerplates/@batijs/firebase-auth/files/firebase/$service-account.json.js +3 -1
  36. package/dist/boilerplates/@batijs/google-analytics/files/$.env.js +8 -3
  37. package/dist/boilerplates/@batijs/h3/files/$package.json.js +15 -13
  38. package/dist/boilerplates/@batijs/h3/files/global.d.ts +0 -12
  39. package/dist/boilerplates/@batijs/hattip/files/$package.json.js +17 -11
  40. package/dist/boilerplates/@batijs/hono/files/$package.json.js +13 -9
  41. package/dist/boilerplates/@batijs/hono/files/$vite.config.ts.js +10 -4
  42. package/dist/boilerplates/@batijs/lucia-auth/files/$.env.js +9 -4
  43. package/dist/boilerplates/@batijs/lucia-auth/files/$README.md.js +8 -3
  44. package/dist/boilerplates/@batijs/lucia-auth/files/$package.json.js +20 -9
  45. package/dist/boilerplates/@batijs/lucia-auth/files/server/lucia-auth-handlers.ts +10 -7
  46. package/dist/boilerplates/@batijs/mantine/files/$README.md.js +8 -3
  47. package/dist/boilerplates/@batijs/mantine/files/$package.json.js +10 -7
  48. package/dist/boilerplates/@batijs/prettier/files/$package.json.js +10 -7
  49. package/dist/boilerplates/@batijs/prisma/files/$.env.js +8 -3
  50. package/dist/boilerplates/@batijs/prisma/files/$README.md.js +8 -3
  51. package/dist/boilerplates/@batijs/prisma/files/$package.json.js +10 -7
  52. package/dist/boilerplates/@batijs/react/files/$README.md.js +8 -3
  53. package/dist/boilerplates/@batijs/react/files/$package.json.js +10 -7
  54. package/dist/boilerplates/@batijs/react/files/$tsconfig.json.js +8 -3
  55. package/dist/boilerplates/@batijs/react/files/$vite.config.ts.js +10 -4
  56. package/dist/boilerplates/@batijs/react-sentry/files/$package.json.js +10 -7
  57. package/dist/boilerplates/@batijs/sentry/files/$.env.js +9 -4
  58. package/dist/boilerplates/@batijs/sentry/files/$README.md.js +8 -3
  59. package/dist/boilerplates/@batijs/sentry/files/$package.json.js +10 -7
  60. package/dist/boilerplates/@batijs/sentry/files/$vite.config.ts.js +12 -5
  61. package/dist/boilerplates/@batijs/sentry/files/pages/$+client.ts.js +14 -6
  62. package/dist/boilerplates/@batijs/shadcn-ui/files/$README.md.js +8 -3
  63. package/dist/boilerplates/@batijs/shadcn-ui/files/$package.json.js +12 -8
  64. package/dist/boilerplates/@batijs/shadcn-ui/files/$tsconfig.json.js +8 -3
  65. package/dist/boilerplates/@batijs/shadcn-ui/files/$vite.config.ts.js +10 -4
  66. package/dist/boilerplates/@batijs/shared/files/$README.md.js +14 -6
  67. package/dist/boilerplates/@batijs/shared-no-db/files/$package.json.js +10 -7
  68. package/dist/boilerplates/@batijs/shared-server/files/$package.json.js +10 -7
  69. package/dist/boilerplates/@batijs/solid/files/$README.md.js +8 -3
  70. package/dist/boilerplates/@batijs/solid/files/$package.json.js +10 -7
  71. package/dist/boilerplates/@batijs/solid/files/$tsconfig.json.js +8 -3
  72. package/dist/boilerplates/@batijs/solid/files/$vite.config.ts.js +10 -4
  73. package/dist/boilerplates/@batijs/solid-sentry/files/$package.json.js +10 -7
  74. package/dist/boilerplates/@batijs/sqlite/files/$.env.js +8 -3
  75. package/dist/boilerplates/@batijs/sqlite/files/$README.md.js +8 -3
  76. package/dist/boilerplates/@batijs/sqlite/files/$package.json.js +12 -9
  77. package/dist/boilerplates/@batijs/sqlite/files/database/sqlite/queries/lucia-auth.ts +1 -0
  78. package/dist/boilerplates/@batijs/sqlite/files/database/sqlite/schema/lucia-auth.ts +2 -1
  79. package/dist/boilerplates/@batijs/tailwindcss/files/$package.json.js +10 -7
  80. package/dist/boilerplates/@batijs/telefunc/files/$package.json.js +10 -7
  81. package/dist/boilerplates/@batijs/telefunc/files/$vite.config.ts.js +10 -4
  82. package/dist/boilerplates/@batijs/trpc/files/$package.json.js +10 -7
  83. package/dist/boilerplates/@batijs/trpc/types/trpc/client.d.ts +4 -4
  84. package/dist/boilerplates/@batijs/ts-rest/files/$package.json.js +10 -7
  85. package/dist/boilerplates/@batijs/vercel/files/$package.json.js +10 -7
  86. package/dist/boilerplates/@batijs/vercel/files/$tsconfig.json.js +8 -3
  87. package/dist/boilerplates/@batijs/vercel/files/$vite.config.ts.js +10 -4
  88. package/dist/boilerplates/@batijs/vue/files/$README.md.js +8 -3
  89. package/dist/boilerplates/@batijs/vue/files/$package.json.js +11 -8
  90. package/dist/boilerplates/@batijs/vue/files/$tsconfig.json.js +8 -3
  91. package/dist/boilerplates/@batijs/vue/files/$vite.config.ts.js +11 -5
  92. package/dist/boilerplates/@batijs/vue-sentry/files/$package.json.js +10 -7
  93. package/dist/boilerplates/boilerplates.json +4 -2
  94. package/dist/chunk-LU7IBQI7.js +39 -0
  95. package/dist/chunk-ZPMGCQ2D.js +202555 -0
  96. package/dist/index.js +851 -66
  97. package/dist/lib-NAFETZUN-TE4QDL3A.js +28258 -0
  98. package/package.json +5 -5
  99. package/dist/boilerplates/@batijs/auth0/files/global.d.ts +0 -11
package/dist/index.js CHANGED
@@ -3,6 +3,15 @@ import {
3
3
  colors,
4
4
  consola
5
5
  } from "./chunk-FWD3UPBV.js";
6
+ import {
7
+ OWr,
8
+ Tps,
9
+ ULe,
10
+ export_which,
11
+ jtt,
12
+ qrs
13
+ } from "./chunk-ZPMGCQ2D.js";
14
+ import "./chunk-LU7IBQI7.js";
6
15
 
7
16
  // index.ts
8
17
  import { existsSync as existsSync2, rmSync } from "node:fs";
@@ -15,21 +24,18 @@ import { fileURLToPath } from "node:url";
15
24
  import { existsSync } from "node:fs";
16
25
  import { mkdir, opendir, rm, rmdir, writeFile } from "node:fs/promises";
17
26
  import path from "node:path";
18
- import "@batijs/core";
19
- import { transformAndFormat as transformAndFormat2 } from "@batijs/core";
20
27
  import { readFile } from "node:fs/promises";
21
28
  import { relative } from "node:path";
22
- import { parseModule, transformAndFormat } from "@batijs/core";
23
29
  import { parse } from "path";
24
- import { formatCode } from "@batijs/core";
30
+ import { extname } from "node:path";
25
31
  async function mergeDts({
26
32
  fileContent,
27
33
  previousContent,
28
34
  filepath,
29
35
  meta
30
36
  }) {
31
- const previousAst = parseModule(previousContent);
32
- const currentAst = parseModule(fileContent);
37
+ const previousAst = ULe(previousContent);
38
+ const currentAst = ULe(fileContent);
33
39
  for (const imp of previousAst.imports.$items) {
34
40
  currentAst.imports[imp.local] = imp;
35
41
  }
@@ -46,7 +52,7 @@ async function mergeDts({
46
52
  currentAst.$ast.body.splice(index, 0, node);
47
53
  }
48
54
  }
49
- const res = await transformAndFormat(currentAst.generate().code, meta, {
55
+ const res = await qrs(currentAst.generate().code, meta, {
50
56
  filepath
51
57
  });
52
58
  return res.code;
@@ -57,7 +63,7 @@ async function executeOperationFile(op, {
57
63
  }) {
58
64
  const code = await readFile(op.sourceAbsolute, { encoding: "utf-8" });
59
65
  const filepath = relative(op.source, op.sourceAbsolute);
60
- const result = await transformAndFormat2(code, meta, {
66
+ const result = await qrs(code, meta, {
61
67
  filepath
62
68
  });
63
69
  let fileContent = result.code;
@@ -85,7 +91,7 @@ async function transformFileAfterExec(filepath, fileContent) {
85
91
  case ".js":
86
92
  case ".tsx":
87
93
  case ".jsx":
88
- return formatCode(fileContent, {
94
+ return jtt(fileContent, {
89
95
  filepath
90
96
  });
91
97
  case ".env":
@@ -180,6 +186,77 @@ Please report this issue to https://github.com/vikejs/bati`);
180
186
  }
181
187
  }
182
188
  };
189
+ var RelationFile = class _RelationFile {
190
+ constructor(pathAbsolute, includeIfImported) {
191
+ this.pathAbsolute = pathAbsolute;
192
+ this.includeIfImported = includeIfImported;
193
+ _RelationFile.allPathAbsolute.set(pathAbsolute, this);
194
+ if (includeIfImported) {
195
+ _RelationFile.allIncludeIfImported.push(this);
196
+ }
197
+ }
198
+ static allPathAbsolute = /* @__PURE__ */ new Map();
199
+ static allIncludeIfImported = [];
200
+ };
201
+ var RelationImport = class _RelationImport {
202
+ constructor(source, importTarget) {
203
+ this.source = source;
204
+ this.importTarget = importTarget;
205
+ _RelationImport.allImports.push(this);
206
+ }
207
+ static allImports = [];
208
+ get importTargetRelationFile() {
209
+ const potentialTargets = importToPotentialTargets(this.importTarget);
210
+ for (const target of potentialTargets) {
211
+ if (RelationFile.allPathAbsolute.has(target)) {
212
+ return RelationFile.allPathAbsolute.get(target);
213
+ }
214
+ }
215
+ }
216
+ static computeUnimportedFiles() {
217
+ const unimportedFiles = [];
218
+ const importedByVolatileFile = [];
219
+ for (const file of RelationFile.allIncludeIfImported) {
220
+ const importedFile = _RelationImport.allImports.find((ai) => ai.importTargetRelationFile === file);
221
+ if (!importedFile) {
222
+ unimportedFiles.push(file);
223
+ } else if (importedFile.source.includeIfImported) {
224
+ importedByVolatileFile.push(importedFile);
225
+ }
226
+ }
227
+ return computeDeepUnimportedFiles(importedByVolatileFile, unimportedFiles);
228
+ }
229
+ };
230
+ function computeDeepUnimportedFiles(importedByVolatileFile, unimportedFiles) {
231
+ const copyImportedByVolatileFile = Array.from(importedByVolatileFile);
232
+ let redo = false;
233
+ for (const relationImport of copyImportedByVolatileFile) {
234
+ const found = unimportedFiles.find((uf) => uf === relationImport.source);
235
+ if (found) {
236
+ redo = true;
237
+ unimportedFiles.push(relationImport.importTargetRelationFile);
238
+ importedByVolatileFile = importedByVolatileFile.filter((i) => i !== relationImport);
239
+ }
240
+ }
241
+ if (redo) {
242
+ computeDeepUnimportedFiles(importedByVolatileFile, unimportedFiles);
243
+ }
244
+ return unimportedFiles;
245
+ }
246
+ function importToPotentialTargets(imp) {
247
+ let subject = imp;
248
+ const ext = extname(imp);
249
+ const targets = [];
250
+ if (ext.match(/^\.[jt]sx?$/)) {
251
+ subject = subject.replace(/^\.[jt]sx?$/, "");
252
+ }
253
+ if (!ext || subject !== imp) {
254
+ targets.push(...[".js", ".jsx", ".ts", ".tsx", ".cjs", ".mjs"].map((e) => `${subject}${e}`));
255
+ } else {
256
+ targets.push(imp);
257
+ }
258
+ return targets;
259
+ }
183
260
  var reIgnoreFile = /^(chunk-|asset-|#)/gi;
184
261
  function toDist(filepath, source, dist) {
185
262
  const split = filepath.split(path.sep);
@@ -223,32 +300,16 @@ async function* walk(dir) {
223
300
  } else if (d.isFile()) yield entry;
224
301
  }
225
302
  }
226
- function importToPotentialTargets(imp) {
227
- let subject = imp;
228
- const ext = path.extname(imp);
229
- const targets = [];
230
- if (ext.match(/^\.[jt]sx?$/)) {
231
- subject = subject.replace(/^\.[jt]sx?$/, "");
232
- }
233
- if (!ext || subject !== imp) {
234
- targets.push(...[".js", ".jsx", ".ts", ".tsx", ".cjs", ".mjs"].map((e) => `${subject}${e}`));
235
- } else {
236
- targets.push(imp);
237
- }
238
- return targets;
239
- }
240
303
  async function main(options, meta) {
241
304
  const sources = Array.isArray(options.source) ? options.source : [options.source];
242
- const allImports = /* @__PURE__ */ new Set();
305
+ const allImports = /* @__PURE__ */ new Map();
243
306
  const filesContainingIncludeIfImported = /* @__PURE__ */ new Set();
244
- function updateAllImports(target, imports) {
307
+ function updateAllImports(target, imports, includeIfImported) {
308
+ const rf = new RelationFile(target, includeIfImported);
245
309
  if (!imports) return;
246
310
  for (const imp of imports.values()) {
247
311
  const importTarget = path.resolve(path.dirname(target), imp);
248
- const importTargets = importToPotentialTargets(importTarget);
249
- for (const imp2 of importTargets) {
250
- allImports.add(imp2);
251
- }
312
+ new RelationImport(rf, importTarget);
252
313
  }
253
314
  }
254
315
  const rearranger = new OperationsRearranger();
@@ -298,7 +359,11 @@ Please report this issue to https://github.com/vikejs/bati`
298
359
  meta,
299
360
  previousOperationSameDestination: previousOp
300
361
  });
301
- updateAllImports(op.destinationAbsolute, report.context?.imports);
362
+ updateAllImports(
363
+ op.destinationAbsolute,
364
+ report.context?.imports,
365
+ Boolean(report.context?.flags.has("include-if-imported"))
366
+ );
302
367
  } else if (op.kind === "transform") {
303
368
  report = await executeOperationTransform(op, {
304
369
  meta,
@@ -308,25 +373,746 @@ Please report this issue to https://github.com/vikejs/bati`
308
373
  if (report.content) {
309
374
  await safeWriteFile(op.destination, report.content.trimStart());
310
375
  }
311
- if (report.context?.flags.has("include-if-imported")) {
312
- filesContainingIncludeIfImported.add(op.destinationAbsolute);
313
- }
314
376
  previousOp = {
315
377
  ...op,
316
378
  ...report
317
379
  };
318
380
  }
319
- for (const target of filesContainingIncludeIfImported) {
320
- if (!allImports.has(target)) {
321
- await safeRmFile(target, { removeEmptyDir: true });
322
- }
381
+ for (const target of RelationImport.computeUnimportedFiles()) {
382
+ await safeRmFile(target.pathAbsolute, { removeEmptyDir: true });
323
383
  }
324
384
  }
325
385
 
326
- // index.ts
327
- import { packageManager, which, withIcon } from "@batijs/core";
328
- import { BatiSet, cliFlags, features } from "@batijs/features";
329
- import { execRules } from "@batijs/features/rules";
386
+ // ../features/dist/chunk-BYAQKFAS.js
387
+ var features = [
388
+ // Vike
389
+ {
390
+ category: "Frontend Framework",
391
+ label: "Vike",
392
+ flag: "vike",
393
+ image: "data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iaGFtbWVyIiB3aWR0aD0iNDcuMjE3IiBoZWlnaHQ9IjQ3LjIxNyIgdmVyc2lvbj0iMS4xIiB2aWV3Qm94PSItNTAgLTUwIDQ3LjIxNyA0Ny4yMTciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzAuMjksLTIxLjMpIj4KICA8ZyBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPgogICA8cGF0aCBkPSJtLTguNTExLTEwLjQ0OSAxLjEyNiA0LjA2NCAyLjcwNy0yLjc2NXoiIGZpbGw9IiNhYmFiYWIiLz4KICAgPHBhdGggZD0ibS0yLjI3My0yNC40OTYtNi4yMzggMTQuMDQ3IDMuODMzIDEuMjk5IDYuMjM4LTE0LjA0OHoiIGZpbGw9IiM5NDk0OTQiLz4KICAgPHBhdGggZD0ibS0yLjI3My0yNC40OTYgMy40NjUtMS4yMDQuMzY4IDIuNTAyeiIgZmlsbD0iI2FiYWJhYiIvPgogICA8cGF0aCBkPSJtMTcuNTExIDQuNjc0LTIuNzA3IDIuNzY2LTIyLjE4OS0xMy44MjUgMi43MDctMi43NjV6IiBmaWxsPSIjOTQ5NDk0Ii8+CiAgPC9nPgogIDxnIHN0cm9rZT0iIzgyODI4MiI+CiAgIDxwYXRoIGQ9Im0tMTAuNTI2IDIzLjcwNS0xLjE3IDIuNjM0IiBzdHJva2Utd2lkdGg9IjkuNiIvPgogICA8cGF0aCBkPSJtLTEzLjg5OSAyNi41MjhjLTEuODUxLTEuMTUzLTIuMzI2LTIuMTMzLTEuMDg3LTIuMjM5IDEuMjQtLjEwNiAzLjY0My43MDkgNS40OTQgMS44NjIgMS44NSAxLjE1MyAyLjMyNiAyLjEzMiAxLjA4NiAyLjIzOC0xLjIzOS4xMDYtMy42NDItLjcwOC01LjQ5My0xLjg2MSIgZmlsbD0iIzgyODI4MiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CiAgIDxwYXRoIGQ9Im0tMTIuNzMgMjMuODk0YzEuODUxIDEuMTUzIDQuMjU1IDEuOTY3IDUuNDk0IDEuODYxcy43NjQtMS4wODUtMS4wODctMi4yMzhjLTEuODUtMS4xNTMtNC4yNTQtMS45NjctNS40OTMtMS44NjEtMS4yNC4xMDYtLjc2NCAxLjA4NSAxLjA4NiAyLjIzOCIgZmlsbD0iIzgyODI4MiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CiAgPC9nPgogIDxnIHN0cm9rZT0iIzdhN2E3YSI+CiAgIDxwYXRoIGQ9Im0tOS44NDQgMjIuMTY5LS4zOS44NzgiIHN0cm9rZS13aWR0aD0iOS4xIi8+CiAgIDxwYXRoIGQ9Im0tMTIuNDM3IDIzLjIzNWMtMS44NTEtMS4xNTMtMi4zMjYtMi4xMzItMS4wODctMi4yMzggMS4yNC0uMTA2IDMuNjQzLjcwOCA1LjQ5NCAxLjg2MSAxLjg1IDEuMTUzIDIuMzI2IDIuMTMzIDEuMDg2IDIuMjM5LTEuMjM5LjEwNi0zLjY0Mi0uNzA5LTUuNDkzLTEuODYyIiBmaWxsPSIjN2E3YTdhIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iLjUiLz4KICAgPHBhdGggZD0ibS0xMi4wNDcgMjIuMzU3YzEuODUgMS4xNTMgNC4yNTQgMS45NjggNS40OTMgMS44NjIgMS4yNC0uMTA2Ljc2NC0xLjA4Ni0xLjA4Ny0yLjIzOS0xLjg1LTEuMTUzLTQuMjU0LTEuOTY3LTUuNDkzLTEuODYxcy0uNzY0IDEuMDg1IDEuMDg3IDIuMjM4IiBmaWxsPSIjN2E3YTdhIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iLjUiLz4KICA8L2c+CiAgPGcgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj4KICAgPHBhdGggZD0ibS0xNi43MS05Ljc0OCA4LjE5OS0uNzAxIDEuMTI2IDQuMDY0LTguMTk5LjcwMXoiIGZpbGw9IiM5NDk0OTQiLz4KICAgPHBhdGggZD0ibTIzLjc0OS05LjM3My02LjIzOCAxNC4wNDctMjIuMTg5LTEzLjgyNCA2LjIzOC0xNC4wNDh6IiBmaWxsPSIjNzU3NTc1Ii8+CiAgIDxwYXRoIGQ9Im0xMC4yNzEtMTYuMDczIDMuNzUxIDMuNTM0Yy4wNjIuMDU4LjA4My4xNTYuMDUyLjIzOGwtMS45NSA1LjEyOGMtLjA0Ni4xMjEtLjE4LjE1My0uMjY4LjA2NWwtMS4wMjQtMS4wM2MtLjA5NS0uMDk2LS4yNDItLjA0OC0uMjc1LjA5MWwtLjUxNiAyLjE1MmMtLjAzNC4xNDUtLjE5MS4xOS0uMjg0LjA4MiAwIDAtLjYwNi0uNjk2LS42MDYtLjY5Ni0uMDk0LS4xMDgtLjI1LS4wNjMtLjI4NS4wODJsLS44MDMgMy4zODRjLS4wNS4yMTItLjMxNy4xNzgtLjMzNi0uMDQzbC0uMDE0LS4xNDdzLjA1OC05Ljg5Mi4wNTgtOS44OTJjLjAwMS0uMTY1LjE2NS0uMjUzLjI3Ny0uMTQ4bDEuMDc3IDEuMDA5Yy4xMDEuMDk1LjI1LjAzNC4yNzQtLjExMWwuNTk3LTMuNTg3Yy4wMjUtLjE0Ni4xNzQtLjIwNi4yNzUtLjExMXoiIGZpbGw9IiNmYmJmMjgiIHN0cm9rZT0iI2ZiYmYyOCIgc3Ryb2tlLXdpZHRoPSIuNiIvPgogICA8cGF0aCBkPSJtLTE2LjcxLTkuNzQ4IDguMTk5LS43MDEgNi4yMzgtMTQuMDQ3LTguMTk5LjcwMXoiIGZpbGw9IiM3NTc1NzUiLz4KICA8L2c+CiAgPHBhdGggZD0ibS0xLjc1NCAzLjk1MS03Ljk5MiAxNy45OTgiIHN0cm9rZT0iIzkxNTEyYiIgc3Ryb2tlLXdpZHRoPSI4LjYiLz4KICA8ZyBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPgogICA8cGF0aCBkPSJtLTExLjk1IDIyLjEzOGMtMS44NTEtMS4xNTMtMi4zMjYtMi4xMzItMS4wODctMi4yMzggMS4yNC0uMTA2IDMuNjQzLjcwOCA1LjQ5NCAxLjg2MXMyLjMyNiAyLjEzMiAxLjA4NyAyLjIzOGMtMS4yNC4xMDYtMy42NDMtLjcwOC01LjQ5NC0xLjg2MSIgZmlsbD0iIzkxNTEyYiIvPgogICA8cGF0aCBkPSJtLTMuOTU4IDQuMTM5YzEuODUxIDEuMTUzIDQuMjU0IDEuOTY4IDUuNDk0IDEuODYyIDEuMjM5LS4xMDYuNzY0LTEuMDg2LTEuMDg3LTIuMjM5cy00LjI1NC0xLjk2Ny01LjQ5My0xLjg2MWMtMS4yNC4xMDYtLjc2NCAxLjA4NSAxLjA4NiAyLjIzOCIgZmlsbD0iIzkxNTEyYiIvPgogICA8cGF0aCBkPSJtMS4xOTItMjUuNy4zNjggMi41MDIgMjIuMTg5IDEzLjgyNS0uMzY4LTIuNTAzeiIgZmlsbD0iIzk0OTQ5NCIvPgogICA8cGF0aCBkPSJtLTEwLjQ3Mi0yMy43OTUgOC4xOTktLjcwMSAzLjQ2NS0xLjIwNC04LjE5OS43MDF6IiBmaWxsPSIjOTQ5NDk0Ii8+CiAgPC9nPgogIDxnIHN0cm9rZT0iIzZlNmU2ZSI+CiAgIDxwYXRoIGQ9Im0tLjQ4NyAxLjA5Ny0xLjE3IDIuNjM0IiBzdHJva2Utd2lkdGg9IjkuMSIvPgogICA8cGF0aCBkPSJtLTMuODYgMy45MmMtMS44NTEtMS4xNTMtMi4zMjYtMi4xMzItMS4wODctMi4yMzhzMy42NDMuNzA4IDUuNDkzIDEuODYxYzEuODUxIDEuMTUzIDIuMzI3IDIuMTMyIDEuMDg3IDIuMjM4LTEuMjM5LjEwNi0zLjY0My0uNzA4LTUuNDkzLTEuODYxIiBmaWxsPSIjNmU2ZTZlIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iLjUiLz4KICAgPHBhdGggZD0ibS0yLjY5MSAxLjI4NmMxLjg1MSAxLjE1MyA0LjI1NCAxLjk2NyA1LjQ5NCAxLjg2MSAxLjIzOS0uMTA2Ljc2NC0xLjA4NS0xLjA4Ny0yLjIzOHMtNC4yNTQtMS45NjctNS40OTMtMS44NjFjLTEuMjQuMTA2LS43NjQgMS4wODUgMS4wODYgMi4yMzgiIGZpbGw9IiM2ZTZlNmUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIuNSIvPgogIDwvZz4KICA8ZyBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPgogICA8cGF0aCBkPSJtMTguMjY5IDYuMjM2LTMuNDY1IDEuMjA0IDIuNzA3LTIuNzY2eiIgZmlsbD0iI2FiYWJhYiIvPgogICA8cGF0aCBkPSJtMTQuODA0IDcuNDQtOC4xOTkuNzAxLTIyLjE4OS0xMy44MjUgOC4xOTktLjcwMXoiIGZpbGw9IiM3NTc1NzUiLz4KICAgPHBhdGggZD0ibS0xNi43MS05Ljc0OCAxLjEyNiA0LjA2NC0uMzY3LTIuNTAyeiIgZmlsbD0iI2FiYWJhYiIvPgogICA8cGF0aCBkPSJtMjQuNTA3LTcuODEyLTYuMjM4IDE0LjA0OC0uNzU4LTEuNTYyIDYuMjM4LTE0LjA0N3oiIGZpbGw9IiM5NDk0OTQiLz4KICAgPHBhdGggZD0ibS0xMC40NzItMjMuNzk1LTYuMjM4IDE0LjA0Ny43NTkgMS41NjIgNi4yMzctMTQuMDQ4eiIgZmlsbD0iIzk0OTQ5NCIvPgogICA8cGF0aCBkPSJtMjQuNTA3LTcuODEyLTEuMTI2LTQuMDY0LjM2OCAyLjUwM3oiIGZpbGw9IiNhYmFiYWIiLz4KICAgPHBhdGggZD0ibTIzLjM4MS0xMS44NzYtOC4xOTkuNzAxLTIyLjE4OS0xMy44MjQgOC4xOTktLjcwMXoiIGZpbGw9IiM3NTc1NzUiLz4KICAgPHBhdGggZD0ibS0xMC40NzItMjMuNzk1IDMuNDY1LTEuMjA0LTIuNzA3IDIuNzY1eiIgZmlsbD0iI2FiYWJhYiIvPgogICA8cGF0aCBkPSJtMTguMjY5IDYuMjM2LTguMTk5LjcwMS0zLjQ2NSAxLjIwNCA4LjE5OS0uNzAxeiIgZmlsbD0iIzk0OTQ5NCIvPgogICA8cGF0aCBkPSJtLTE1Ljk1MS04LjE4Ni4zNjcgMi41MDIgMjIuMTg5IDEzLjgyNS0uMzY3LTIuNTAzeiIgZmlsbD0iIzk0OTQ5NCIvPgogICA8cGF0aCBkPSJtMTguMjY5IDYuMjM2LTguMTk5LjcwMSA2LjIzOC0xNC4wNDggOC4xOTktLjcwMXoiIGZpbGw9IiM3NTc1NzUiLz4KICAgPHBhdGggZD0ibS05LjcxNC0yMi4yMzQtNi4yMzcgMTQuMDQ4IDIyLjE4OSAxMy44MjQgNi4yMzctMTQuMDQ3eiIgZmlsbD0iIzc1NzU3NSIvPgogICA8cGF0aCBkPSJtMi41NDUtMTIuNzktNC41ODMtMS42NTljLS4wNzYtLjAyNy0uMTU2LjAwOC0uMTk1LjA4NSAwIDAtMi40NjMgNC44MDgtMi40NjMgNC44MDgtLjA1OC4xMTQtLjAwNS4yNjMuMTA3LjI5OGwxLjI5Ni40MTZjLjEyMi4wMzkuMTcxLjIxLjA5My4zMjEgMCAwLTEuMjA1IDEuNzIyLTEuMjA1IDEuNzIyLS4wODEuMTE2LS4wMjQuMjk0LjEwNS4zMjVsLjgyNy4xOTZjLjEyOC4wMzEuMTg2LjIwOS4xMDQuMzI1IDAgMC0xLjg5OSAyLjcwMS0xLjg5OSAyLjcwMS0uMTE4LjE2OS4wNTYuNDEuMjIuMzA0bC4xMS0uMDcgNi44NDktNS42NjFjLjExNS0uMDk1LjA4My0uMzA0LS4wNTQtLjM1NGwtMS4zMTItLjQ4Yy0uMTIzLS4wNDUtLjE2NS0uMjI0LS4wNzgtLjMzMSAwIDAgMi4xNTctMi42MTUgMi4xNTctMi42MTUuMDg3LS4xMDYuMDQ1LS4yODYtLjA3OS0uMzMxeiIgZmlsbD0iI2ZiYmYyOCIgc3Ryb2tlPSIjZmJiZjI4IiBzdHJva2Utd2lkdGg9Ii42Ii8+CiAgIDxwYXRoIGQ9Im0yNC41MDctNy44MTItOC4xOTkuNzAxLTEuMTI2LTQuMDY0IDguMTk5LS43MDF6IiBmaWxsPSIjOTQ5NDk0Ii8+CiAgIDxwYXRoIGQ9Im0xNS4xODItMTEuMTc1LTIuNzA3IDIuNzY2LTIyLjE4OS0xMy44MjUgMi43MDctMi43NjV6IiBmaWxsPSIjOTQ5NDk0Ii8+CiAgIDxwYXRoIGQ9Im0xMC4wNyA2LjkzNy0zLjQ2NSAxLjIwNC0uMzY3LTIuNTAzeiIgZmlsbD0iI2FiYWJhYiIvPgogICA8cGF0aCBkPSJtMTYuMzA4LTcuMTExLTYuMjM4IDE0LjA0OC0zLjgzMi0xLjI5OSA2LjIzNy0xNC4wNDd6IiBmaWxsPSIjOTQ5NDk0Ii8+CiAgIDxwYXRoIGQ9Im0xNi4zMDgtNy4xMTEtMS4xMjYtNC4wNjQtMi43MDcgMi43NjZ6IiBmaWxsPSIjYWJhYmFiIi8+CiAgPC9nPgogPC9nPgo8L3N2Zz4K",
394
+ url: "https://vike.dev",
395
+ tagline: "Flexible, lean, reliable, community-driven, fast Vite-based frontend framework",
396
+ repo: "vikejs/vike",
397
+ links: [
398
+ {
399
+ label: "Docs",
400
+ href: "https://vike.dev"
401
+ },
402
+ {
403
+ label: "FAQ",
404
+ href: "https://vike.dev/faq"
405
+ }
406
+ ],
407
+ invisibleCli: true,
408
+ readonly: true
409
+ },
410
+ // UI Framework
411
+ {
412
+ category: "UI Framework",
413
+ label: "React",
414
+ flag: "react",
415
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxLjEzZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjU2IDIyOCI+PHBhdGggZmlsbD0iIzAwRDhGRiIgZD0iTTIxMC40ODMgNzMuODI0YTE3MS40OSAxNzEuNDkgMCAwIDAtOC4yNC0yLjU5N2MuNDY1LTEuOS44OTMtMy43NzcgMS4yNzMtNS42MjFjNi4yMzgtMzAuMjgxIDIuMTYtNTQuNjc2LTExLjc2OS02Mi43MDhjLTEzLjM1NS03LjctMzUuMTk2LjMyOS01Ny4yNTQgMTkuNTI2YTE3MS4yMyAxNzEuMjMgMCAwIDAtNi4zNzUgNS44NDhhMTU1Ljg2NiAxNTUuODY2IDAgMCAwLTQuMjQxLTMuOTE3QzEwMC43NTkgMy44MjkgNzcuNTg3LTQuODIyIDYzLjY3MyAzLjIzM0M1MC4zMyAxMC45NTcgNDYuMzc5IDMzLjg5IDUxLjk5NSA2Mi41ODhhMTcwLjk3NCAxNzAuOTc0IDAgMCAwIDEuODkyIDguNDhjLTMuMjguOTMyLTYuNDQ1IDEuOTI0LTkuNDc0IDIuOThDMTcuMzA5IDgzLjQ5OCAwIDk4LjMwNyAwIDExMy42NjhjMCAxNS44NjUgMTguNTgyIDMxLjc3OCA0Ni44MTIgNDEuNDI3YTE0NS41MiAxNDUuNTIgMCAwIDAgNi45MjEgMi4xNjVhMTY3LjQ2NyAxNjcuNDY3IDAgMCAwLTIuMDEgOS4xMzhjLTUuMzU0IDI4LjItMS4xNzMgNTAuNTkxIDEyLjEzNCA1OC4yNjZjMTMuNzQ0IDcuOTI2IDM2LjgxMi0uMjIgNTkuMjczLTE5Ljg1NWExNDUuNTY3IDE0NS41NjcgMCAwIDAgNS4zNDItNC45MjNhMTY4LjA2NCAxNjguMDY0IDAgMCAwIDYuOTIgNi4zMTRjMjEuNzU4IDE4LjcyMiA0My4yNDYgMjYuMjgyIDU2LjU0IDE4LjU4NmMxMy43MzEtNy45NDkgMTguMTk0LTMyLjAwMyAxMi40LTYxLjI2OGExNDUuMDE2IDE0NS4wMTYgMCAwIDAtMS41MzUtNi44NDJjMS42Mi0uNDggMy4yMS0uOTc0IDQuNzYtMS40ODhjMjkuMzQ4LTkuNzIzIDQ4LjQ0My0yNS40NDMgNDguNDQzLTQxLjUyYzAtMTUuNDE3LTE3Ljg2OC0zMC4zMjYtNDUuNTE3LTM5Ljg0NFptLTYuMzY1IDcwLjk4NGMtMS40LjQ2My0yLjgzNi45MS00LjMgMS4zNDVjLTMuMjQtMTAuMjU3LTcuNjEyLTIxLjE2My0xMi45NjMtMzIuNDMyYzUuMTA2LTExIDkuMzEtMjEuNzY3IDEyLjQ1OS0zMS45NTdjMi42MTkuNzU4IDUuMTYgMS41NTcgNy42MSAyLjRjMjMuNjkgOC4xNTYgMzguMTQgMjAuMjEzIDM4LjE0IDI5LjUwNGMwIDkuODk2LTE1LjYwNiAyMi43NDMtNDAuOTQ2IDMxLjE0Wm0tMTAuNTE0IDIwLjgzNGMyLjU2MiAxMi45NCAyLjkyNyAyNC42NCAxLjIzIDMzLjc4N2MtMS41MjQgOC4yMTktNC41OSAxMy42OTgtOC4zODIgMTUuODkzYy04LjA2NyA0LjY3LTI1LjMyLTEuNC00My45MjctMTcuNDEyYTE1Ni43MjYgMTU2LjcyNiAwIDAgMS02LjQzNy01Ljg3YzcuMjE0LTcuODg5IDE0LjQyMy0xNy4wNiAyMS40NTktMjcuMjQ2YzEyLjM3Ni0xLjA5OCAyNC4wNjgtMi44OTQgMzQuNjcxLTUuMzQ1YTEzNC4xNyAxMzQuMTcgMCAwIDEgMS4zODYgNi4xOTNaTTg3LjI3NiAyMTQuNTE1Yy03Ljg4MiAyLjc4My0xNC4xNiAyLjg2My0xNy45NTUuNjc1Yy04LjA3NS00LjY1Ny0xMS40MzItMjIuNjM2LTYuODUzLTQ2Ljc1MmExNTYuOTIzIDE1Ni45MjMgMCAwIDEgMS44NjktOC40OTljMTAuNDg2IDIuMzIgMjIuMDkzIDMuOTg4IDM0LjQ5OCA0Ljk5NGM3LjA4NCA5Ljk2NyAxNC41MDEgMTkuMTI4IDIxLjk3NiAyNy4xNWExMzQuNjY4IDEzNC42NjggMCAwIDEtNC44NzcgNC40OTJjLTkuOTMzIDguNjgyLTE5Ljg4NiAxNC44NDItMjguNjU4IDE3Ljk0Wk01MC4zNSAxNDQuNzQ3Yy0xMi40ODMtNC4yNjctMjIuNzkyLTkuODEyLTI5Ljg1OC0xNS44NjNjLTYuMzUtNS40MzctOS41NTUtMTAuODM2LTkuNTU1LTE1LjIxNmMwLTkuMzIyIDEzLjg5Ny0yMS4yMTIgMzcuMDc2LTI5LjI5M2MyLjgxMy0uOTggNS43NTctMS45MDUgOC44MTItMi43NzNjMy4yMDQgMTAuNDIgNy40MDYgMjEuMzE1IDEyLjQ3NyAzMi4zMzJjLTUuMTM3IDExLjE4LTkuMzk5IDIyLjI0OS0xMi42MzQgMzIuNzkyYTEzNC43MTggMTM0LjcxOCAwIDAgMS02LjMxOC0xLjk3OVptMTIuMzc4LTg0LjI2Yy00LjgxMS0yNC41ODctMS42MTYtNDMuMTM0IDYuNDI1LTQ3Ljc4OWM4LjU2NC00Ljk1OCAyNy41MDIgMi4xMTEgNDcuNDYzIDE5LjgzNWExNDQuMzE4IDE0NC4zMTggMCAwIDEgMy44NDEgMy41NDVjLTcuNDM4IDcuOTg3LTE0Ljc4NyAxNy4wOC0yMS44MDggMjYuOTg4Yy0xMi4wNCAxLjExNi0yMy41NjUgMi45MDgtMzQuMTYxIDUuMzA5YTE2MC4zNDIgMTYwLjM0MiAwIDAgMS0xLjc2LTcuODg3Wm0xMTAuNDI3IDI3LjI2OGEzNDcuOCAzNDcuOCAwIDAgMC03Ljc4NS0xMi44MDNjOC4xNjggMS4wMzMgMTUuOTk0IDIuNDA0IDIzLjM0MyA0LjA4Yy0yLjIwNiA3LjA3Mi00Ljk1NiAxNC40NjUtOC4xOTMgMjIuMDQ1YTM4MS4xNTEgMzgxLjE1MSAwIDAgMC03LjM2NS0xMy4zMjJabS00NS4wMzItNDMuODYxYzUuMDQ0IDUuNDY1IDEwLjA5NiAxMS41NjYgMTUuMDY1IDE4LjE4NmEzMjIuMDQgMzIyLjA0IDAgMCAwLTMwLjI1Ny0uMDA2YzQuOTc0LTYuNTU5IDEwLjA2OS0xMi42NTIgMTUuMTkyLTE4LjE4Wk04Mi44MDIgODcuODNhMzIzLjE2NyAzMjMuMTY3IDAgMCAwLTcuMjI3IDEzLjIzOGMtMy4xODQtNy41NTMtNS45MDktMTQuOTgtOC4xMzQtMjIuMTUyYzcuMzA0LTEuNjM0IDE1LjA5My0yLjk3IDIzLjIwOS0zLjk4NGEzMjEuNTI0IDMyMS41MjQgMCAwIDAtNy44NDggMTIuODk3Wm04LjA4MSA2NS4zNTJjLTguMzg1LS45MzYtMTYuMjkxLTIuMjAzLTIzLjU5My0zLjc5M2MyLjI2LTcuMyA1LjA0NS0xNC44ODUgOC4yOTgtMjIuNmEzMjEuMTg3IDMyMS4xODcgMCAwIDAgNy4yNTcgMTMuMjQ2YzIuNTk0IDQuNDggNS4yOCA4Ljg2OCA4LjAzOCAxMy4xNDdabTM3LjU0MiAzMS4wM2MtNS4xODQtNS41OTItMTAuMzU0LTExLjc3OS0xNS40MDMtMTguNDMzYzQuOTAyLjE5MiA5Ljg5OS4yOSAxNC45NzguMjljNS4yMTggMCAxMC4zNzYtLjExNyAxNS40NTMtLjM0M2MtNC45ODUgNi43NzQtMTAuMDE4IDEyLjk3LTE1LjAyOCAxOC40ODZabTUyLjE5OC01Ny44MTdjMy40MjIgNy44IDYuMzA2IDE1LjM0NSA4LjU5NiAyMi41MmMtNy40MjIgMS42OTQtMTUuNDM2IDMuMDU4LTIzLjg4IDQuMDcxYTM4Mi40MTcgMzgyLjQxNyAwIDAgMCA3Ljg1OS0xMy4wMjZhMzQ3LjQwMyAzNDcuNDAzIDAgMCAwIDcuNDI1LTEzLjU2NVptLTE2Ljg5OCA4LjEwMWEzNTguNTU3IDM1OC41NTcgMCAwIDEtMTIuMjgxIDE5LjgxNWEzMjkuNCAzMjkuNCAwIDAgMS0yMy40NDQuODIzYy03Ljk2NyAwLTE1LjcxNi0uMjQ4LTIzLjE3OC0uNzMyYTMxMC4yMDIgMzEwLjIwMiAwIDAgMS0xMi41MTMtMTkuODQ2aC4wMDFhMzA3LjQxIDMwNy40MSAwIDAgMS0xMC45MjMtMjAuNjI3YTMxMC4yNzggMzEwLjI3OCAwIDAgMSAxMC44OS0yMC42MzdsLS4wMDEuMDAxYTMwNy4zMTggMzA3LjMxOCAwIDAgMSAxMi40MTMtMTkuNzYxYzcuNjEzLS41NzYgMTUuNDItLjg3NiAyMy4zMS0uODc2SDEyOGM3LjkyNiAwIDE1Ljc0My4zMDMgMjMuMzU0Ljg4M2EzMjkuMzU3IDMyOS4zNTcgMCAwIDEgMTIuMzM1IDE5LjY5NWEzNTguNDg5IDM1OC40ODkgMCAwIDEgMTEuMDM2IDIwLjU0YTMyOS40NzIgMzI5LjQ3MiAwIDAgMS0xMSAyMC43MjJabTIyLjU2LTEyMi4xMjRjOC41NzIgNC45NDQgMTEuOTA2IDI0Ljg4MSA2LjUyIDUxLjAyNmMtLjM0NCAxLjY2OC0uNzMgMy4zNjctMS4xNSA1LjA5Yy0xMC42MjItMi40NTItMjIuMTU1LTQuMjc1LTM0LjIzLTUuNDA4Yy03LjAzNC0xMC4wMTctMTQuMzIzLTE5LjEyNC0yMS42NC0yNy4wMDhhMTYwLjc4OSAxNjAuNzg5IDAgMCAxIDUuODg4LTUuNGMxOC45LTE2LjQ0NyAzNi41NjQtMjIuOTQxIDQ0LjYxMi0xOC4zWk0xMjggOTAuODA4YzEyLjYyNSAwIDIyLjg2IDEwLjIzNSAyMi44NiAyMi44NnMtMTAuMjM1IDIyLjg2LTIyLjg2IDIyLjg2cy0yMi44Ni0xMC4yMzUtMjIuODYtMjIuODZzMTAuMjM1LTIyLjg2IDIyLjg2LTIyLjg2WiIvPjwvc3ZnPg==",
416
+ url: "https://react.dev",
417
+ spectrum: "beaten_path",
418
+ tagline: "The library for web and native user interfaces",
419
+ repo: "facebook/react",
420
+ selected: true,
421
+ links: [
422
+ {
423
+ label: "Learn",
424
+ href: "https://react.dev/learn"
425
+ },
426
+ {
427
+ label: "Docs",
428
+ href: "https://react.dev/reference/react"
429
+ }
430
+ ]
431
+ },
432
+ {
433
+ category: "UI Framework",
434
+ label: "Vue",
435
+ flag: "vue",
436
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxLjE2ZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjU2IDIyMSI+PHBhdGggZmlsbD0iIzQxQjg4MyIgZD0iTTIwNC44IDBIMjU2TDEyOCAyMjAuOEwwIDBoOTcuOTJMMTI4IDUxLjJMMTU3LjQ0IDBoNDcuMzZaIi8+PHBhdGggZmlsbD0iIzQxQjg4MyIgZD0ibTAgMGwxMjggMjIwLjhMMjU2IDBoLTUxLjJMMTI4IDEzMi40OEw1MC41NiAwSDBaIi8+PHBhdGggZmlsbD0iIzM1NDk1RSIgZD0iTTUwLjU2IDBMMTI4IDEzMy4xMkwyMDQuOCAwaC00Ny4zNkwxMjggNTEuMkw5Ny45MiAwSDUwLjU2WiIvPjwvc3ZnPg==",
437
+ url: "https://vuejs.org",
438
+ tagline: "The Progressive JavaScript Framework",
439
+ repo: "vuejs/core",
440
+ links: [
441
+ {
442
+ label: "Quick start",
443
+ href: "https://vuejs.org/guide/quick-start.html"
444
+ },
445
+ {
446
+ label: "Examples",
447
+ href: "https://vuejs.org/examples/#hello-world"
448
+ },
449
+ {
450
+ label: "API",
451
+ href: "https://vuejs.org/api/"
452
+ }
453
+ ]
454
+ },
455
+ {
456
+ category: "UI Framework",
457
+ label: "SolidJS",
458
+ flag: "solid",
459
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxLjA4ZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIyNTYgMjM5IDI1NiAyMzkiPjxkZWZzPjxsaW5lYXJHcmFkaWVudCBpZD0ibG9nb3NTb2xpZGpzSWNvbjAiIHgxPSIyNy41IiB4Mj0iMTUyIiB5MT0iMyIgeTI9IjYzLjUiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQ5LjU2IDIzMy4xMikgc2NhbGUoMS42MTAwNikiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj48c3RvcCBvZmZzZXQ9Ii4xIiBzdG9wLWNvbG9yPSIjNzZiM2UxIi8+PHN0b3Agb2Zmc2V0PSIuMyIgc3RvcC1jb2xvcj0iI2RjZjJmZCIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzc2YjNlMSIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJsb2dvc1NvbGlkanNJY29uMSIgeDE9Ijk1LjgiIHgyPSI3NCIgeTE9IjMyLjYiIHkyPSIxMDUuMiIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSgyNDkuNTYgMjMzLjEyKSBzY2FsZSgxLjYxMDA2KSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iIzc2YjNlMSIvPjxzdG9wIG9mZnNldD0iLjUiIHN0b3AtY29sb3I9IiM0Mzc3YmIiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMxZjNiNzciLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0ibG9nb3NTb2xpZGpzSWNvbjIiIHgxPSIxOC40IiB4Mj0iMTQ0LjMiIHkxPSI2NC4yIiB5Mj0iMTQ5LjgiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQ5LjU2IDIzMy4xMikgc2NhbGUoMS42MTAwNikiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiMzMTVhYTkiLz48c3RvcCBvZmZzZXQ9Ii41IiBzdG9wLWNvbG9yPSIjNTE4YWM4Ii8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMzE1YWE5Ii8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImxvZ29zU29saWRqc0ljb24zIiB4MT0iNzUuMiIgeDI9IjI0LjQiIHkxPSI3NC41IiB5Mj0iMjYwLjgiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQ5LjU2IDIzMy4xMikgc2NhbGUoMS42MTAwNikiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiM0Mzc3YmIiLz48c3RvcCBvZmZzZXQ9Ii41IiBzdG9wLWNvbG9yPSIjMWEzMzZiIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMWEzMzZiIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHBhdGggZmlsbD0iIzc2YjNlMSIgZD0iTTUxMiAyODkuNDcycy04NS4zMzMtNjIuNzkxLTE1MS4zNDctNDguMzAxbC00LjgyOSAxLjYxYy05LjY2IDMuMjIxLTE3LjcxMSA4LjA1LTIyLjU0MiAxNC40OTFsLTMuMjE5IDQuODI5bC0yNC4xNTIgNDEuODYybDQxLjg2MyA4LjA1MWMxNy43MSAxMS4yNyA0MC4yNTEgMTYuMTAxIDYxLjE4MiAxMS4yN2w3NC4wNjMgMTQuNDkxTDUxMiAyODkuNDcyWiIvPjxwYXRoIGZpbGw9InVybCgjbG9nb3NTb2xpZGpzSWNvbjApIiBkPSJNNTEyIDI4OS40NzJzLTg1LjMzMy02Mi43OTEtMTUxLjM0Ny00OC4zMDFsLTQuODI5IDEuNjFjLTkuNjYgMy4yMjEtMTcuNzExIDguMDUtMjIuNTQyIDE0LjQ5MWwtMy4yMTkgNC44MjlsLTI0LjE1MiA0MS44NjJsNDEuODYzIDguMDUxYzE3LjcxIDExLjI3IDQwLjI1MSAxNi4xMDEgNjEuMTgyIDExLjI3bDc0LjA2MyAxNC40OTFMNTEyIDI4OS40NzJaIiBvcGFjaXR5PSIuMyIvPjxwYXRoIGZpbGw9IiM1MThhYzgiIGQ9Im0zMzMuMjgyIDI4OS40NzJsLTYuNDM5IDEuNjExYy0yNy4zNzEgOC4wNS0zNS40MjEgMzMuODExLTIwLjkzMiA1Ni4zNTJjMTYuMTAxIDIwLjkzMSA0OS45MTMgMzIuMjAxIDc3LjI4NCAyNC4xNTFsOTkuODI0LTMzLjgxMXMtODUuMzM0LTYyLjc5Mi0xNDkuNzM3LTQ4LjMwM1oiLz48cGF0aCBmaWxsPSJ1cmwoI2xvZ29zU29saWRqc0ljb24xKSIgZD0ibTMzMy4yODIgMjg5LjQ3MmwtNi40MzkgMS42MTFjLTI3LjM3MSA4LjA1LTM1LjQyMSAzMy44MTEtMjAuOTMyIDU2LjM1MmMxNi4xMDEgMjAuOTMxIDQ5LjkxMyAzMi4yMDEgNzcuMjg0IDI0LjE1MWw5OS44MjQtMzMuODExcy04NS4zMzQtNjIuNzkyLTE0OS43MzctNDguMzAzWiIgb3BhY2l0eT0iLjMiLz48cGF0aCBmaWxsPSJ1cmwoI2xvZ29zU29saWRqc0ljb24yKSIgZD0iTTQ2NS4zMDggMzYxLjkyNWMtMTguNDM5LTIzLjAzNi00OS4wMDgtMzIuNTg4LTc3LjI4My0yNC4xNWwtOTkuODIzIDMyLjIwMUwyNTYgNDI2LjMyOGwxODAuMzI3IDMwLjU5MmwzMi4yMDEtNTcuOTYzYzYuNDQxLTExLjI3MSA0LjgzMS0yNC4xNS0zLjIyLTM3LjAzMloiLz48cGF0aCBmaWxsPSJ1cmwoI2xvZ29zU29saWRqc0ljb24zKSIgZD0iTTQzMy4xMDYgNDE4LjI3N2MtMTguNDM5LTIzLjAzNi00OS4wMDYtMzIuNTg4LTc3LjI4Mi0yNC4xNUwyNTYgNDI2LjMyOHM4NS4zMzMgNjQuNDAyIDE1MS4zNDYgNDguMzAzbDQuODMtMS42MTJjMjcuMzcxLTguMDQ5IDM3LjAzMS0zMy44MSAyMC45My01NC43NDJaIi8+PC9zdmc+",
460
+ url: "https://www.solidjs.com",
461
+ spectrum: "bleeding_edge",
462
+ tagline: "Simple and performant reactivity for building user interfaces",
463
+ repo: "solidjs/solid",
464
+ links: [
465
+ {
466
+ label: "Getting started",
467
+ href: "https://www.solidjs.com/guides/getting-started"
468
+ },
469
+ {
470
+ label: "Examples",
471
+ href: "https://www.solidjs.com/examples"
472
+ },
473
+ {
474
+ label: "API",
475
+ href: "https://www.solidjs.com/docs/latest/api"
476
+ }
477
+ ]
478
+ },
479
+ // CSS
480
+ {
481
+ category: "CSS",
482
+ label: "TailwindCSS",
483
+ flag: "tailwindcss",
484
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxLjY3ZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjU2IDE1NCI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJsb2dvc1RhaWx3aW5kY3NzSWNvbjAiIHgxPSItMi43NzglIiB4Mj0iMTAwJSIgeTE9IjMyJSIgeTI9IjY3LjU1NiUiPjxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiMyMjk4QkQiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwRUQ3QjUiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cGF0aCBmaWxsPSJ1cmwoI2xvZ29zVGFpbHdpbmRjc3NJY29uMCkiIGQ9Ik0xMjggMEM5My44NjcgMCA3Mi41MzMgMTcuMDY3IDY0IDUxLjJDNzYuOCAzNC4xMzMgOTEuNzMzIDI3LjczMyAxMDguOCAzMmM5LjczNyAyLjQzNCAxNi42OTcgOS40OTkgMjQuNDAxIDE3LjMxOEMxNDUuNzUxIDYyLjA1NyAxNjAuMjc1IDc2LjggMTkyIDc2LjhjMzQuMTMzIDAgNTUuNDY3LTE3LjA2NyA2NC01MS4yYy0xMi44IDE3LjA2Ny0yNy43MzMgMjMuNDY3LTQ0LjggMTkuMmMtOS43MzctMi40MzQtMTYuNjk3LTkuNDk5LTI0LjQwMS0xNy4zMThDMTc0LjI0OSAxNC43NDMgMTU5LjcyNSAwIDEyOCAwWk02NCA3Ni44QzI5Ljg2NyA3Ni44IDguNTMzIDkzLjg2NyAwIDEyOGMxMi44LTE3LjA2NyAyNy43MzMtMjMuNDY3IDQ0LjgtMTkuMmM5LjczNyAyLjQzNCAxNi42OTcgOS40OTkgMjQuNDAxIDE3LjMxOEM4MS43NTEgMTM4Ljg1NyA5Ni4yNzUgMTUzLjYgMTI4IDE1My42YzM0LjEzMyAwIDU1LjQ2Ny0xNy4wNjcgNjQtNTEuMmMtMTIuOCAxNy4wNjctMjcuNzMzIDIzLjQ2Ny00NC44IDE5LjJjLTkuNzM3LTIuNDM0LTE2LjY5Ny05LjQ5OS0yNC40MDEtMTcuMzE4QzExMC4yNDkgOTEuNTQzIDk1LjcyNSA3Ni44IDY0IDc2LjhaIi8+PC9zdmc+",
485
+ url: "https://tailwindcss.com",
486
+ spectrum: "beaten_path",
487
+ tagline: "Rapidly build modern websites without ever leaving your HTML",
488
+ repo: "tailwindlabs/tailwindcss",
489
+ links: [
490
+ {
491
+ label: "Docs",
492
+ href: "https://tailwindcss.com/docs/installation"
493
+ }
494
+ ]
495
+ },
496
+ {
497
+ category: "CSS",
498
+ label: "Compiled",
499
+ flag: "compiled-css",
500
+ image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAFf0lEQVR4nLSaXWzbVBvHz3OOncRJnY926vp27Uu7Tm3Vsi7hsxpDRahjrMAFEqsYlAk6IQECpF2ttEwwGBLccAE3fAmhCfEhJK4AiQ+BGGKirJuYhoRg68pKV5bSZCEfrpPYMXLSpE5iJ3ZyciRfxD5+nud3nuc5/9ouc/fjh1Ajhgxc09Kmx76QCL+5Y/WNMbu0Mt8IP7gRRtXxj/uuo0lb560y8fauuseONcpPQwDW2I6BqGv46fzvhGNon8i0DzbCV0MAQvyeFxBgpnACEAnzo9ON8EUdQGTa+wTH4L2l5+Pc0HiSae2h7Y86wNWmkUMIdOwCZkL87hna/qgCyMDxcaf/QaPrcS4wQTsLVAGizuvHFWCbDCcAZkP8nc/T9EkVIMb5x6vNiXP+/SLTPkDLJzUAGTiXaOsaqToREAm57zhCyy81AMHWvQsBtpuZu64LVLJADUC0b91penI2C3uP0vBLD4DdErAyP8EN3rfGdgzV65caQJpp7bN6z9Wm2w/X65cKgIIAScTzf6v30VBnKgASuLwIsMPyjRTUmU4GsM1d671xLvCQyLRZLr/8oAKQAYep7VN3qFlw167OVABAScn13F+PLlACkBL1GahdnakAMBkhXK+NXBas94JlgEi6ZehvsXNMUQA2jKTSkFkLWrVVNGp8arMEEJW8vScje0+djo58fjY2/JqibFyzSavnrTovHXHO/4BVXbAEsCBuPwyY2DDG6LK47cmLwsAT+Wu29PKvVmzpjhp0wTSAIPOdQalnAgCj7IEB/S5c96paUup1R2pprpaYS4fVpzbTAAupwDMIGBtgjDAGpGYBMLGfS+x8U+0HLnXhRM1Ra0f2qc18FkwBJDKe7mCmbxJng1cD3zgSmZbhS2L/pF0KnidS5EJdwa8PK+psCuBP6cYjCBh7Lujc6mth5pOBY3KG5ZrEc5/WHT2yps5VARIZX88q6psoDTp/qL9l4NoWU/0HeeHMB1QALKhzVYC/lJtnAAibX31t4AUYwOhyevApLnXpLJu+QqWZzapzRQBB8V4Tgv4Jo9LJB6/+TiJ3b0jesssXP/E6FQCT6lwRYBkPTyFMWKPSKT2/Im3b7xbmPiTyvwtUCEyosyGAiDwdIXztI0aB51d/4zygkNJ1DyhS2hf7/hUqACbU2RBgmdwyhXBu58Ga8ikEDtos5HpDAldnQvH1eBM/vkfk2BIVgirqrAsggrcjzO44qA2utOZLM5PPTkxpuwmjdNIX+/ZlKgBV1FkX4Ipt5FnAjKNazeudF1DLdtWGN3HybSLR6gXjd6plACLe1B2x+Sd1gwa9oIu3VhH5tuYMp1PNsa9fpAJQ4Z1qGUDQcds0rO88heDUstEtHShrbAm7NudteYTZ40SK1P1ndnYY6EIRgIg3dUUd/gNFwYFRves3tvb1Okay3Bz75iUqAAbqXASw6hqdzv29vx4c6DdqGZAmOwizRGvTI8y+z0iRP6gQ6GShAJAkrd0xZ+Bh/T3eXAOrBwNyotiBmoWvnqMCoPPFswAQ4ken1NovXVH9oMGwsW0grJQ69QizH7Pplfqf2FC5OmcBUqS5Pe4MHMg1K6my0pUb246iF8t9Koov/h1Fdd54p5oFCPO7pxAQB4C65aoHyX7mNax3w8bGyImCv+g5dQtzHzFShM6/G2jUGadI8/+izhseLboOCOECiEHpGGSHlxd/0POJkSz5KO5IeXXGIX7PjLr6uqBqRrKrTQwbWwvDKaE5hxJeNHKq6gIjhX+jQrCuzjjO7bi/4jzQguiXVf5cS/rMO5VsZXek6JfUPrPGOf8+7BZOvYsQqvpytrg/SNkuxWWCPzUn545Xs+NZO/0Jl5z/rN7gFYQyvPDzW/8FAAD//wWcstmJqV1FAAAAAElFTkSuQmCC",
501
+ url: "https://compiledcssinjs.com",
502
+ tagline: "A familiar and performant compile time CSS-in-JS library for React.",
503
+ repo: "atlassian-labs/compiled",
504
+ links: [
505
+ {
506
+ label: "Docs",
507
+ href: "https://compiledcssinjs.com/docs/"
508
+ }
509
+ ]
510
+ },
511
+ // UI Component Libraries
512
+ {
513
+ category: "UI Component Libraries",
514
+ label: "daisyUI",
515
+ flag: "daisyui",
516
+ dependsOn: ["tailwindcss"],
517
+ image: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0nMzInIGhlaWdodD0nMzInIHZpZXdCb3g9JzAgMCA0MTUgNDE1JyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnPjxyZWN0IHg9JzgyLjUnIHk9JzI5MCcgd2lkdGg9JzI1MCcgaGVpZ2h0PScxMjUnIHJ4PSc2Mi41JyBmaWxsPScjMUFEMUE1Jz48L3JlY3Q+PGNpcmNsZSBjeD0nMjA3LjUnIGN5PScxMzUnIHI9JzEzMCcgZmlsbD0nYmxhY2snIGZpbGwtb3BhY2l0eT0nLjMnPjwvY2lyY2xlPjxjaXJjbGUgY3g9JzIwNy41JyBjeT0nMTM1JyByPScxMjUnIGZpbGw9J3doaXRlJz48L2NpcmNsZT48Y2lyY2xlIGN4PScyMDcuNScgY3k9JzEzNScgcj0nNTYnIGZpbGw9JyNGRjk5MDMnPjwvY2lyY2xlPjwvc3ZnPg==",
518
+ url: "https://daisyui.com",
519
+ tagline: "The most popular component library for Tailwind CSS",
520
+ repo: "saadeghi/daisyui",
521
+ links: [
522
+ {
523
+ label: "Docs",
524
+ href: "https://daisyui.com/docs/use/"
525
+ }
526
+ ]
527
+ },
528
+ {
529
+ category: "UI Component Libraries",
530
+ label: "shadcn/ui",
531
+ flag: "shadcn-ui",
532
+ dependsOn: ["tailwindcss", "react"],
533
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiBjbGFzcz0iaC02IHctNiI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgyNTZ2MjU2SDB6Ii8+PHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxNiIgZD0ibTIwOCAxMjgtODAgODBtNjQtMTY4TDQwIDE5MiIvPjwvc3ZnPg==",
534
+ url: "https://ui.shadcn.com",
535
+ tagline: "Beautifully designed components that you can copy and paste into your apps.",
536
+ repo: "shadcn-ui/ui",
537
+ links: [
538
+ {
539
+ label: "Docs",
540
+ href: "https://ui.shadcn.com/docs"
541
+ }
542
+ ]
543
+ },
544
+ {
545
+ category: "UI Component Libraries",
546
+ label: "Mantine",
547
+ flag: "mantine",
548
+ dependsOn: ["react"],
549
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCAxNjMgMTYzIj48cGF0aCBmaWxsPSIjMzM5QUYwIiBkPSJNMTYyLjE2MiA4MS41YzAtNDUuMDExLTM2LjMwMS04MS41LTgxLjA4LTgxLjVDMzYuMzAxIDAgMCAzNi40ODkgMCA4MS41IDAgMTI2LjUxIDM2LjMwMSAxNjMgODEuMDgxIDE2M3M4MS4wODEtMzYuNDkgODEuMDgxLTgxLjUiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNjUuOTgzIDQzLjA0OWE2LjIzIDYuMjMgMCAwIDAtLjMzNiA2Ljg4NCA2LjEgNi4xIDAgMCAwIDEuNjE4IDEuNzg2YzkuNDQ0IDcuMDM2IDE0Ljg2NiAxNy43OTQgMTQuODY2IDI5LjUycy01LjQyMiAyMi40ODQtMTQuODY2IDI5LjUyYTYuMiA2LjIgMCAwIDAtMS42MTYgMS43ODYgNi4yIDYuMiAwIDAgMC0uNjk0IDQuNjkzIDYuMiA2LjIgMCAwIDAgMS4wMjggMi4xODYgNi4xNSA2LjE1IDAgMCAwIDYuNDU3IDIuMzE5IDYuMiA2LjIgMCAwIDAgMi4xNzctMS4wMzUgNTAgNTAgMCAwIDAgNy45NDctNy4zOWgxNy40OTNjMy40MDYgMCA2LjE3NC0yLjc3MiA2LjE3NC02LjE5NHMtMi43NjItNi4xOTQtNi4xNzQtNi4xOTRoLTkuNjU1YTQ5LjIgNDkuMiAwIDAgMCA0LjA3MS0xOS42OSA0OS4yIDQ5LjIgMCAwIDAtNC4wNy0xOS42OTJoOS42NmMzLjQwNiAwIDYuMTczLTIuNzcxIDYuMTczLTYuMTk0cy0yLjc2Mi02LjE5My02LjE3My02LjE5M0g4Mi41NzRhNTAgNTAgMCAwIDAtNy45NTItNy4zOTcgNi4xNSA2LjE1IDAgMCAwLTQuNTc4LTEuMTUzIDYuMiA2LjIgMCAwIDAtNC4wNTUgMi40Mzh6Ii8+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNTYuMjM2IDc5LjM5MWE5LjMgOS4zIDAgMCAxIC42MzItMy42MDggOS4zIDkuMyAwIDAgMSAxLjk2Ny0zLjA3NyA5LjEgOS4xIDAgMCAxIDIuOTk0LTIuMDYzIDkuMDYgOS4wNiAwIDAgMSA3LjEwMyAwIDkuMTUgOS4xNSAwIDAgMSAyLjk5NSAyLjA2MyA5LjMgOS4zIDAgMCAxIDEuOTY3IDMuMDc3IDkuMzQgOS4zNCAwIDAgMS0yLjEyNSAxMC4wMDMgOS4xIDkuMSAwIDAgMS02LjM4OCAyLjYzIDkuMSA5LjEgMCAwIDEtNi4zOS0yLjYzIDkuMyA5LjMgMCAwIDEtMi43NTUtNi4zOTUiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==",
550
+ url: "https://mantine.dev",
551
+ tagline: "A fully featured React components library.",
552
+ repo: "mantinedev/mantine",
553
+ links: [
554
+ {
555
+ label: "Docs",
556
+ href: "https://mantine.dev/getting-started/"
557
+ }
558
+ ]
559
+ },
560
+ // Auth
561
+ {
562
+ category: "Auth",
563
+ label: "Auth.js",
564
+ flag: "authjs",
565
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCI+PHBhdGggZmlsbD0iIzg4ODg4OCIgZD0ibTUwLjAyNyAxMC40NTlsLS4wMTgtLjAzMmwtMzMuNjA2IDE5LjQwNGwuMDc2LjEzMnYyMi44OTNoLjAxNGMuMjg2IDE5LjExMSAxNC44NTkgMzQuNzU1IDMzLjUxOSAzNi43MThjMTguNjYtMS45NjIgMzMuMjM0LTE3LjYwNiAzMy41MTktMzYuNzE4VjI5Ljk1M2wuMDY2LS4xMTRsLTMzLjU3LTE5LjM4em0tLjAxNSA2OS4wOTdWNTEuNjc3SDI2LjQzNVYzNS42NTFMNTAuMDEyIDIyLjA0djI5LjYzN2gyMy41NjN2MS4xNzloLjAxN2MtLjI3OCAxMy41OTMtMTAuNDM5IDI0Ljc5OC0yMy41OCAyNi43eiIvPjwvc3ZnPg==",
566
+ url: "https://authjs.dev",
567
+ spectrum: "bleeding_edge",
568
+ tagline: "Authentication for the Web",
569
+ repo: "nextauthjs/next-auth",
570
+ links: [
571
+ {
572
+ label: "Getting started",
573
+ href: "https://authjs.dev/getting-started/introduction"
574
+ },
575
+ {
576
+ label: "API",
577
+ href: "https://authjs.dev/reference"
578
+ }
579
+ ]
580
+ },
581
+ {
582
+ category: "Auth",
583
+ label: "Auth0",
584
+ flag: "auth0",
585
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIwLjllbSIgaGVpZ2h0PSIxZW0iIHZpZXdCb3g9IjAgMCAyNTYgMjg1Ij48cGF0aCBkPSJNMjIwLjQxMiAwaC05Mi40MTVsMjguNTYyIDg5LjAwNmg5Mi40MTZsLTc0Ljc3IDUzLjA3N2wyOC41NyA4OS41MTFjNDguMTI4LTM1LjA2IDYzLjg1NC04OC4xMiA0Ni4yMDgtMTQyLjU4OEwyMjAuNDEzIDBaTTcuMDE4IDg5LjAwNmg5Mi40MTZMMTI3Ljk5NyAwSDM1LjU4OUw3LjAxOSA4OS4wMDZjLTE3LjY1NSA1NC40NjgtMS45MiAxMDcuNTI5IDQ2LjIwNyAxNDIuNTg4bDI4LjU2My04OS41MWwtNzQuNzctNTMuMDc4Wm00Ni4yMDggMTQyLjU4OGw3NC43NyA1Mi45N2w3NC43Ny01Mi45N2wtNzQuNzctNTMuODQ3bC03NC43NyA1My44NDdaIi8+PC9zdmc+",
586
+ url: "https://auth0.com",
587
+ tagline: "Secure access for everyone. But not just anyone.",
588
+ repo: "nextauthjs/next-auth",
589
+ links: [
590
+ {
591
+ label: "Auth0 doc",
592
+ href: "https://auth0.com/docs"
593
+ },
594
+ {
595
+ label: "Auth.js auth0 provider doc",
596
+ href: "https://authjs.dev/reference/core/providers/auth0"
597
+ }
598
+ ]
599
+ },
600
+ {
601
+ category: "Auth",
602
+ label: "Firebase",
603
+ flag: "firebase-auth",
604
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIwLjczZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjU2IDM1MSI+PGRlZnM+PGZpbHRlciBpZD0ibG9nb3NGaXJlYmFzZTAiIHdpZHRoPSIyMDAlIiBoZWlnaHQ9IjIwMCUiIHg9Ii01MCUiIHk9Ii01MCUiIGZpbHRlclVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJzaGFkb3dCbHVySW5uZXIxIiBzdGREZXZpYXRpb249IjE3LjUiLz48ZmVPZmZzZXQgaW49InNoYWRvd0JsdXJJbm5lcjEiIHJlc3VsdD0ic2hhZG93T2Zmc2V0SW5uZXIxIi8+PGZlQ29tcG9zaXRlIGluPSJzaGFkb3dPZmZzZXRJbm5lcjEiIGluMj0iU291cmNlQWxwaGEiIGsyPSItMSIgazM9IjEiIG9wZXJhdG9yPSJhcml0aG1ldGljIiByZXN1bHQ9InNoYWRvd0lubmVySW5uZXIxIi8+PGZlQ29sb3JNYXRyaXggaW49InNoYWRvd0lubmVySW5uZXIxIiB2YWx1ZXM9IjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAuMDYgMCIvPjwvZmlsdGVyPjxmaWx0ZXIgaWQ9ImxvZ29zRmlyZWJhc2UxIiB3aWR0aD0iMjAwJSIgaGVpZ2h0PSIyMDAlIiB4PSItNTAlIiB5PSItNTAlIiBmaWx0ZXJVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giPjxmZUdhdXNzaWFuQmx1ciBpbj0iU291cmNlQWxwaGEiIHJlc3VsdD0ic2hhZG93Qmx1cklubmVyMSIgc3RkRGV2aWF0aW9uPSIzLjUiLz48ZmVPZmZzZXQgZHg9IjEiIGR5PSItOSIgaW49InNoYWRvd0JsdXJJbm5lcjEiIHJlc3VsdD0ic2hhZG93T2Zmc2V0SW5uZXIxIi8+PGZlQ29tcG9zaXRlIGluPSJzaGFkb3dPZmZzZXRJbm5lcjEiIGluMj0iU291cmNlQWxwaGEiIGsyPSItMSIgazM9IjEiIG9wZXJhdG9yPSJhcml0aG1ldGljIiByZXN1bHQ9InNoYWRvd0lubmVySW5uZXIxIi8+PGZlQ29sb3JNYXRyaXggaW49InNoYWRvd0lubmVySW5uZXIxIiB2YWx1ZXM9IjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAuMDkgMCIvPjwvZmlsdGVyPjxwYXRoIGlkPSJsb2dvc0ZpcmViYXNlMiIgZD0ibTEuMjUzIDI4MC43MzJsMS42MDUtMy4xMzFsOTkuMzUzLTE4OC41MThsLTQ0LjE1LTgzLjQ3NUM1NC4zOTItMS4yODMgNDUuMDc0LjQ3NCA0My44NyA4LjE4OEwxLjI1MyAyODAuNzMyWiIvPjxwYXRoIGlkPSJsb2dvc0ZpcmViYXNlMyIgZD0ibTEzNC40MTcgMTQ4Ljk3NGwzMi4wMzktMzIuODEybC0zMi4wMzktNjEuMDA3Yy0zLjA0Mi01Ljc5MS0xMC40MzMtNi4zOTgtMTMuNDQzLS41OWwtMTcuNzA1IDM0LjEwOWwtLjUzIDEuNzQ0bDMxLjY3OCA1OC41NTZaIi8+PC9kZWZzPjxwYXRoIGZpbGw9IiNGRkMyNEEiIGQ9Im0wIDI4Mi45OThsMi4xMjMtMi45NzJMMTAyLjUyNyA4OS41MTJsLjIxMi0yLjAxN0w1OC40OCA0LjM1OEM1NC43Ny0yLjYwNiA0NC4zMy0uODQ1IDQzLjExNCA2Ljk1MUwwIDI4Mi45OThaIi8+PHVzZSBmaWxsPSIjRkZBNzEyIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGhyZWY9IiNsb2dvc0ZpcmViYXNlMiIvPjx1c2UgZmlsdGVyPSJ1cmwoI2xvZ29zRmlyZWJhc2UwKSIgaHJlZj0iI2xvZ29zRmlyZWJhc2UyIi8+PHBhdGggZmlsbD0iI0Y0QkQ2MiIgZD0ibTEzNS4wMDUgMTUwLjM4bDMyLjk1NS0zMy43NWwtMzIuOTY1LTYyLjkzYy0zLjEyOS01Ljk1Ny0xMS44NjYtNS45NzUtMTQuOTYyIDBMMTAyLjQyIDg3LjI4N3YyLjg2bDMyLjU4NCA2MC4yMzNaIi8+PHVzZSBmaWxsPSIjRkZBNTBFIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGhyZWY9IiNsb2dvc0ZpcmViYXNlMyIvPjx1c2UgZmlsdGVyPSJ1cmwoI2xvZ29zRmlyZWJhc2UxKSIgaHJlZj0iI2xvZ29zRmlyZWJhc2UzIi8+PHBhdGggZmlsbD0iI0Y2ODIwQyIgZD0ibTAgMjgyLjk5OGwuOTYyLS45NjhsMy40OTYtMS40MmwxMjguNDc3LTEyOGwxLjYyOC00LjQzMWwtMzIuMDUtNjEuMDc0eiIvPjxwYXRoIGZpbGw9IiNGREUwNjgiIGQ9Im0xMzkuMTIxIDM0Ny41NTFsMTE2LjI3NS02NC44NDdsLTMzLjIwNC0yMDQuNDk1Yy0xLjAzOS02LjM5OC04Ljg4OC04LjkyNy0xMy40NjgtNC4zNEwwIDI4Mi45OThsMTE1LjYwOCA2NC41NDhhMjQuMTI2IDI0LjEyNiAwIDAgMCAyMy41MTMuMDA1Ii8+PHBhdGggZmlsbD0iI0ZDQ0EzRiIgZD0iTTI1NC4zNTQgMjgyLjE2TDIyMS40MDIgNzkuMjE4Yy0xLjAzLTYuMzUtNy41NTgtOC45NzctMTIuMTAzLTQuNDI0TDEuMjkgMjgyLjZsMTE0LjMzOSA2My45MDhhMjMuOTQzIDIzLjk0MyAwIDAgMCAyMy4zMzQuMDA2bDExNS4zOTItNjQuMzU1WiIvPjxwYXRoIGZpbGw9IiNFRUFCMzciIGQ9Ik0xMzkuMTIgMzQ1LjY0YTI0LjEyNiAyNC4xMjYgMCAwIDEtMjMuNTEyLS4wMDVMLjkzMSAyODIuMDE1bC0uOTMuOTgzbDExNS42MDcgNjQuNTQ4YTI0LjEyNiAyNC4xMjYgMCAwIDAgMjMuNTEzLjAwNWwxMTYuMjc1LTY0Ljg0N2wtLjI4NS0xLjc1MmwtMTE1Ljk5IDY0LjY4OVoiLz48L3N2Zz4=",
605
+ url: "https://firebase.google.com",
606
+ tagline: "Firebase Authentication aims to make building secure authentication systems easy, while improving the sign-in and onboarding experience for end users",
607
+ links: [
608
+ {
609
+ label: "Getting started",
610
+ href: "https://firebase.google.com/docs/web/setup"
611
+ },
612
+ {
613
+ label: "API",
614
+ href: "https://firebase.google.com/docs/reference"
615
+ }
616
+ ]
617
+ },
618
+ {
619
+ category: "Auth",
620
+ label: "Lucia",
621
+ flag: "lucia-auth",
622
+ image: "data:image/svg+xml;base64,PHN2ZyBpZD0nV2Fyc3R3YV8xJyBkYXRhLW5hbWU9J1dhcnN0d2EgMScgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyB4bWxuczp4bGluaz0naHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluaycgdmlld0JveD0nMCAwIDIwMDAgMjAwMCc+PHBhdGggZmlsbD0nIzVmNTdmZicgZD0nbTE2NDcuNjYsMTY3My4zNkwxMDAwLDcyLjczLDM1Mi4zNCwxNjczLjM2bC0xMDIuNzQsMjUzLjkxaDE1MDAuOGwtMTAyLjc0LTI1My45MVptLTY0Ny42Ni01NDlsLTQ0Mi44Miw1NDUuMzksOTkuNTUtMjQ2LjA0LDM0My4yNy04NDguMzUsMzQzLjI2LDg0OC4zNSw5OS41NSwyNDYuMDQtNDQyLjgxLTU0NS4zOVonIC8+PC9zdmc+",
623
+ url: "https://lucia-auth.com",
624
+ spectrum: "bleeding_edge",
625
+ tagline: "Lucia is an auth library for your server that abstracts away the complexity of handling sessions",
626
+ links: [
627
+ {
628
+ label: "Getting started",
629
+ href: "https://lucia-auth.com/getting-started/"
630
+ },
631
+ {
632
+ label: "API reference",
633
+ href: "https://lucia-auth.com/reference/main/"
634
+ }
635
+ ]
636
+ },
637
+ // RPC
638
+ {
639
+ category: "Data fetching",
640
+ label: "Telefunc",
641
+ flag: "telefunc",
642
+ image: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDcuMDIiIGhlaWdodD0iNDcuMDIiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDQ3LjAyIDQ3LjAyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogPGNpcmNsZSBjeD0iMjMuNTEiIGN5PSIyMy41MSIgcj0iMjEuOTUiIGZpbGw9IiNmN2UwMTgiIHN0cm9rZT0iIzMxMzQzZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIzLjEyIiBzdHlsZT0icGFpbnQtb3JkZXI6bm9ybWFsIi8+CiA8ZyB0cmFuc2Zvcm09Im1hdHJpeCguOTU1MDMgMCAwIC45NTUwMyAuMzQ0MDUgMS4wMTE3KSIgZmlsbD0iIzMxMzQzZCIgc2hhcGUtcmVuZGVyaW5nPSJhdXRvIj4KICA8cGF0aCBkPSJtMjEuODA0IDEzLjkxMyA2LjQzMzMgOS42NDU4LTYuNDMzMyA5LjY0NDFoNS44ODI0bDMuNDkzLTUuMjM1MiAzLjQ5MTMgNS4yMzUyaDUuODgyNGwtMTIuODY3LTE5LjI5eiIgY29sb3I9IiMwMDAwMDAiIGNvbG9yLXJlbmRlcmluZz0iYXV0byIgZG9taW5hbnQtYmFzZWxpbmU9ImF1dG8iIGltYWdlLXJlbmRlcmluZz0iYXV0byIgc29saWQtY29sb3I9IiMwMDAwMDAiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1hbHRlcm5hdGVzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsO2ZvbnQtdmFyaWFudC1wb3NpdGlvbjpub3JtYWw7aXNvbGF0aW9uOmF1dG87bWl4LWJsZW5kLW1vZGU6bm9ybWFsO3NoYXBlLXBhZGRpbmc6MDt0ZXh0LWRlY29yYXRpb24tY29sb3I6IzAwMDAwMDt0ZXh0LWRlY29yYXRpb24tbGluZTpub25lO3RleHQtZGVjb3JhdGlvbi1zdHlsZTpzb2xpZDt0ZXh0LWluZGVudDowO3RleHQtb3JpZW50YXRpb246bWl4ZWQ7dGV4dC10cmFuc2Zvcm06bm9uZTt3aGl0ZS1zcGFjZTpub3JtYWwiLz4KICA8cGF0aCBkPSJtMTQuODgyIDEzLjkxMyA2LjQzMzMgOS42NDU4LTYuNDMzMyA5LjY0NDFoNS44ODI0YzIuMDg1NS0zLjI5MTEgNC4wNDUyLTYuMjk1OSA2LjIyMjEtOS45NjE4bC02LjIyMjEtOS4zMjgxeiIgY29sb3I9IiMwMDAwMDAiIGNvbG9yLXJlbmRlcmluZz0iYXV0byIgZG9taW5hbnQtYmFzZWxpbmU9ImF1dG8iIGZpbGwtb3BhY2l0eT0iLjU3MzE1IiBpbWFnZS1yZW5kZXJpbmc9ImF1dG8iIHNvbGlkLWNvbG9yPSIjMDAwMDAwIiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtYWx0ZXJuYXRlczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbDtmb250LXZhcmlhbnQtcG9zaXRpb246bm9ybWFsO2lzb2xhdGlvbjphdXRvO21peC1ibGVuZC1tb2RlOm5vcm1hbDtzaGFwZS1wYWRkaW5nOjA7dGV4dC1kZWNvcmF0aW9uLWNvbG9yOiMwMDAwMDA7dGV4dC1kZWNvcmF0aW9uLWxpbmU6bm9uZTt0ZXh0LWRlY29yYXRpb24tc3R5bGU6c29saWQ7dGV4dC1pbmRlbnQ6MDt0ZXh0LW9yaWVudGF0aW9uOm1peGVkO3RleHQtdHJhbnNmb3JtOm5vbmU7d2hpdGUtc3BhY2U6bm9ybWFsIi8+CiAgPHBhdGggZD0ibTcuOTYwNCAxMy45MTMgNi40MzMzIDkuNjQ1OC02LjQzMzMgOS42NDQxaDUuODgyNGMyLjA4NTUtMy4yOTExIDQuMDQ1Mi02LjI5NTkgNi4yMjIxLTkuOTYxOGwtNi4yMjIxLTkuMzI4MXoiIGNvbG9yPSIjMDAwMDAwIiBjb2xvci1yZW5kZXJpbmc9ImF1dG8iIGRvbWluYW50LWJhc2VsaW5lPSJhdXRvIiBmaWxsLW9wYWNpdHk9Ii4yNzY1NSIgaW1hZ2UtcmVuZGVyaW5nPSJhdXRvIiBzb2xpZC1jb2xvcj0iIzAwMDAwMCIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWFsdGVybmF0ZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWw7Zm9udC12YXJpYW50LXBvc2l0aW9uOm5vcm1hbDtpc29sYXRpb246YXV0bzttaXgtYmxlbmQtbW9kZTpub3JtYWw7c2hhcGUtcGFkZGluZzowO3RleHQtZGVjb3JhdGlvbi1jb2xvcjojMDAwMDAwO3RleHQtZGVjb3JhdGlvbi1saW5lOm5vbmU7dGV4dC1kZWNvcmF0aW9uLXN0eWxlOnNvbGlkO3RleHQtaW5kZW50OjA7dGV4dC1vcmllbnRhdGlvbjptaXhlZDt0ZXh0LXRyYW5zZm9ybTpub25lO3doaXRlLXNwYWNlOm5vcm1hbCIvPgogPC9nPgo8L3N2Zz4K",
643
+ url: "https://telefunc.com",
644
+ tagline: "Remote Functions. Instead of API",
645
+ repo: "brillout/telefunc",
646
+ spectrum: "bleeding_edge"
647
+ },
648
+ {
649
+ category: "Data fetching",
650
+ label: "tRPC",
651
+ flag: "trpc",
652
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIwLjg0ZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjU2IDMwNSI+PHBhdGggZmlsbD0iIzM5OENDQiIgZD0iTTI4LjU3IDI0NC40ODRoMjEuOTgydjExLjE1M0gyOC41NzF2MjUuMzA4YTE2Ljg4IDE2Ljg4IDAgMCAwIC43MzggNS4zNjRhOC4xNTIgOC4xNTIgMCAwIDAgMi4wODggMy40YTcuODE1IDcuODE1IDAgMCAwIDMuMyAxLjg1MWMxLjIzNS4zMyAyLjUwNC41MSAzLjc4LjUzNmwuNTQ3LjAwMmMxLjE1IDAgMi4zMzggMCAzLjU2My0uMTYybC43MjctLjA5bDEuNDA5LS4xNmMuNDYxLS4wNTQuOTE1LS4xMTMgMS4zNjYtLjE4OGwuNjYtLjEwNWwxLjI0LS4xODRjLjQwMS0uMDYuNzktLjEyNCAxLjE3NS0uMTk5bC45MTgtLjE4NGwuNDI3LS4wOWwuNzktLjE3NmwuMzY2LS4wODdsMS40NzYgMTAuMzlhMTguNTA1IDE4LjUwNSAwIDAgMS0zLjc1MiAxLjZhMzUuOSAzNS45IDAgMCAxLTQuNTEzIDEuMTEzYy0xLjYuMy0zLjI2NC41MjYtNS4wMDIuNjg4YTU0LjI4IDU0LjI4IDAgMCAxLTUuMDg5LjIzOGEyOC4zOTYgMjguMzk2IDAgMCAxLTguNzUyLTEuMjVhMTYuODMgMTYuODMgMCAwIDEtNi43MjctNC4wMDJhMTcuMzQzIDE3LjM0MyAwIDAgMS00LjMwMi02Ljg1MmEyOS4xOTYgMjkuMTk2IDAgMCAxLTEuNTI1LTEwLjAwM3YtMjYuNzU4SDB2LTExLjE1M2gxMy40NDF2LTE0LjQxN2gxNS4xM3YxNC40MTdabTUzLjg4IDI5LjI3MXYyOS42MDlINjcuMTU2di03OS4yMzZoMjYuNjJhNDIuNTIgNDIuNTIgMCAwIDEgMTEuOTE2IDEuNTVhMjYuNjcgMjYuNjcgMCAwIDEgOS4xNCA0LjU1MmExOS44OCAxOS44OCAwIDAgMSA1Ljc5IDcuNTAyYTI0LjU3IDI0LjU3IDAgMCAxIDIuMDUgMTAuMzRhMjYuNzIgMjYuNzIgMCAwIDEtMS4wMTIgNy42NGEyMC4zMzEgMjAuMzMxIDAgMCAxLTcuNDAzIDEwLjgwNGEzMC4wOTYgMzAuMDk2IDAgMCAxLTUuOTAxIDMuNDg4bDE3LjAzIDMyLjY5N3YuNzEzaC0xNi40NDNMOTQuMDQgMjczLjc1NUg4Mi40NVptLjAxMi0xMi40MjhoMTEuMzE1YTE3Ljg2OCAxNy44NjggMCAwIDAgNi4yNTItMWExMC44NjYgMTAuODY2IDAgMCAwIDQuMzktMi45MTRhMTAuNTI4IDEwLjUyOCAwIDAgMCAyLjExMi0zLjU4OWMuNDQ4LTEuMzU4LjY5Mi0yLjc3NS43MjMtNC4yMDNsLjAwMi0uNTM2YTE1LjEwNCAxNS4xMDQgMCAwIDAtLjk1LTUuNTc2YTkuODY1IDkuODY1IDAgMCAwLTIuODUtNC4wMDFhMTIuMDY2IDEyLjA2NiAwIDAgMC00LjE0LTIuMTc2YTE5LjE0MyAxOS4xNDMgMCAwIDAtNC45Ny0uNzZsLTExLjg4NC0uMDAzdjI0Ljc1OFptNjcuODQ1IDQyLjAzN0gxMzUuMDR2LTc5LjIzNmgyNy4wOTVhMzQuNDEgMzQuNDEgMCAwIDEgMTEuNzAzIDEuODc2YTI2LjYzMyAyNi42MzMgMCAwIDEgOC45MjggNS4yMDFhMjMuMzA3IDIzLjMwNyAwIDAgMSA1LjYyNyA4LjA1M2EyNi4zNTggMjYuMzU4IDAgMCAxIDEuOTg4IDkuNzIzdi42NjdhMjQuMTcgMjQuMTcgMCAwIDEtMS45ODggOS44NTNhMjIuNTA3IDIyLjUwNyAwIDAgMS01LjYyNyA3Ljc3N2EyNi4zNyAyNi4zNyAwIDAgMS04Ljk2NSA1LjE3N2EzNC43MjMgMzQuNzIzIDAgMCAxLTExLjcwNCAxLjg1aC0xMS44MDNsLjAxMyAyOS4wNTlabTAtNDEuNDYyaDExLjgwM2ExNS4wMDQgMTUuMDA0IDAgMCAwIDUuNjY0LS45ODhhMTEuNTUzIDExLjU1MyAwIDAgMCA0LjAyNi0yLjY2M2ExMS4xNzggMTEuMTc4IDAgMCAwIDIuMzY0LTMuODg5Yy41My0xLjQ3Ni44LTMuMDMzLjgtNC42MDFhMTYuMzY3IDE2LjM2NyAwIDAgMC0uOC01LjE2NGExMS45NjYgMTEuOTY2IDAgMCAwLTIuMzY0LTQuMjAyYTExLjU5IDExLjU5IDAgMCAwLTQuMDI2LTIuODI1YTE0LjI2NyAxNC4yNjcgMCAwIDAtNS42NjQtMS4wMzhoLTExLjgwM3YyNS4zN1ptMTAzLjA0MiAyNy40MmEyNS4zMDcgMjUuMzA3IDAgMCAxLTUuOTAyIDguMTY1YTI2LjA0NSAyNi4wNDUgMCAwIDEtOC44MTUgNS4yMDJhMzMuNjQ3IDMzLjY0NyAwIDAgMS0xMC41NTggMS44MTRsLS43Ny0uMDAxYTMwLjc1OSAzMC43NTkgMCAwIDEtOS4wNTMtMS4yNWEyNS4zNDUgMjUuMzQ1IDAgMCAxLTcuNTAyLTMuNjc3YTI1LjcwNyAyNS43MDcgMCAwIDEtNS40MTQtNS4zODlhMzMuNjcyIDMzLjY3MiAwIDAgMS00LjAwMS02Ljk2NGE0MS41NzUgNDEuNTc1IDAgMCAxLTIuNDEzLTguMzc4YTUzLjQwOCA1My40MDggMCAwIDEtLjg1MS05LjY5di0xMC42NjZhNTMuNDMgNTMuNDMgMCAwIDEgLjc2My05LjExNWEzOS40MTEgMzkuNDExIDAgMCAxIDEuOTUtNy4xNjFsLjMzOC0uODY2YTMwLjQwOSAzMC40MDkgMCAwIDEgNC41NzctOC4wNTNhMjkuMjcxIDI5LjI3MSAwIDAgMSA2LjQxNC01Ljk3NmEyNi4xNTggMjYuMTU4IDAgMCAxIDcuMDUyLTMuMTg5YTI5LjEwOCAyOS4xMDggMCAwIDEgNy40OC0xLjExbC43Ni0uMDAzYTMzLjc2IDMzLjc2IDAgMCAxIDExLjYxNiAxLjg1YTIzLjc1NyAyMy43NTcgMCAwIDEgMTQuMzQyIDEzLjY1NWEzNy40MTEgMzcuNDExIDAgMCAxIDIuNjEzIDExLjE1M2gtMTUuMjNjLS4wOS0yLjEyLS40NDItNC4yMi0xLjA1LTYuMjUyYTEyLjM1NCAxMi4zNTQgMCAwIDAtMi40MjUtNC40NjNhMTAuNDE2IDEwLjQxNiAwIDAgMC00LjA1Mi0yLjYzOWExNi43MyAxNi43MyAwIDAgMC01LjgwMS0uOWExNC4yNDIgMTQuMjQyIDAgMCAwLTMuMzUxLjM4OGMtMSAuMjQzLTEuOTU5LjYyNi0yLjg1MSAxLjEzN2ExMS4zMjggMTEuMzI4IDAgMCAwLTMuNzUxIDMuNzUyYTIxLjk2OSAyMS45NjkgMCAwIDAtMi41MDEgNS42MzlhMzQuMDEgMzQuMDEgMCAwIDAtMS4wMjUgNS41MjZhNTguNzY3IDU4Ljc2NyAwIDAgMC0uMzI1IDYuNTAydjEwLjc2NmE2MS4yOCA2MS4yOCAwIDAgMCAuNTEyIDguNDY1YTI4LjkyIDI4LjkyIDAgMCAwIDEuNiA2LjUwMmExNS45OTIgMTUuOTkyIDAgMCAwIDEuODI2IDMuMzc2Yy42NjcuOTYgMS40ODcgMS44MDQgMi40MjYgMi41YTEwLjAwMyAxMC4wMDMgMCAwIDAgMy4yODggMS42YTE0LjU2IDE0LjU2IDAgMCAwIDQuMDUyLjUyNmExNy45MTggMTcuOTE4IDAgMCAwIDUuMzg5LS43NjNhMTAuMzAzIDEwLjMwMyAwIDAgMCA0LjA4OC0yLjRhMTEuMjUzIDExLjI1MyAwIDAgMCAyLjY2NC00LjE5YTIwLjk2OSAyMC45NjkgMCAwIDAgMS4yNS02LjE1SDI1NmEzMC4zOTYgMzAuMzk2IDAgMCAxLTIuNjUgMTAuNzI3Wk0xODYuMzggOTIuNDAybDM4LjQ4NiAyMi4yMnY0NC40NjJsLTM4LjQ4NiAyMi4yMmwtMTcuMDg1LTkuODgxbC00MS41NDUgMjMuOTg0bC00MS4yOTYtMjMuODQ3bC0xNi44NDYgOS43NDNsLTM4LjQ4Ni0yMi4yNTZWMTE0LjYybDM4LjQ4Ni0yMi4yMTlsMzguNDg2IDIyLjIydjQ0LjQyNWwtMTEuNjQzIDYuNzMzbDMxLjI5OSAxOC4wNzRsMzEuNTQ4LTE4LjIxMmwtMTEuNDA1LTYuNTk1VjExNC42MmwzOC40ODctMjIuMjE5Wk0xNTcuODk2IDEyNi4ydjI3LjEybDIzLjQ4MiAxMy41NTV2LTI3LjEyTDE1Ny44OTYgMTI2LjJabTU2Ljk2Ny0uMDM3bC0yMy40ODIgMTMuNTU0djI3LjE1OGwyMy40ODItMTMuNTkydi0yNy4xMlptLTE3My43MzggMHYyNy4xMmwyMy40ODEgMTMuNTU0di0yNy4xMmwtMjMuNDgxLTEzLjU1NFptNTYuOTY2IDBMNzQuNjEgMTM5LjcxNnYyNy4xMmwyMy40ODItMTMuNTU0di0yNy4xMlptODguMjg5LTIyLjE4MmwtMjMuNDgyIDEzLjU1NGwyMy40ODIgMTMuNTY3bDIzLjQ4MS0xMy41NjdsLTIzLjQ4MS0xMy41NTRabS0xMTYuNzcyLS4wMzdsLTIzLjQ4MiAxMy41OTFsMjMuNDgyIDEzLjUzbDIzLjQ4Mi0xMy41M2wtMjMuNDgyLTEzLjU5MVptMTkuMTQzLTY4LjkydjExLjU0bC0zNS42MSAyMC41N3YzNC43NzJsLTEwLjAwMyA1Ljc3N1Y2MS4zNTVMODguNzUgMzUuMDIzWk0xMjcuMjM3IDBsMzguNTEyIDIyLjIxOXYxMi4yMTlsNDYuNjEzIDI2LjkxN3Y0Ni4wMzlsLTEwLjAwMy01Ljc3N1Y2Ny4xMzJsLTM2LjYxLTIxLjE0MXYyMC42NjZsLTM4LjQ4NyAyMi4yMTlsLTM4LjQ4Ni0yMi4yMTlWMjIuMjE5TDEyNy4yMzcgMFpNOTguNzggMzMuNzZ2MjcuMTJsMjMuNDU3IDEzLjU1NFY0Ny4zMjZMOTguNzc5IDMzLjc2Wm01Ni45NDIgMGwtMjMuNDU3IDEzLjU2NnYyNy4wOTZMMTU1LjcyIDYwLjg4VjMzLjc2Wm0tMjguNDg0LTIyLjIwN0wxMDMuNzggMjUuMTA3bDIzLjQ1NyAxMy41NTRsMjMuNDgyLTEzLjU1NGwtMjMuNDgyLTEzLjU1NFoiLz48L3N2Zz4=",
653
+ url: "https://trpc.io",
654
+ spectrum: "beaten_path",
655
+ tagline: "End-to-end typesafe APIs made easy",
656
+ repo: "trpc/trpc",
657
+ links: [
658
+ {
659
+ label: "Getting started",
660
+ href: "https://trpc.io/docs/getting-started"
661
+ },
662
+ {
663
+ label: "Docs",
664
+ href: "https://trpc.io/docs"
665
+ }
666
+ ]
667
+ },
668
+ {
669
+ category: "Data fetching",
670
+ label: "ts-rest",
671
+ flag: "ts-rest",
672
+ image: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0nMTE2JyBoZWlnaHQ9JzExNScgdmlld0JveD0nMCAwIDExNiAxMTUnIGZpbGw9J25vbmUnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc+PGcgY2xpcC1wYXRoPSd1cmwoI2NsaXAwXzEzXzIwKSc+PHJlY3Qgd2lkdGg9JzExNicgaGVpZ2h0PScxMTYnIHJ4PScyNicgZmlsbD0nIzkzMzNFQScvPjxwYXRoIGQ9J002Mi40ODcgNTkuOTU2Nkw5NS4xMTY2IDYwLjEyNjJMOTUuMTQ5MyA1My44MjEyTDYyLjUxOTggNTMuNjUxN0w2Mi40ODcgNTkuOTU2NlpNNjIuNTg2MyA0MC44NDY5TDk1LjIxNTkgNDEuMDE2NEw5NS4yNDkzIDM0LjU4MTVMNjIuNjE5NyAzNC40MTJMNjIuNTg2MyA0MC44NDY5Wk02Mi40MTY4IDczLjQ3NjVMOTUuMDQ2MyA3My42NDZMOTUuMDEyOSA4MC4wODA5TDYyLjM4MzMgNzkuOTExNEw2Mi40MTY4IDczLjQ3NjVaJyBmaWxsPSd3aGl0ZScvPjxwYXRoIGQ9J000Ni4wNiA2NC45MkM1Mi4zIDYyLjU4IDU1Ljg3NSA1Ny41MSA1NS44NzUgNTAuNTU1QzU1Ljg3NSA0MC41NDUgNDguNTk1IDM0LjUgMzYuNyAzNC41SDE4LjVWNDAuOTM1SDM2LjQ0QzQ0LjMwNSA0MC45MzUgNDguNCA0NC40NDUgNDguNCA1MC41NTVDNDguNCA1Ni42IDQ0LjMwNSA2MC4xNzUgMzYuNDQgNjAuMTc1SDE4LjVWODBIMjUuOTFWNjYuNDhIMzYuN0MzNy40OCA2Ni40OCAzOC4zMjUgNjYuNDggMzkuMDQgNjYuNDE1TDQ4LjU5NSA4MEg1Ni42NTVMNDYuMDYgNjQuOTJaJyBmaWxsPSd3aGl0ZScvPjwvZz48ZGVmcz48Y2xpcFBhdGggaWQ9J2NsaXAwXzEzXzIwJz48cmVjdCB3aWR0aD0nMTE2JyBoZWlnaHQ9JzExNScgZmlsbD0nd2hpdGUnLz48L2NsaXBQYXRoPjwvZGVmcz48L3N2Zz4=",
673
+ url: "https://ts-rest.com",
674
+ tagline: "Incrementally adoptable type-safety for your new and existing APIs",
675
+ repo: "ts-rest/ts-rest",
676
+ links: [
677
+ {
678
+ label: "Quickstart",
679
+ href: "https://ts-rest.com/docs/quickstart"
680
+ },
681
+ {
682
+ label: "Docs",
683
+ href: "https://ts-rest.com/docs/intro"
684
+ }
685
+ ]
686
+ },
687
+ // Server
688
+ {
689
+ category: "Server",
690
+ label: "Hono",
691
+ flag: "hono",
692
+ image: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgd2lkdGg9IjUwMHB4IiBoZWlnaHQ9IjUwMHB4IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CjxnPjxwYXRoIHN0eWxlPSJvcGFjaXR5OjAuOTkzIiBmaWxsPSIjZmY1YjExIiBkPSJNIDI1Ny41LDAuNSBDIDI1OC44MjIsMC4zMzAwMzQgMjU5Ljk4OSwwLjY2MzM2OCAyNjEsMS41QyAyOTguMTkzLDQ2Ljg5MzYgMzMzLjE5Myw5My44OTM2IDM2NiwxNDIuNUMgMzkwLjI4OSwxNzkuMDY5IDQxMC45NTUsMjE3LjczNSA0MjgsMjU4LjVDIDQ1NS4yMjEsMzMxLjEwNCA0NDEuMDU0LDM5NC4yNzEgMzg1LjUsNDQ4QyAzMzYuODkyLDQ4OS4wODIgMjgwLjg5Miw1MDUuMDgyIDIxNy41LDQ5NkMgMTQxLjcyNyw0ODAuNTUxIDkwLjIyNjUsNDM2LjcxOCA2MywzNjQuNUMgNTUuOTA4MSwzNDAuOTg5IDUzLjU3NDgsMzE2Ljk4OSA1NiwyOTIuNUMgNjAuMDM4NCwyNTAuMzQ3IDcwLjAzODQsMjA5LjY4IDg2LDE3MC41QyA5Mi42NTA5LDE1NC41MTQgMTAxLjMxOCwxMzkuODQ4IDExMiwxMjYuNUMgMTIwLjcxNSwxMzYuODggMTI5LjA0OCwxNDcuNTQ3IDEzNywxNTguNUMgMTQwLjY4MiwxNjIuMzQ5IDE0NC41MTUsMTY2LjAxNiAxNDguNSwxNjkuNUMgMTc4LjkxNywxMDkuMTM2IDIxNS4yNTEsNTIuODAyOCAyNTcuNSwwLjUgWiIvPjwvZz4KPGc+PHBhdGggc3R5bGU9Im9wYWNpdHk6MSIgZmlsbD0iI2ZmOTc1OCIgZD0iTSAyNTAuNSw4MS41IEMgMjg3LjE5MywxMjQuMDYgMzIwLjM2LDE2OS4zOTMgMzUwLDIxNy41QyAzNTkuMjkzLDIzMy40MTggMzY2Ljk1OSwyNTAuMDg1IDM3MywyNjcuNUMgMzg1LjU4NCwzMTcuMDA4IDM3Mi4wODQsMzU3Ljg0MiAzMzIuNSwzOTBDIDI5NC4yMTYsNDE2LjkzOSAyNTIuMjE2LDQyNC45MzkgMjA2LjUsNDE0QyAxNTcuMjAxLDM5OC43MDIgMTI4LjcwMSwzNjUuNTM1IDEyMSwzMTQuNUMgMTE5LjEzMSwyOTguNDA5IDEyMC43OTgsMjgyLjc0MiAxMjYsMjY3LjVDIDEzMy40MTgsMjQ4LjY2MyAxNDIuNDE4LDIzMC42NjMgMTUzLDIxMy41QyAxNjMsMTk4LjgzMyAxNzMsMTg0LjE2NyAxODMsMTY5LjVDIDIwNS43MTYsMTQwLjI5IDIyOC4yMTYsMTEwLjk1NyAyNTAuNSw4MS41IFoiLz48L2c+Cjwvc3ZnPgo=",
693
+ url: "https://hono.dev",
694
+ tagline: "Fast, lightweight, built on web standards. Support for any JavaScript runtime.",
695
+ repo: "honojs/hono",
696
+ links: [
697
+ {
698
+ label: "Getting started",
699
+ href: "https://hono.dev/top"
700
+ },
701
+ {
702
+ label: "API",
703
+ href: "https://hono.dev/api/hono"
704
+ }
705
+ ]
706
+ },
707
+ {
708
+ category: "Server",
709
+ label: "h3",
710
+ flag: "h3",
711
+ url: "https://github.com/unjs/h3",
712
+ tagline: "Minimal H(TTP) framework built for high performance and portability",
713
+ repo: "unjs/h3"
714
+ },
715
+ {
716
+ category: "Server",
717
+ label: "Express",
718
+ flag: "express",
719
+ url: "https://expressjs.com",
720
+ spectrum: "beaten_path",
721
+ tagline: "Fast, unopinionated, minimalist web framework for Node.js",
722
+ repo: "expressjs/express",
723
+ links: [
724
+ {
725
+ label: "Getting started",
726
+ href: "https://expressjs.com/en/starter/installing.html"
727
+ },
728
+ {
729
+ label: "API",
730
+ href: "https://expressjs.com/en/4x/api.html"
731
+ }
732
+ ]
733
+ },
734
+ {
735
+ category: "Server",
736
+ label: "Fastify",
737
+ flag: "fastify",
738
+ image: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0nODQ5JyBoZWlnaHQ9JzU0NScgdmlld0JveD0nMCAwIDg0OSA1NDUnIGZpbGw9J25vbmUnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc+PHBhdGggZD0nTTgyMi4xOCA3Ny4zMkw4NDguOSA4LjExTDg0Ny43NSAzLjgzTDU4My40MSA3My40OEM2MTEuNTUgMzIuNyA2MDEuOSAwIDYwMS45IDBDNjAxLjkgMCA1MTcuNDkgNTMuOTEgNDUzLjY0IDUyLjQ5QzM4OS43OSA1MS4wNyAzNjkuMjMgMzQuMDUgMjcxLjMzIDY1LjI2QzE3My40MyA5Ni40NyAxNDUuNzcgMTkyLjI2IDExNy40IDIxMi44MUM4OS4wMyAyMzMuMzYgMCAzMDAuNDIgMCAzMDAuNDJMMC4xOTAwMDIgMzAxLjYyTDgwLjQ1IDI3Ni4wNkM4MC40NSAyNzYuMDYgNTguNDUgMjk2LjgxIDExLjY4IDM1OS44M0MxMS42OCAzNTkuODMgMTAuODYgMzU5LjA4IDkuNSAzNTcuODNMOS41NyAzNTguMjZDOS41NyAzNTguMjYgNDcuMTcgNDE1LjcyIDg0LjA2IDQwNS4wOEM4OC4zNzQ0IDQwMy43MzkgOTIuNTU1NSA0MDIuMDAxIDk2LjU1IDM5OS44OUMxMTEuNCA0MDguMTYgMTMwLjc5IDQxNi4yOSAxNTIuMiA0MTguNTNDMTQyLjU2OCA0MDcuMTIgMTMzLjY4OSAzOTUuMDk0IDEyNS42MiAzODIuNTNMMTM1LjYyIDM3Ni4wMkwxMzQuMDYgMzc3LjE0TDE2NC42MyAzODguMzZMMTYxLjIzIDM1OS42TDE2MS41MyAzNTkuNDFMMTkxLjUzIDM3MC40MUwxODcuNzkgMzQ0LjI4QzE5MS41OSAzNDIuMjggMTk1LjQgMzQwLjQxIDE5OS4xOSAzMzguNjVMMjMwLjU1IDIyMC4yNkwzNjAuMDEgMTMxLjk0TDM0OS43MyAxNTcuODNDMzIzLjQ3IDIyMi4zOSAyNzQuMTcgMjM3LjYgMjc0LjE3IDIzNy42TDI1My42IDI0NS40QzIzOC4yOSAyNjMuNDkgMjMxLjg2IDI2Ny45NCAyMjYuNiAzMjguNjVDMjM4LjkzIDMyNS41NCAyNTAuNzIgMzI0LjgyIDI2MS40IDMyNy42NUMzMTYuNzMgMzQyLjU1IDMzNS44OSA0MDkuMjMgMzIwLjk5IDQyNy42NUMzMTcuMjYgNDMyLjI3IDMwOC4zOCA0NDAuMTcgMjk3LjE3IDQ0OS40MkgyNzQuNzJMMjc0LjQzIDQ2Ny42MUwyNzIuMTIgNDY5LjQxSDI0OS4yOEwyNDguOTkgNDg3LjE2QzI0Ni45OSA0ODguNyAyNDQuOTkgNDkwLjIxIDI0Mi45OSA0OTEuNjhDMjIxLjUyIDQ5Mi4xMyAxOTQuMzQgNDczLjQxIDE5NC4zNCA0NzMuNDFDMTk0LjM0IDQ5MC40MSAyMDguNTMgNTE2LjY4IDIwOC41MyA1MTYuNjhMMjExLjA0IDUxNS40NkwyMDguODkgNTE3LjAzQzIwOC44OSA1MTcuMDMgMjY2LjM1IDU1NS4zNCAzMDIuNTIgNTQxLjE1QzMzNC43MiA1MjguNiA0MTcuOTkgNDYyLjk3IDQ4OS44OCA0MzEuOUw3MDcuNDIgMzc0LjZMNzM2LjExIDMwMC4yOUw1NzAuMzMgMzQzLjk1VjI3Ny4xOUw3NjQuOCAyMjUuOTVMNzkzLjQ5IDE1MS42TDU3MC4zMyAyMTAuNFYxNDMuNjhMODIyLjE4IDc3LjMyWk00MjcuMzYgMjE4Ljc5TDQ3OC45OCAyMDUuMTlMNDc5LjY3IDIwNy43OEw0NjMuNTUgMjQ5LjVMNDEwLjA3IDI2My42TDQyNy4zNiAyMTguNzlaTTQ0NS4xOCAzMDguMDlMMzkxLjY4IDMyMi4xOUw0MDguOTcgMjc3LjM4TDQ2MC41NSAyNjMuNzhMNDYxLjI0IDI2Ni4zN0w0NDUuMTggMzA4LjA5Wk01MTQuODkgMjkzLjA5TDQ2MS4zOCAzMDcuMTlMNDc4LjY4IDI2Mi4zOUw1MzAuMyAyNDguNzhMNTMwLjk5IDI1MS4zN0w1MTQuODkgMjkzLjA5WicgZmlsbD0nIzIxNUZGNicvPjwvc3ZnPgo=",
739
+ url: "https://fastify.dev",
740
+ tagline: "Fast and low overhead web framework, for Node.js",
741
+ repo: "fastify/fastify",
742
+ links: [
743
+ {
744
+ label: "Getting started",
745
+ href: "https://fastify.dev/docs/latest/Guides/Getting-Started/"
746
+ },
747
+ {
748
+ label: "API",
749
+ href: "https://fastify.dev/docs/latest/Reference/"
750
+ }
751
+ ]
752
+ },
753
+ {
754
+ category: "Server",
755
+ label: "HatTip",
756
+ flag: "hattip",
757
+ image: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB2aWV3Qm94PSIwIDAgMjYzIDIyOCIgc3R5bGU9ImZpbGwtcnVsZTpldmVub2RkO2NsaXAtcnVsZTpldmVub2RkO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDoyOyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8ZyBpZD0iSGF0VGlwTG9nbyIgdHJhbnNmb3JtPSJtYXRyaXgoMSwgMCwgMCwgMSwgMC43MTcxMDUsIDcuODg4MTU4KSI+CiAgICA8cGF0aCBkPSJNMzQuNjMsMTYyLjMxMWMtMCwwIC0xMi4xNjEsLTYxLjc4IC0xMi42NzksLTgxLjAxOGMwLC0wIDEuODkyLC01My4zNDIgNzUuMDU3LC02OC41OGMwLDAgNzkuMTcxLC0zMC4wNzYgMTA1LjUzOCwyNC4zMzZjMCwtMCAyMy4wNDMsNTcuMzIzIDI1LjM0LDc2Ljg5Yy0wLC0wIC01NC40NywzOS4wNzMgLTE5MS44MjEsNTQuMzY3bC0xLjQzNSwtNS45OTVaIiBzdHlsZT0iZmlsbDojMjMzNjNmO2ZpbGwtcnVsZTpub256ZXJvOyIvPgogICAgPHBhdGggZD0iTTM5LjI3NywxODEuNjkybC0zLjIxMiwtMTMuMzg2YzAsMCAxMjEuOTM0LC0xMS4yMzUgMTkxLjgyMSwtNTQuMzY3bDMuODg3LDE2LjIwNGMtMCwwIC04OS4xLDU5LjYzNyAtMTkyLjQ5Niw1MS41NDlaIiBzdHlsZT0iZmlsbDojMDRiNTc4O2ZpbGwtcnVsZTpub256ZXJvOyIvPgogICAgPHBhdGggZD0iTTMzLjg1MiwxNTguMDI0bDUuNDI1LDIzLjY2OGMtMCwtMCA4OS4wNTksMTEuMTM3IDE5Mi40OTYsLTUxLjU0OWwtMy44ODcsLTE2LjIwNGwyNC44ODksLTEyLjAwNmMwLDAgNy4yMzEsLTMuOTczIDQuNTI0LDcuNDgxYy0wLC0wIDEuNjM5LDU3Ljk1MyAtMTMwLjI1MSw4Ny4zMTRjLTEyNi43NTQsMjguMjE4IC0xMzEuMzg1LC0zMi41NzUgLTExNy4wOTQsLTM1LjYxM2wyMy44OTgsLTMuMDkxWiIgc3R5bGU9ImZpbGw6IzIzMzY0MDtmaWxsLXJ1bGU6bm9uemVybzsiLz4KICA8L2c+Cjwvc3ZnPg==",
758
+ url: "https://github.com/hattipjs/hattip",
759
+ spectrum: "bleeding_edge",
760
+ tagline: "Like Express, but for the future",
761
+ repo: "hattipjs/hattip"
762
+ },
763
+ // Database
764
+ {
765
+ category: "Database",
766
+ label: "Drizzle",
767
+ flag: "drizzle",
768
+ image: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgd2lkdGg9IjI4MHB4IiBoZWlnaHQ9IjI4MHB4IiBzdHlsZT0ic2hhcGUtcmVuZGVyaW5nOmdlb21ldHJpY1ByZWNpc2lvbjsgdGV4dC1yZW5kZXJpbmc6Z2VvbWV0cmljUHJlY2lzaW9uOyBpbWFnZS1yZW5kZXJpbmc6b3B0aW1pemVRdWFsaXR5OyBmaWxsLXJ1bGU6ZXZlbm9kZDsgY2xpcC1ydWxlOmV2ZW5vZGQiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4KPGc+PHBhdGggc3R5bGU9Im9wYWNpdHk6MSIgZmlsbD0iIzAwMDAwMCIgZD0iTSAtMC41LC0wLjUgQyA5Mi44MzMzLC0wLjUgMTg2LjE2NywtMC41IDI3OS41LC0wLjVDIDI3OS41LDkyLjgzMzMgMjc5LjUsMTg2LjE2NyAyNzkuNSwyNzkuNUMgMTg2LjE2NywyNzkuNSA5Mi44MzMzLDI3OS41IC0wLjUsMjc5LjVDIC0wLjUsMTg2LjE2NyAtMC41LDkyLjgzMzMgLTAuNSwtMC41IFoiLz48L2c+CjxnPjxwYXRoIHN0eWxlPSJvcGFjaXR5OjEiIGZpbGw9IiNjMWYyNGQiIGQ9Ik0gMTMzLjUsODQuNSBDIDE0Mi44MTQsODIuNzI2OSAxNDYuNjQ3LDg2LjM5MzUgMTQ1LDk1LjVDIDEzNS45MDYsMTEyLjAyOCAxMjYuNTcyLDEyOC4zNjIgMTE3LDE0NC41QyAxMTEuMjQ5LDE0OS45ODQgMTA2LjI0OSwxNDkuMzE3IDEwMiwxNDIuNUMgMTAxLjMzMywxNDAuODMzIDEwMS4zMzMsMTM5LjE2NyAxMDIsMTM3LjVDIDExMS41NDcsMTE5LjA0MSAxMjIuMDQ3LDEwMS4zNzUgMTMzLjUsODQuNSBaIi8+PC9nPgo8Zz48cGF0aCBzdHlsZT0ib3BhY2l0eToxIiBmaWxsPSIjYzBmMTRkIiBkPSJNIDIyMy41LDg0LjUgQyAyMzMuNTM5LDgzLjY5NzIgMjM3LjAzOSw4OC4wMzA1IDIzNCw5Ny41QyAyMjUuMzQ3LDExMi44MDEgMjE2LjY4MSwxMjguMTM1IDIwOCwxNDMuNUMgMjAzLjM4NywxNDkuNzM3IDE5OC4zODcsMTUwLjA3MSAxOTMsMTQ0LjVDIDE5MS41NzgsMTQxLjk3IDE5MS4yNDUsMTM5LjMwMyAxOTIsMTM2LjVDIDIwMC41MiwxMjIuNzk0IDIwOC41MiwxMDguNzk0IDIxNiw5NC41QyAyMTguMjg5LDkwLjg4MTIgMjIwLjc4OSw4Ny41NDc5IDIyMy41LDg0LjUgWiIvPjwvZz4KPGc+PHBhdGggc3R5bGU9Im9wYWNpdHk6MSIgZmlsbD0iI2MwZjE0ZCIgZD0iTSA3NS41LDEyMC41IEMgODMuOTg4NSwxMTkuNjE4IDg3LjgyMTgsMTIzLjI4NSA4NywxMzEuNUMgNzcuOTA1NywxNDguMDI4IDY4LjU3MjQsMTY0LjM2MiA1OSwxODAuNUMgNTYuMDQ1MywxODQuMjc3IDUyLjIxMiwxODUuNDQzIDQ3LjUsMTg0QyA0My44Njk3LDE4MC45NSA0Mi43MDMsMTc3LjExNyA0NCwxNzIuNUMgNTMsMTU2LjUgNjIsMTQwLjUgNzEsMTI0LjVDIDcyLjM5NjgsMTIyLjkzIDczLjg5NjgsMTIxLjU5NiA3NS41LDEyMC41IFoiLz48L2c+CjxnPjxwYXRoIHN0eWxlPSJvcGFjaXR5OjEiIGZpbGw9IiNjMWYyNGQiIGQ9Ik0gMTY1LjUsMTIwLjUgQyAxNzQuMTY0LDExOS4zMzIgMTc3Ljk5NywxMjIuOTk5IDE3NywxMzEuNUMgMTY3LjQxNCwxNDcuNjcxIDE1OC4wOCwxNjQuMDA0IDE0OSwxODAuNUMgMTQ2LjM5OCwxODQuMjEyIDE0Mi44OTgsMTg1LjM3OCAxMzguNSwxODRDIDEzMy45MzEsMTgxLjQ1OSAxMzIuNDMxLDE3Ny42MjUgMTM0LDE3Mi41QyAxNDMuNTcyLDE1Ni4zNjIgMTUyLjkwNiwxNDAuMDI4IDE2MiwxMjMuNUMgMTYzLjE0NSwxMjIuMzY0IDE2NC4zMTIsMTIxLjM2NCAxNjUuNSwxMjAuNSBaIi8+PC9nPgo8L3N2Zz4K",
769
+ url: "https://orm.drizzle.team/",
770
+ tagline: "Headless TypeScript ORM that feels like SPA with SSR",
771
+ repo: "drizzle-team/drizzle-orm",
772
+ links: [
773
+ {
774
+ label: "Docs & Getting started",
775
+ href: "https://orm.drizzle.team/docs/overview"
776
+ }
777
+ ]
778
+ },
779
+ {
780
+ category: "Database",
781
+ label: "SQLite",
782
+ flag: "sqlite",
783
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMTI4IDEyOCI+Cgk8ZGVmcz4KCQk8bGluZWFyR3JhZGllbnQgaWQ9ImRldmljb25TcWxpdGUwIiB4MT0iLTE1LjYxNSIgeDI9Ii02Ljc0MSIgeTE9Ii05LjEwOCIgeTI9Ii05LjEwOCIgZ3JhZGllbnRUcmFuc2Zvcm09InJvdGF0ZSg5MCAtOTAuNDg2IDY0LjYzNClzY2FsZSg5LjI3MTIpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CgkJCTxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iIzk1ZDdmNCIgLz4KCQkJPHN0b3Agb2Zmc2V0PSIuOTIiIHN0b3AtY29sb3I9IiMwZjdmY2MiIC8+CgkJCTxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzBmN2ZjYyIgLz4KCQk8L2xpbmVhckdyYWRpZW50PgoJPC9kZWZzPgoJPHBhdGggZmlsbD0iIzBiN2ZjYyIgZD0iTTY5LjUgOTkuMTc2Yy0uMDU5LS43My0uMDk0LTEuMi0uMDk0LTEuMlM2Ny4yIDgzLjA4NyA2NC41NyA3OC42NDJjLS40MTQtLjcwNy4wNDMtMy41OTQgMS4yMDctNy44OGMuNjggMS4xNjkgMy41NCA2LjE5MiA0LjExOCA3LjgxYy42NDggMS44MjQuNzggMi4zNDcuNzggMi4zNDdzLTEuNTctOC4wODItNC4xNDQtMTIuNzk3YTE2MiAxNjIgMCAwIDEgMi4wMDQtNi4yNjVjLjk3MyAxLjcxIDMuMzEzIDUuODU5IDMuODI4IDcuM2MuMTAyLjI5My4xOTIuNTQzLjI3Ljc3NGwuMDc0LS40MTRjLS41OS0yLjUwNC0xLjc1LTYuODYtMy4zMzYtMTAuMDgyYzMuNTItMTguMzI4IDE1LjUzMS00Mi44MjQgMjcuODQtNTMuNzU0SDE2LjljLTUuMzg3IDAtOS43ODkgNC40MDYtOS43ODkgOS43ODl2ODguNTdjMCA1LjM4MyA0LjQwNiA5Ljc4OSA5Ljc5IDkuNzg5aDUyLjg5N2ExMTkgMTE5IDAgMCAxLS4yOTctMTQuNjUyIiAvPgoJPHBhdGggZmlsbD0idXJsKCNkZXZpY29uU3FsaXRlMCkiIGQ9Ik02NS43NzcgNzAuNzYyYy42OCAxLjE2OCAzLjU0IDYuMTg4IDQuMTE3IDcuODA5Yy42NDkgMS44MjQuNzgxIDIuMzQ3Ljc4MSAyLjM0N3MtMS41Ny04LjA4Mi00LjE0NC0xMi43OTdhMTY1IDE2NSAwIDAgMSAyLjAwNC02LjI3Yy44ODcgMS41NjcgMi45MjIgNS4xNjkgMy42NTIgNi44NzJsLjA4Mi0uOTYxYy0uNjQ4LTIuNDk2LTEuNjMzLTUuNzY2LTIuODk4LTguMzI4YzMuMjQyLTE2Ljg3MSAxMy42OC0zOC45NyAyNC45MjYtNTAuODk4SDE2Ljg5OWE2Ljk0IDYuOTQgMCAwIDAtNi45MzQgNi45MzN2ODIuMTFjMTcuNTI3LTYuNzMxIDM4LjY2NC0xMi44OCA1Ni44NTUtMTIuNjE0Yy0uNjcyLTIuNjA1LTEuNDQxLTQuOTYtMi4yNS02LjMyNGMtLjQxNC0uNzA3LjA0My0zLjU5NyAxLjIwNy03Ljg3OSIgLz4KCTxwYXRoIGZpbGw9IiMwMDM5NTYiIGQ9Ik0xMTUuOTUgMi43ODFjLTUuNS00LjkwNi0xMi4xNjQtMi45MzMtMTguNzM0IDIuODk5YTQ0IDQ0IDAgMCAwLTIuOTE0IDIuODU5Yy0xMS4yNSAxMS45MjYtMjEuNjg0IDM0LjAyMy0yNC45MjYgNTAuODk1YzEuMjYyIDIuNTYzIDIuMjUgNS44MzIgMi44OTQgOC4zMjhjLjE2OC42NC4zMiAxLjI0Mi40NDIgMS43NTRjLjI4NSAxLjIwNy40MzcgMS45OTYuNDM3IDEuOTk2cy0uMTAxLS4zODMtLjUxNS0xLjU4MmMtLjA3OC0uMjMtLjE2OC0uNDg0LS4yNy0uNzczYTggOCAwIDAgMC0uMTcyLS40MzRjLS43MzQtMS43MDMtMi43NjUtNS4zMDUtMy42NTYtNi44NjdjLS43NjIgMi4yNS0xLjQzNyA0LjM2LTIuMDA0IDYuMjY1YzIuNTc4IDQuNzE1IDQuMTQ5IDEyLjc5NyA0LjE0OSAxMi43OTdzLS4xMzctLjUyMy0uNzgyLTIuMzQ3Yy0uNTc4LTEuNjIxLTMuNDQxLTYuNjQtNC4xMTctNy44MDljLTEuMTY0IDQuMjgxLTEuNjI1IDcuMTcyLTEuMjA3IDcuODhjLjgwOSAxLjM2MiAxLjU3NCAzLjcyMiAyLjI1IDYuMzIzYzEuNTI0IDUuODY3IDIuNTg2IDEzLjAxMiAyLjU4NiAxMy4wMTJzLjAzMS40NjkuMDk0IDEuMmExMTkgMTE5IDAgMCAwIC4yOTcgMTQuNjUxYy41MDQgNi4xMSAxLjQ1MyAxMS4zNjMgMi42NjQgMTQuMTcybC44MjgtLjQ0OWMtMS43ODEtNS41MzUtMi41MDQtMTIuNzkzLTIuMTg4LTIxLjE1NmMuNDgtMTIuNzkzIDMuNDIyLTI4LjIxNSA4Ljg1Ni00NC4yODljOS4xOTEtMjQuMjcgMjEuOTM4LTQzLjczOCAzMy42MDItNTMuMDM1Yy0xMC42MzMgOS42MDItMjUuMDIzIDQwLjY4NC0yOS4zMzIgNTIuMTk1Yy00LjgyIDEyLjg5MS04LjIzOCAyNC45ODQtMTAuMzAxIDM2LjU3NGMzLjU1LTEwLjg2MyAxNS4wNDctMTUuNTMgMTUuMDQ3LTE1LjUzczUuNjM3LTYuOTU4IDEyLjIyNy0xNi44ODhjLTMuOTUuOTAzLTEwLjQzIDIuNDQyLTEyLjU5OCAzLjM1MmMtMy4yIDEuMzQ0LTQuMDY3IDEuOC00LjA2NyAxLjhzMTAuMzcxLTYuMzEyIDE5LjI3LTkuMTcxYzEyLjIzNC0xOS4yNyAyNS41NjItNDYuNjQ4IDEyLjE0MS01OC42MjEiIC8+Cjwvc3ZnPg==",
784
+ url: "https://www.sqlite.org/",
785
+ tagline: "SQLite is a C-language library that implements a small, fast, self-contained, high-reliability, full-featured, SQL database engine",
786
+ repo: "sqlite/sqlite",
787
+ links: [
788
+ {
789
+ label: "better-sqlite3: API",
790
+ href: "https://github.com/WiseLibs/better-sqlite3/blob/master/docs/api.md"
791
+ },
792
+ {
793
+ label: "D1: Getting started",
794
+ href: "https://developers.cloudflare.com/d1/get-started/"
795
+ }
796
+ ]
797
+ },
798
+ {
799
+ category: "Database",
800
+ label: "Prisma",
801
+ flag: "prisma",
802
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIwLjgzZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjU2IDMxMCI+PHBhdGggZD0iTTI1NC4zMTMgMjM1LjUxOUwxNDggOS43NDlBMTcuMDYzIDE3LjA2MyAwIDAgMCAxMzMuNDczLjAzN2ExNi44NyAxNi44NyAwIDAgMC0xNS41MzMgOC4wNTJMMi42MzMgMTk0Ljg0OGExNy40NjUgMTcuNDY1IDAgMCAwIC4xOTMgMTguNzQ3TDU5LjIgMzAwLjg5NmExOC4xMyAxOC4xMyAwIDAgMCAyMC4zNjMgNy40ODlsMTYzLjU5OS00OC4zOTJhMTcuOTI5IDE3LjkyOSAwIDAgMCAxMS4yNi05LjcyMmExNy41NDIgMTcuNTQyIDAgMCAwLS4xMDEtMTQuNzZsLS4wMDguMDA4Wm0tMjMuODAyIDkuNjgzbC0xMzguODIzIDQxLjA1Yy00LjIzNSAxLjI2LTguMy0yLjQxMS03LjQxOS02LjY4NWw0OS41OTgtMjM3LjQ4NGMuOTI3LTQuNDQzIDcuMDYzLTUuMTQ3IDkuMDAzLTEuMDM1bDkxLjgxNCAxOTQuOTczYTYuNjMgNi42MyAwIDAgMS00LjE4IDkuMThoLjAwN1oiLz48L3N2Zz4=",
803
+ url: "https://www.prisma.io",
804
+ spectrum: "beaten_path",
805
+ tagline: "Next-generation Node.js and TypeScript ORM",
806
+ repo: "prisma/prisma",
807
+ links: [
808
+ {
809
+ label: "Getting started",
810
+ href: "https://www.prisma.io/docs/getting-started"
811
+ },
812
+ {
813
+ label: "Docs",
814
+ href: "https://www.prisma.io/docs"
815
+ }
816
+ ]
817
+ },
818
+ {
819
+ category: "Database",
820
+ label: "EdgeDB",
821
+ flag: "edgedb",
822
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyLjIxZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgNTEyIDIzMi43MjciPjxwYXRoIGZpbGw9IiM0RDRENEQiIGQ9Ik00MzMuNjY3IDExNS4yMzhjMCAzNS4zMzMtMTQuMTY3IDQxLjY2Ni0zMC4wMDIgNDEuNjY2SDM3MFY3My41NzFoMzMuNjY2YzE1LjgzNSAwIDMwLjAwMiA2LjMzNCAzMC4wMDIgNDEuNjY3Wm0tMTcuMTY3LjAwNGMwLTI0LjY2Ny03LjUtMjUuODMzLTE4LjMzMy0yNS44MzNoLTEwLjQ5OXY1MS42NjZoMTAuNWMxMC44MzMgMCAxOC4zMzItMS4xNjcgMTguMzMyLTI1LjgzM1ptLTE3OC4zMzYgNDEuNjYyVjczLjU3MWg1My4wMDF2MTUuODM0aC0zNS4zMzR2MTdoMjYuNjY2djE1LjY2NmgtMjYuNjY2djE5aDM1LjMzNHYxNS44MzNoLTUzWk0zMjAgMjMyLjcyN2gxNy40NTVWMEgzMjB2MjMyLjcyN1pNNDY4Ljk5NSAxMTkuOTF2MjEuMTY2aDE0LjY2OGM5LjE2NiAwIDExLjUtNiAxMS41LTEwLjVjMC0zLjUtMS42NjgtMTAuNjY2LTE0LjE2OC0xMC42NjZoLTEyWm0wLTMwLjUwMnYxNS44MzNoMTJjNi44MzMgMCAxMC44MzMtMyAxMC44MzMtOHMtNC03LjgzMy0xMC44MzMtNy44MzNoLTEyWk00NTEuMzM0IDczLjU3aDMzLjk5OGMxNy44MzYgMCAyMy4xNjggMTIuNSAyMy4xNjggMjEuNWMwIDguMzM0LTUuMzMyIDE0LjMzNC05IDE2YzEwLjY2NyA1LjE2NyAxMi41IDE1LjY2NyAxMi41IDIxYzAgNy0zLjUgMjQuODMzLTI2LjY2OCAyNC44MzNoLTMzLjk5OFY3My41NzFabS0zMTQuNjY1IDQxLjY2N2MwIDM1LjMzMy0xNC4xNjcgNDEuNjY2LTMwIDQxLjY2Nkg3My4wMDJWNzMuNTcxaDMzLjY2N2MxNS44MzMgMCAzMCA2LjMzNCAzMCA0MS42NjdabTUxLjk5NyAyNi41MDdjOSAwIDEzLjY2Ni0zIDE1LjMzMy01di05LjE2NmgtMTQuMzM0di0xNC4zMzRoMjguNXYzMy4xNjdjLTIuNSAzLjgzMy0xNi4xNjYgMTEuMzMzLTI4LjY2NiAxMS4zMzNjLTIwLjUgMC0zNy44MzMtOC0zNy44MzMtNDMuMzMzczE3LjUtNDEuNjY2IDMzLjMzMy00MS42NjZjMjQuODMzIDAgMzEgMTMgMzMgMjQuNWwtMTQuNjY3IDMuMzMzYy0uODMzLTUuMzM0LTUuNS0xMi0xNi4xNjYtMTJjLTEwLjgzNCAwLTE4LjMzNCAxLjE2Ni0xOC4zMzQgMjUuODMzYzAgMjQuNjY3IDcuODM0IDI3LjMzMyAxOS44MzQgMjcuMzMzWk0xMTkuNSAxMTUuMjQyYzAtMjQuNjY3LTcuNS0yNS44MzMtMTguMzMzLTI1LjgzM2gtMTAuNXY1MS42NjZoMTAuNWMxMC44MzMgMCAxOC4zMzMtMS4xNjcgMTguMzMzLTI1LjgzM1pNMCAxNTYuOTA0VjczLjU3MWg1M3YxNS44MzRIMTcuNjY3djE3aDI2LjY2NnYxNS42NjZIMTcuNjY3djE5SDUzdjE1LjgzM0gwWiIvPjwvc3ZnPg==",
823
+ url: "https://www.edgedb.com",
824
+ spectrum: "bleeding_edge",
825
+ tagline: "A graph-like schema with a relational core",
826
+ repo: "edgedb/edgedb",
827
+ links: [
828
+ {
829
+ label: "Getting started",
830
+ href: "https://www.edgedb.com/docs/intro/quickstart"
831
+ },
832
+ {
833
+ label: "Docs",
834
+ href: "https://www.edgedb.com/docs"
835
+ }
836
+ ]
837
+ },
838
+ // Analytics
839
+ {
840
+ category: "Analytics",
841
+ label: "Plausible.io",
842
+ flag: "plausible.io",
843
+ image: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8dGl0bGU+bG9nbzwvdGl0bGU+CiAgICA8ZGVmcz4KICAgICAgICA8cmFkaWFsR3JhZGllbnQgY3g9Ijc5LjEzMDUyNjMlIiBjeT0iODcuNjQ0ODE1OCUiIGZ4PSI3OS4xMzA1MjYzJSIgZnk9Ijg3LjY0NDgxNTglIiByPSI5Ni45ODk3NzYzJSIgaWQ9InJhZGlhbEdyYWRpZW50LTEiPgogICAgICAgICAgICA8c3RvcCBzdG9wLWNvbG9yPSIjMjQ0MEU2IiBvZmZzZXQ9IjAlIj48L3N0b3A+CiAgICAgICAgICAgIDxzdG9wIHN0b3AtY29sb3I9IiM1NjYxQjMiIG9mZnNldD0iMTAwJSI+PC9zdG9wPgogICAgICAgIDwvcmFkaWFsR3JhZGllbnQ+CiAgICAgICAgPHJhZGlhbEdyYWRpZW50IGN4PSIxLjUwNjEwNDU3ZS0wNSUiIGN5PSIzMC4yMTk4OTQxJSIgZng9IjEuNTA2MTA0NTdlLTA1JSIgZnk9IjMwLjIxOTg5NDElIiByPSI2Mi4yNjg4NzczJSIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSgwLjAwMDAwMCwwLjMwMjE5OSksc2NhbGUoMS4wMDAwMDAsMC43MjI1MTkpLHJvdGF0ZSg2MS43MzQ1MjIpLHRyYW5zbGF0ZSgtMC4wMDAwMDAsLTAuMzAyMTk5KSIgaWQ9InJhZGlhbEdyYWRpZW50LTIiPgogICAgICAgICAgICA8c3RvcCBzdG9wLWNvbG9yPSIjNjU3NENEIiBzdG9wLW9wYWNpdHk9IjAuNSIgb2Zmc2V0PSIwJSI+PC9zdG9wPgogICAgICAgICAgICA8c3RvcCBzdG9wLWNvbG9yPSIjNjU3NENEIiBvZmZzZXQ9IjEwMCUiPjwvc3RvcD4KICAgICAgICA8L3JhZGlhbEdyYWRpZW50PgogICAgPC9kZWZzPgogICAgPGcgaWQ9IlBhZ2UtMSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9ImxvZ28iPgogICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlIiB4PSIwIiB5PSIwIiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiPjwvcmVjdD4KICAgICAgICAgICAgPGcgaWQ9IkJpdG1hcCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMi41MzEwMTcsIDAuMDQ5NjI4KSIgZmlsbC1ydWxlPSJub256ZXJvIj4KICAgICAgICAgICAgICAgIDxnIGlkPSJHcm91cCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNy40Njg5ODMsIDkuOTY3NTIzKSBzY2FsZSgtMSwgMSkgcm90YXRlKC0xODAuMDAwMDAwKSB0cmFuc2xhdGUoLTcuNDY4OTgzLCAtOS45Njc1MjMpIHRyYW5zbGF0ZSgwLjAwMDAwMCwgMC4wMDAwMDApIj4KICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGlkPSJPdmFsIiBmaWxsPSJ1cmwoI3JhZGlhbEdyYWRpZW50LTEpIiBjeD0iNy40Njg5ODI2NCIgY3k9IjEyLjQ2NjA2MjciIHI9IjcuNDY4OTgyNjQiPjwvY2lyY2xlPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik02LjE4ODU4NTYyLDE5Ljg1MTExNjYgQzQuNjQ1MTYxMywxOS41ODMxMjY2IDMuMzQ0OTEzMTgsMTguOTI4MDM5NyAyLjI2Nzk5MDEsMTcuODc1OTMwNSBDMS4xNjEyOTAzNCwxNi43OTQwNDQ3IDAuNDc2NDI2ODE4LDE1LjUzMzQ5ODggMC4xNDM5MjA2MTUsMTMuOTYwMjk3OCBMMC4wMjk3NzY2OTQsMTMuNDI0MzE3NiBMMC4wMTQ4ODgzNTY2LDYuNzE0NjQwMTkgTDEuOTE2MDAwMDNlLTA4LC00LjkyOTM5MDIzZS0xNiBMMC4xMzg5NTc4MzYsLTQuOTI5MzkwMjNlLTE2IEMwLjIxODM2MjMwMiwtNC45MjkzOTAyM2UtMTYgMC40NzE0NjQwNCwwLjAyNDgxMzg5NTggMC42OTk3NTE4OCwwLjA0OTYyNzc5MTYgQzIuNjUwMTI0MDgsMC4yODc4NDExOTEgNC4zMDc2OTIzMiwxLjQ2ODk4MjYzIDUuMjEwOTE4MTQsMy4yNjA1NDU5MSBDNS40MzkyMDU5OCwzLjcxNzEyMTU5IDUuNjAyOTc3NjgsNC4yNDMxNzYxNyA1LjcxNzEyMTYsNC44OTgyNjMwMyBDNS44MTE0MTQ0Miw1LjQ1NDA5NDI5IDUuODE2Mzc3Miw1LjYzNzcxNzEzIDUuODAxNDg4ODYsOC41MzU5ODAxNSBMNS43ODY2MDA1MiwxMS41ODgwODkzIEw1LjkwNTcwNzIyLDExLjg4NTg1NjEgQzYuMDY5NDc4OTIsMTIuMjkyODA0IDYuNTIxMDkxODQsMTIuNzQ0NDE2OSA2LjkyODAzOTcyLDEyLjkwODE4ODYgTDcuMjI1ODA2NDgsMTMuMDI3Mjk1MyBMMTAuMDA0OTYyOCwxMy4wMzIyNTgxIEMxMS41MzM0OTg4LDEzLjAzMjI1ODEgMTIuODczNDQ5MiwxMy4wNTIxMDkyIDEyLjk3NzY2NzUsMTMuMDcxOTYwMyBDMTMuNDY0MDE5OSwxMy4xNjYyNTMxIDEzLjk4NTExMTcsMTMuNTczMjAxIDE0LjE5MzU0ODQsMTQuMDI0ODEzOSBDMTQuMjUzMTAxOCwxNC4xNDg4ODM0IDE0LjMzMjUwNjIsMTQuMzkyMDU5NiAxNC4zNjcyNDU3LDE0LjU1NTgzMTMgQzE0LjQyMTgzNjIsMTQuODI4Nzg0MSAxNC40MTY4NzM1LDE0LjkwMzIyNTggMTQuMzM3NDY5LDE1LjIxMDkxODEgQzE0LjA4OTMzLDE2LjEyNDA2OTUgMTMuMjE1ODgwOSwxNy4zODk1NzgyIDEyLjMyMjU4MDcsMTguMTI5MDMyMyBDMTEuMzEwMTczNywxOC45Njc3NDE5IDEwLjE5MzU0ODQsMTkuNTI4NTM2IDguOTg3NTkzMDgsMTkuODExNDE0NCBDOC4zNTIzNTczNCwxOS45NTUzMzUgNi45MTMxNTEzOCwxOS45ODAxNDg5IDYuMTg4NTg1NjIsMTkuODUxMTE2NiBaIiBpZD0iUGF0aCIgZmlsbD0idXJsKCNyYWRpYWxHcmFkaWVudC0yKSI+PC9wYXRoPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=",
844
+ url: "https://plausible.io",
845
+ tagline: "Easy to use and privacy-friendly Google Analytics alternative",
846
+ repo: "plausible/analytics"
847
+ },
848
+ {
849
+ category: "Analytics",
850
+ label: "Google Analytics",
851
+ flag: "google-analytics",
852
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIwLjkxZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjU2IDI4NCI+PHBhdGggZmlsbD0iI0Y5QUIwMCIgZD0iTTI1Ni4wMDMgMjQ3LjkzM2EzNS4yMjQgMzUuMjI0IDAgMCAxLTM5LjM3NiAzNS4xNjFjLTE4LjA0NC0yLjY3LTMxLjI2Ni0xOC4zNzEtMzAuODI2LTM2LjYwNlYzNi44NDVDMTg1LjM2NSAxOC41OTEgMTk4LjYyIDIuODgxIDIxNi42ODcuMjRhMzUuMjIxIDM1LjIyMSAwIDAgMSAzOS4zMTYgMzUuMTZ2MjEyLjUzM1oiLz48cGF0aCBmaWxsPSIjRTM3NDAwIiBkPSJNMzUuMTAxIDIxMy4xOTNjMTkuMzg2IDAgMzUuMTAxIDE1LjcxNiAzNS4xMDEgMzUuMTAxYzAgMTkuMzg2LTE1LjcxNSAzNS4xMDEtMzUuMTAxIDM1LjEwMVMwIDI2Ny42OCAwIDI0OC4yOTVjMC0xOS4zODYgMTUuNzE1LTM1LjEwMiAzNS4xMDEtMzUuMTAyWm05Mi4zNTgtMTA2LjM4N2MtMTkuNDc3IDEuMDY4LTM0LjU5IDE3LjQwNi0zNC4xMzcgMzYuOTA4djk0LjI4NWMwIDI1LjU4OCAxMS4yNTkgNDEuMTIyIDI3Ljc1NSA0NC40MzNhMzUuMTYxIDM1LjE2MSAwIDAgMCA0Mi4xNDYtMzQuNTZWMTQyLjA4OWEzNS4yMjIgMzUuMjIyIDAgMCAwLTM1Ljc2NC0zNS4yODJaIi8+PC9zdmc+",
853
+ url: "https://analytics.google.com/"
854
+ },
855
+ {
856
+ category: "Analytics",
857
+ label: "Segment",
858
+ flag: "segment",
859
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIwLjk3ZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjU2IDI2NSI+PHBhdGggZmlsbD0iIzRGQjU4QiIgZD0ibTIzMy41NiAxNDEuOTI3bC4xNy4wMTNsMTcuODkyIDEuODdhNC45MjcgNC45MjcgMCAwIDEgMy4yMjUgMS43MDdsLjEzMy4xNjNsLS4xNy4wODVhNC45MyA0LjkzIDAgMCAxIDEuMDIgMy43NGExMzMuMjcyIDEzMy4yNzIgMCAwIDEtNDEuNjA0IDgxLjA4M2ExMjguODYgMTI4Ljg2IDAgMCAxLTg3LjYyOSAzNC4zOGExMjcuNDg4IDEyNy40ODggMCAwIDEtNDYuMTU2LTguNTdsLS44MDItLjMxMmE0LjcxNiA0LjcxNiAwIDAgMS0yLjY4Ni0yLjUzM2wtLjA3Ny0uMTg3YTQuODkxIDQuODkxIDAgMCAxLS4wODMtMy42Nmw3LjA2Mi0xNy4yM2E0Ljg0NiA0Ljg0NiAwIDAgMSA2LjExOC0yLjc5OWwuMTYzLjA2YzM2LjA5NyAxMy45MzkgNzYuOTggNi4wODkgMTA1LjM0OS0yMC4yMjdhMTA0LjQ1NSAxMDQuNDU1IDAgMCAwIDMyLjg5MS02My4zMmE0LjkzIDQuOTMgMCAwIDEgNS4wMTMtNC4yN2wuMTcuMDA3Wm0tMTkwLjA4IDY0LjMxbC4yNTEtLjAwMmwuMjUzLjAwMmM4LjEyLjA5MyAxNC42NTggNi42NTkgMTQuNzQ2IDE0Ljc0OXYuMjUzYzAgLjA4NCAwIC4xNjgtLjAwMi4yNTJjLS4xNDEgOC4yODQtNi45NyAxNC44ODYtMTUuMjU0IDE0Ljc0NWMtOC4yODQtLjE0MS0xNC44ODUtNi45Ny0xNC43NDUtMTUuMjU0Yy4xMzktOC4xMTUgNi42OTUtMTQuNjE1IDE0Ljc1LTE0Ljc0NVpNNC45MyAxNDcuMDgyaDE0Ni4zMTZhNC45NzMgNC45NzMgMCAwIDEgNC45MjggNC44NDRsLjAwMi4xNzF2MTguMzE2YTQuOTc0IDQuOTc0IDAgMCAxLTQuNzYgNS4wMWwtLjE3LjAwNUg0LjkzQTQuOTc1IDQuOTc1IDAgMCAxIDAgMTcwLjU4NHYtMTguNjU5YTQuOTc1IDQuOTc1IDAgMCAxIDQuNzU1LTQuODM4bC4xNzUtLjAwNVpNMTY5LjU2IDcuMzExYTQuOTc0IDQuOTc0IDAgMCAxIDIuODQ4IDIuNjM1YTUuMDk2IDUuMDk2IDAgMCAxIDAgMy44NjdsLTYuMzc1IDE2Ljk5OWE0Ljg0NSA0Ljg0NSAwIDAgMS02LjE2MiAyLjk3NEExMDEuMjI4IDEwMS4yMjggMCAwIDAgNjIuMTMgNTEuMjUyYTEwNS4yNjcgMTA1LjI2NyAwIDAgMC0zNC41MDcgNTQuOTlhNC45MyA0LjkzIDAgMCAxLTQuNzYgMy42OThoLTEuMTA1TDQuMjUgMTA1LjczM2E0Ljg4NiA0Ljg4NiAwIDAgMS0zLjEwMy0yLjI5NWgtLjA4NUE0LjkyOSA0LjkyOSAwIDAgMSAuNTEgOTkuNTdhMTMzLjM5MyAxMzMuMzkzIDAgMCAxIDQ0LjQxLTcwLjIwNEM3OS43MzkuNyAxMjcuMDE5LTcuNjY2IDE2OS41NiA3LjMxMVptLTY0LjgwNyA3My40MzRIMjUxLjA3YTQuOTcyIDQuOTcyIDAgMCAxIDQuOTIyIDQuNjdsLjAwOC4xNzR2MTguMzE3YTQuOTczIDQuOTczIDAgMCAxLTQuNzYgNS4wMWwtLjE3LjAwNUgxMDQuNzU0YTQuOTcyIDQuOTcyIDAgMCAxLTQuODg2LTQuODQybC0uMDAyLS4xNzNWODUuNzU5YTQuOTcyIDQuOTcyIDAgMCAxIDQuNzE1LTUuMDA4bC4xNzMtLjAwNlptMTAxLjU3Mi01NS44ODNsLjI1Mi0uMDAybC4yNTMuMDAyYzguMTIuMDkzIDE0LjY1OCA2LjY1OSAxNC43NDYgMTQuNzQ4di4yNTNjMCAuMDg1IDAgLjE3LS4wMDIuMjUzYy0uMTQgOC4yODQtNi45NyAxNC44ODUtMTUuMjU0IDE0Ljc0NGMtOC4yODQtLjE0LTE0Ljg4NS02Ljk3LTE0Ljc0NC0xNS4yNTNjLjEzOC04LjExNiA2LjY5NC0xNC42MTYgMTQuNzQ5LTE0Ljc0NVoiLz48L3N2Zz4=",
860
+ url: "https://segment.com",
861
+ disabled: true
862
+ },
863
+ // Hosting
864
+ {
865
+ category: "Hosting",
866
+ label: "Cloudflare",
867
+ flag: "cloudflare",
868
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyLjE5ZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjU2IDExNyI+PHBhdGggZmlsbD0iI2ZiYWQ0MSIgZD0iTTIwNS41MiA1MC44MTNjLS44NTggMC0xLjcwNS4wMy0yLjU1MS4wNThxLS4yMDcuMDEyLS4zOTguMDk0YTEuNDIgMS40MiAwIDAgMC0uOTIuOTk0bC0zLjYyOCAxMi42NzJjLTEuNTY1IDUuNDQ5LS45ODMgMTAuNDggMS42NDYgMTQuMTc0YzIuNDEgMy40MTYgNi40MiA1LjQyMSAxMS4yODkgNS42NTVsMTkuNjc5IDEuMTk0Yy41ODUuMDMgMS4wOTIuMzEyIDEuNC43NzZhMS45MiAxLjkyIDAgMCAxIC4yIDEuNjkyYTIuNSAyLjUgMCAwIDEtMi4xMzQgMS42NjJsLTIwLjQ0OCAxLjE5M2MtMTEuMTEuNTE1LTIzLjA2MiA5LjU4LTI3LjI1NSAyMC42MzNsLTEuNDc0IDMuOWExLjA5MiAxLjA5MiAwIDAgMCAuOTY3IDEuNDloNzAuNDI1YTEuODcgMS44NyAwIDAgMCAxLjgxLTEuMzY1QTUxLjIgNTEuMiAwIDAgMCAyNTYgMTAxLjgyOGMwLTI4LjE2LTIyLjU4Mi01MC45ODQtNTAuNDQ5LTUwLjk4NCIvPjxwYXRoIGZpbGw9IiNmNjgyMWYiIGQ9Im0xNzQuNzgyIDExNS4zNjJsMS4zMDMtNC41ODNjMS41NjgtNS40NDkuOTg3LTEwLjQ4LTEuNjM5LTE0LjE3M2MtMi40MTgtMy40MTctNi40MjQtNS40MjItMTEuMjk2LTUuNjU2bC05Mi4zMTItMS4xOTNhMS44MiAxLjgyIDAgMCAxLTEuNDU5LS43NzZhMS45MiAxLjkyIDAgMCAxLS4yMDMtMS42OTNhMi41IDIuNSAwIDAgMSAyLjE1NC0xLjY2Mmw5My4xNzMtMS4xOTNjMTEuMDYzLS41MTEgMjMuMDE1LTkuNTggMjcuMjA4LTIwLjYzM2w1LjMxMy0xNC4wNGMuMjE0LS41OTYuMjctMS4yMzguMTU2LTEuODZDMTkxLjEyNiAyMC41MSAxNjYuOTEgMCAxMzcuOTYgMEMxMTEuMjY5IDAgODguNjI2IDE3LjQwMyA4MC41IDQxLjU5NmEyNyAyNyAwIDAgMC0xOS4xNTYtNS4zNTlDNDguNTQ5IDM3LjUyNCAzOC4yNSA0Ny45NDYgMzYuOTc5IDYwLjg4YTI3LjkgMjcuOSAwIDAgMCAuNzAyIDkuNjQyQzE2Ljc3MyA3MS4xNDUgMCA4OC40NTQgMCAxMDkuNzI2YzAgMS45MjMuMTM3IDMuODE4LjQxMyA1LjY2N2MuMTE1Ljg5Ny44NzkgMS41NyAxLjc4MyAxLjU2OGgxNzAuNDhhMi4yMiAyLjIyIDAgMCAwIDIuMTA2LTEuNjMiLz48L3N2Zz4=",
869
+ url: "https://pages.cloudflare.com/",
870
+ tagline: "Create full-stack applications that are instantly deployed to the Cloudflare global network",
871
+ repo: "cloudflare/workers-sdk",
872
+ links: [
873
+ {
874
+ label: "Docs",
875
+ href: "https://developers.cloudflare.com/pages/"
876
+ },
877
+ {
878
+ label: "Vike integration",
879
+ href: "https://vike.dev/cloudflare-pages#full-stack"
880
+ },
881
+ {
882
+ label: "vike-cloudflare",
883
+ href: "https://github.com/vikejs/vike-cloudflare"
884
+ }
885
+ ]
886
+ },
887
+ {
888
+ category: "Hosting",
889
+ label: "Vercel",
890
+ flag: "vercel",
891
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxLjE2ZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjU2IDIyMiI+PHBhdGggZD0ibTEyOCAwbDEyOCAyMjEuNzA1SDB6Ii8+PC9zdmc+",
892
+ url: "https://vercel.com",
893
+ tagline: "Develop with your favorite tools. Launch globally, instantly. Keep pushing",
894
+ repo: "vercel/vercel",
895
+ links: [
896
+ {
897
+ label: "Guides",
898
+ href: "https://vercel.com/guides"
899
+ },
900
+ {
901
+ label: "Docs",
902
+ href: "https://vercel.com/docs"
903
+ }
904
+ ]
905
+ },
906
+ {
907
+ category: "Hosting",
908
+ label: "Netlify",
909
+ flag: "netlify",
910
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxLjE0ZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjU2IDIyNiI+PHBhdGggZmlsbD0iIzA1QkRCQSIgZD0iTTY5LjE4MSAxODguMDg3aC0yLjQxN2wtMTIuMDY1LTEyLjA2NXYtMi40MTdsMTguNDQ0LTE4LjQ0NGgxMi43NzhsMS43MDQgMS43MDR2MTIuNzc4ek01NC42OTkgNTEuNjI4di0yLjQxN2wxMi4wNjUtMTIuMDY1aDIuNDE3TDg3LjYyNSA1NS41OXYxMi43NzhsLTEuNzA0IDEuNzA0SDczLjE0M3oiLz48cGF0aCBmaWxsPSIjMDE0ODQ3IiBkPSJNMTYwLjkwNiAxNDkuMTk4aC0xNy41NTJsLTEuNDY2LTEuNDY2di00MS4wODljMC03LjMxLTIuODczLTEyLjk3Ni0xMS42ODktMTMuMTc0Yy00LjUzNy0uMTE5LTkuNzI3IDAtMTUuMjc0LjIxOGwtLjgzMy44NTJ2NTMuMTczbC0xLjQ2NiAxLjQ2Nkg5NS4wNzRsLTEuNDY2LTEuNDY2di03MC4xOWwxLjQ2Ni0xLjQ2N2gzOS41MDNjMTUuMzU0IDAgMjcuNzk1IDEyLjQ0MSAyNy43OTUgMjcuNzk1djQzLjg4MmwtMS40NjYgMS40NjZaIi8+PHBhdGggZmlsbD0iIzA1QkRCQSIgZD0iTTcxLjY3NyAxMjIuODg5SDEuNDY2TDAgMTIxLjQyM1YxMDMuODNsMS40NjYtMS40NjZoNzAuMjExbDEuNDY2IDEuNDY2djE3LjU5M3ptMTgyLjg1NyAwaC03MC4yMTFsLTEuNDY2LTEuNDY2VjEwMy44M2wxLjQ2Ni0xLjQ2Nmg3MC4yMTFMMjU2IDEwMy44M3YxNy41OTN6TTExNy44NzYgNTQuMTI0VjEuNDY2TDExOS4zNDIgMGgxNy41OTNsMS40NjYgMS40NjZ2NTIuNjU4bC0xLjQ2NiAxLjQ2NmgtMTcuNTkzem0wIDE2OS42NjN2LTUyLjY1OGwxLjQ2Ni0xLjQ2NmgxNy41OTNsMS40NjYgMS40NjZ2NTIuNjU4bC0xLjQ2NiAxLjQ2NWgtMTcuNTkzeiIvPjwvc3ZnPg==",
911
+ url: "https://www.netlify.com",
912
+ disabled: true
913
+ },
914
+ {
915
+ category: "Hosting",
916
+ label: "AWS",
917
+ flag: "aws",
918
+ image: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iODBweCIgaGVpZ2h0PSI4MHB4IiB2aWV3Qm94PSIwIDAgODAgODAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDY0ICg5MzUzNykgLSBodHRwczovL3NrZXRjaC5jb20gLS0+CiAgICA8dGl0bGU+SWNvbi1BcmNoaXRlY3R1cmUvNjQvQXJjaF9BV1MtQ2xvdWQtRGV2ZWxvcG1lbnQtS2l0XzY0PC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+CiAgICAgICAgPGxpbmVhckdyYWRpZW50IHgxPSIwJSIgeTE9IjEwMCUiIHgyPSIxMDAlIiB5Mj0iMCUiIGlkPSJsaW5lYXJHcmFkaWVudC0xIj4KICAgICAgICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iIzJFMjdBRCIgb2Zmc2V0PSIwJSI+PC9zdG9wPgogICAgICAgICAgICA8c3RvcCBzdG9wLWNvbG9yPSIjNTI3RkZGIiBvZmZzZXQ9IjEwMCUiPjwvc3RvcD4KICAgICAgICA8L2xpbmVhckdyYWRpZW50PgogICAgPC9kZWZzPgogICAgPGcgaWQ9Ikljb24tQXJjaGl0ZWN0dXJlLzY0L0FyY2hfQVdTLUNsb3VkLURldmVsb3BtZW50LUtpdF82NCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9Ikljb24tQXJjaGl0ZWN0dXJlLUJHLzY0L0RldmVsb3Blci1Ub29scyIgZmlsbD0idXJsKCNsaW5lYXJHcmFkaWVudC0xKSI+CiAgICAgICAgICAgIDxyZWN0IGlkPSJSZWN0YW5nbGUiIHg9IjAiIHk9IjAiIHdpZHRoPSI4MCIgaGVpZ2h0PSI4MCI+PC9yZWN0PgogICAgICAgIDwvZz4KICAgICAgICA8cGF0aCBkPSJNNjgsMzkuMzA1NTI0OSBDNjgsNDYuMjM0NzA3OCA2My4yNjYyNDk1LDQ4Ljc3NjA0MTMgNjAuNDQ1MjU1OSw0OS42NzQ4MDU2IEw1OS44NDU3MjAzLDQ3Ljc2ODMwNTYgQzYyLjY1OTc2NTcsNDYuODcyNTQwNSA2Ni4wMTQ3ODI4LDQ0LjY3NzExNjIgNjYuMDE0NzgyOCwzOS4zMDU1MjQ5IEM2Ni4wMTQ3ODI4LDMyLjUxNDMwNTggNjAuNDU2MTc0NiwzMC44MTg3NTA1IDU4LjA2Njk2NTYsMzAuNDA0ODU5IEM1Ny41MzM5MzQ4LDMwLjMxMjg4MzEgNTcuMTczNjE3OSwyOS44MDgwMTU1IDU3LjI1MzAyNjYsMjkuMjcwMTU2NiBMNTcuMjUzMDI2NiwyOS4yNzAxNTY2IEM1Ny4wMTY3ODU3LDI2LjE3NTk2OCA1NS41Nzc1MDMyLDIzLjk1MDU1MTYgNTMuMzkwNzg2NSwyMy4zMDY3MjA0IEM1MS41NzQzMTI3LDIyLjc3Mjg2MDQgNDkuNjIyODQ0MiwyMy40ODA2NzQ4IDQ4LjQyNTc1ODIsMjUuMTE0MjQ2NCBDNDguMjA4Mzc2OSwyNS40MTExNjg2IDQ3Ljg0MTExMTcsMjUuNTYyMTI5IDQ3LjQ4MDc5NDgsMjUuNTA5MTQyOSBDNDcuMTE3NSwyNS40NTUxNTcgNDYuODEzNzYxOCwyNS4yMDIyMjM0IDQ2LjY5MTY3MSwyNC44NTMzMTQ5IEM0NS44NjY4MTMyLDIyLjUwMzkzMSA0NC42NzE3MTI0LDIwLjUyNzQ0OTMgNDMuMTQwMTE3MywxOC45Nzg4NTU0IEM0MS4yNjAxMTY2LDE3LjA3OTM1MzUgMzYuMTAyNTIyMywxMi45OTQ0MjQ4IDI4LjgxMjgwNDcsMTYuMTAxNjA5OSBDMjQuNjAzMTUxNSwxNy44OTcxMzkxIDIxLjMwNTcwNTcsMjMuMDY5NzgyNiAyMS4zMDU3MDU3LDI3Ljg3NjUyMjEgQzIxLjMwNTcwNTcsMjguNDExMzgxOCAyMS4zMzc0NjkyLDI4Ljk1MDI0MDUgMjEuNDAwOTk2MiwyOS40NzkxMDE4IEMyMS40NTk1NjAxLDI5Ljk3Njk3MTIgMjEuMTQyOTE3OSwzMC40NDE4NDkzIDIwLjY2MDUxMDEsMzAuNTY1ODE2OCBDMTguMTY3MDc3MywzMS4yMDY2NDg4IDEzLjk4NTIxNzIsMzMuMTgyMTMwNyAxMy45ODUyMTcyLDM5LjIyMTU0NjkgQzEzLjk4NTIxNzIsMzkuNDE3NDk1NSAxMy45OTAxODAzLDM5LjYwOTQ0NTIgMTQuMDAwMTA2NCwzOS43OTgzOTU2IEMxNC4xODY3MTY4LDQzLjY4NjM3NiAxNy4wMjc1NjI2LDQ3LjAyNjUwMDEgMjAuOTEwNjQ3NSw0Ny45MjMyNjUgTDIwLjQ2NTk1ODgsNDkuODcxNzU0IEMxNS43MjEyODk3LDQ4Ljc3NTA0MTYgMTIuMjQ2MTY2OSw0NC42NzQxMTcgMTIuMDE2ODc0MywzOS44OTgzNjk0IEMxMi4wMDQ5NjMsMzkuNjgwNDI2NiAxMiwzOS40NTI0ODY0IDEyLDM5LjIyMTU0NjkgQzEyLDMyLjMxNDM1ODMgMTYuNjM3NDY3NCwyOS43NjcwMjYzIDE5LjM1MjI1MiwyOC44NjkyNjE3IEMxOS4zMzE0MDcyLDI4LjUzODM0ODUgMTkuMzIwNDg4NSwyOC4yMDY0MzU1IDE5LjMyMDQ4ODUsMjcuODc2NTIyMSBDMTkuMzIwNDg4NSwyMi4yMzQwMDE4IDIzLjA2ODU3ODYsMTYuMzgwNTM2OCAyOC4wMzk1NjI1LDE0LjI2MDA5MjkgQzMzLjg2NDE4OTksMTEuNzc0NzQ0NiA0MC4wMzYyMzAyLDEzLjAxMTQyMDMgNDQuNTQ1NjUxMSwxNy41NjcyMjU2IEM0NS45NDgyMDcxLDE4Ljk4NDg1MzggNDcuMDk3NjQ3OSwyMC43MDQ0MDI5IDQ3Ljk3NDEyMTMsMjIuNjk0ODgwOSBDNDkuNjQyNjk2NCwyMS4yODIyNTEzIDUxLjg0OTI2NTMsMjAuNzcwMzg1NiA1My45NDc2Mzk5LDIxLjM4ODIyMzYgQzU2LjgyNjIwNDksMjIuMjM1MDAxNSA1OC43NTI4NTgyLDI0LjkwNjMwMSA1OS4xODI2NTc3LDI4LjU5NDMzMzggQzYxLjk5ODY4ODMsMjkuMjU3MTYgNjgsMzEuNTgwNTUwNyA2OCwzOS4zMDU1MjQ5IEw2OCwzOS4zMDU1MjQ5IFogTTU2Ljg5ODY2NTMsNjEuMzEzNzUzNCBMNDkuOTYzMzA4OSw2NS4xOTk3MzQzIEw0OS45NjMzMDg5LDU2LjU1NDAwMTYgTDU2Ljg5ODY2NTMsNTIuNjEyMDM1NCBMNTYuODk4NjY1Myw2MS4zMTM3NTM0IFogTTM5LjAwNzg4NzcsNjEuMjg4NzYgTDMyLjA4NzQyMDUsNjUuMjc2NzE0MiBMMzIuMDg3NDIwNSw1Ni41MjAwMTA1IEwzOS4wMDc4ODc3LDUyLjU5MDA0MTEgTDM5LjAwNzg4NzcsNjEuMjg4NzYgWiBNMzEuMDkxODM0LDU0Ljc5MDQ2NDEgTDI0LjE2OTM4MTYsNTAuOTA1NDgyOSBMMzEuMTAzNzQ1Myw0Ny4wMjA1MDE3IEwzNy45NzE2MDQzLDUwLjg4MjQ4ODkgTDMxLjA5MTgzNCw1NC43OTA0NjQxIFogTTIzLjEyMTE4NjksNTIuNjA2MDM2OSBMMzAuMTAyMjAzMiw1Ni41MjQwMDk1IEwzMC4xMDIyMDMyLDY1LjI4MTcxMjggTDIzLjEyMTE4NjksNjEuMjg2NzYwNSBMMjMuMTIxMTg2OSw1Mi42MDYwMzY5IFogTTQwLjAyOTI4MiwzMi4wNTM0MjY3IEw0Ni45MTEwMzc1LDM1Ljg5ODQxODQgTDQwLjAwMDQ5NjMsMzkuNzYzNDA0OCBMMzMuMTQ0NTQ4NiwzNS45MTg0MTMxIEw0MC4wMjkyODIsMzIuMDUzNDI2NyBaIE00Mi4wMzIzNjYxLDUwLjg4NDQ4ODQgTDQ4Ljk1NDgxODYsNDcuMDA0NTA1OSBMNTUuODY1MzU5Nyw1MC45MDM0ODM0IEw0OC45NzA3MDAzLDU0LjgyMjQ1NTcgTDQyLjAzMjM2NjEsNTAuODg0NDg4NCBaIE00MC45OTMxMDQ5LDUyLjU4OTA0MTQgTDQ3Ljk3ODA5MTcsNTYuNTU0MDAxNiBMNDcuOTc4MDkxNyw2NS4xOTk3MzQzIEw0MC45OTMxMDQ5LDYxLjI4MDc2MjEgTDQwLjk5MzEwNDksNTIuNTg5MDQxNCBaIE00Ny45NjQxOTUyLDQ1LjI3MTk2MDIgTDQwLjk5MzEwNDksNDkuMTc3OTM1OSBMNDAuOTkzMTA0OSw0MS40OTQ5NTA3IEw0Ny45NjQxOTUyLDM3LjU5Njk3MjkgTDQ3Ljk2NDE5NTIsNDUuMjcxOTYwMiBaIE0zMi4wOTczNDY1LDM3LjYxODk2NzIgTDM5LjAwNzg4NzcsNDEuNDkzOTUxIEwzOS4wMDc4ODc3LDQ5LjE3NDkzNjcgTDMyLjA5NzM0NjUsNDUuMjg4OTU1OCBMMzIuMDk3MzQ2NSwzNy42MTg5NjcyIFogTTU4LjM5MTU0ODYsNTAuMDM2NzEwNyBDNTguMzg2NTg1Niw1MC4wMzM3MTE1IDU4LjM4MDYzLDUwLjAzMjcxMTggNTguMzc1NjY2OSw1MC4wMjk3MTI2IEw1OC4zNzY2NTk1LDUwLjAyNzcxMzEgTDQ5Ljk0OTQxMjQsNDUuMjczOTU5NyBMNDkuOTQ5NDEyNCwzNS44OTg0MTg0IEM0OS45NDk0MTI0LDM1LjU0MzUxMTQgNDkuNzYzNzk0NiwzNS4yMTY1OTcyIDQ5LjQ2MDA1NjQsMzUuMDM2NjQ0NCBDNDkuNDUyMTE1NSwzNS4wMzI2NDU0IDQ5LjQ0NTE2NzIsMzUuMDMwNjQ1OSA0OS40MzcyMjY0LDM1LjAyNjY0NyBMNDkuNDM5MjExNiwzNS4wMjM2NDc4IEw0MC41MTA2OTcxLDMwLjAzNTk1NTggQzQwLjIwODk0NDEsMjkuODY4OTk5NSAzOS44NDM2NjQxLDI5Ljg2ODk5OTUgMzkuNTQ1ODgxNiwzMC4wMzY5NTU1IEwzMC42MjIzMzAxLDM1LjA0NTY0MiBMMzAuNjIzMzIyOCwzNS4wNDc2NDE1IEMzMC42MTYzNzQ1LDM1LjA1MTY0MDQgMzAuNjA4NDMzNiwzNS4wNTI2NDAyIDMwLjYwMTQ4NTQsMzUuMDU2NjM5MSBDMzAuMjk4NzM5NywzNS4yMzY1OTE5IDMwLjExMjEyOTMsMzUuNTY0NTA1OSAzMC4xMTIxMjkzLDM1LjkxODQxMzEgTDMwLjExMjEyOTMsNDUuMjg2OTU2MyBMMjEuNjQ2MTcwNSw1MC4wMzA3MTIzIEwyMS42NDgxNTU3LDUwLjAzMjcxMTggQzIxLjY0MDIxNDgsNTAuMDM2NzEwNyAyMS42MzIyNzQsNTAuMDM4NzEwMiAyMS42MjUzMjU3LDUwLjA0MjcwOTIgQzIxLjMyMjU4MDEsNTAuMjIxNjYyMiAyMS4xMzU5Njk3LDUwLjU1MDU3NiAyMS4xMzU5Njk3LDUwLjkwNDQ4MzIgTDIxLjEzNTk2OTcsNjEuODY4NjA3OSBDMjEuMTM1OTY5Nyw2Mi4yMjg1MTM1IDIxLjMyNzU0MzEsNjIuNTYwNDI2NSAyMS42MzgyMjk2LDYyLjczNzM4MDEgTDMwLjU5NjUyMjMsNjcuODY1MDM1NCBMMzAuNjA0NDYzMiw2Ny44NzAwMzQxIEwzMC42MDQ0NjMyLDY3Ljg2OTAzNDMgQzMwLjc1NzMyNDksNjcuOTU2MDExNSAzMC45MjYwNjg0LDY4IDMxLjA5NDgxMTgsNjggQzMxLjI2NDU0NzksNjggMzEuNDM1Mjc2Niw2Ny45NTYwMTE1IDMxLjU4ODEzODMsNjcuODY4MDM0NiBMNDAuMDA3NDQ0Niw2My4wMTYzMDY5IEw0OC40ODgyOTI1LDY3Ljc3NDA1OTMgTDQ4LjQ4OTI4NTEsNjcuNzcxMDYgQzQ4LjYzOTE2OSw2Ny44NTUwMzggNDguODAzOTQyMSw2Ny45MDAwMjYyIDQ4Ljk3MDcwMDMsNjcuOTAwMDI2MiBDNDkuMTM2NDY2LDY3LjkwMDAyNjIgNDkuMzAzMjI0Miw2Ny44NTgwMzcyIDQ5LjQ1MzEwODEsNjcuNzc0MDU5MyBMNTguMzc0Njc0Myw2Mi43NzUzNzAxIEM1OC42ODkzMzEyLDYyLjU5ODQxNjUgNTguODgzODgyNSw2Mi4yNjQ1MDQxIDU4Ljg4Mzg4MjUsNjEuOTAxNTk5MyBMNTguODgzODgyNSw1MC45MDA0ODQyIEM1OC44ODM4ODI1LDUwLjU0NDU3NzUgNTguNjk3MjcyMSw1MC4yMTY2NjM1IDU4LjM5MTU0ODYsNTAuMDM2NzEwNyBMNTguMzkxNTQ4Niw1MC4wMzY3MTA3IFoiIGlkPSJBV1MtQ2xvdWQtRGV2ZWxvcG1lbnQtS2l0X0ljb25fNjRfU3F1aWQiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4KICAgIDwvZz4KPC9zdmc+",
919
+ url: "https://aws.amazon.com",
920
+ tagline: "Deploy to AWS Lambda with Infrastructure as Code with the AWS CDK",
921
+ repo: "aws/aws-cdk",
922
+ links: [
923
+ {
924
+ label: "Docs",
925
+ href: "https://github.com/aws/aws-cdk"
926
+ }
927
+ ]
928
+ },
929
+ // Linter
930
+ {
931
+ category: "Linter",
932
+ label: "ESLint",
933
+ flag: "eslint",
934
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxLjE0ZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjU2IDIyNSI+PHBhdGggZmlsbD0iIzgwODBGMiIgZD0ibTc3Ljk2NSA4MC41NjhsNDguNTctMjguMDQyYTMuOTI5IDMuOTI5IDAgMCAxIDMuOTMgMGw0OC41NyAyOC4wNDJBMy45MzIgMy45MzIgMCAwIDEgMTgxIDgzLjk3MXY1Ni4wODRjMCAxLjQwMy0uNzUgMi43LTEuOTY1IDMuNDAzbC00OC41NyAyOC4wNDJhMy45MjkgMy45MjkgMCAwIDEtMy45MyAwbC00OC41Ny0yOC4wNDJBMy45MzEgMy45MzEgMCAwIDEgNzYgMTQwLjA1NVY4My45N2MuMDAxLTEuNDA0Ljc1LTIuNyAxLjk2NS0zLjQwMyIvPjxwYXRoIGZpbGw9IiM0QjMyQzMiIGQ9Ik0yNTQuNDE3IDEwNy40MTdMMTk2LjMyMyA2LjM1QzE5NC4yMTMgMi42OTYgMTkwLjMxNSAwIDE4Ni4wOTUgMEg2OS45MDZjLTQuMjIgMC04LjEyIDIuNjk2LTEwLjIzIDYuMzVMMS41ODMgMTA3LjE5NGMtMi4xMSAzLjY1NS0yLjExIDguMjY4IDAgMTEuOTIzbDU4LjA5MyAxMDAuMjM5YzIuMTEgMy42NTQgNi4wMSA1LjUyMiAxMC4yMyA1LjUyMmgxMTYuMTg4YzQuMjIgMCA4LjExOS0xLjgxMiAxMC4yMjgtNS40NjdsNTguMDk0LTEwMC40MDJjMi4xMTItMy42NTMgMi4xMTItNy45MzggMC0xMS41OTJabS00OC4xMDUgNDguNmMwIDEuNDg1LS44OTQgMi44Ni0yLjE4MiAzLjYwNGwtNzMuOTk5IDQyLjY5M2E0LjIxIDQuMjEgMCAwIDEtNC4xODYgMGwtNzQuMDU2LTQyLjY5M2MtMS4yODctLjc0NC0yLjE4OC0yLjExOC0yLjE4OC0zLjYwNVY3MC42MjhjMC0xLjQ4Ny44ODgtMi44NiAyLjE3Ni0zLjYwNGw3My45OTUtNDIuNjk0YTQuMjAyIDQuMjAyIDAgMCAxIDQuMTg1IDBsNzQuMDYgNDIuNjk0YzEuMjg5Ljc0NCAyLjE5NSAyLjExNyAyLjE5NSAzLjYwNHY4NS4zODhaIi8+PC9zdmc+",
935
+ url: "https://eslint.org",
936
+ tagline: "Find and fix problems in your JavaScript code",
937
+ repo: "eslint/eslint",
938
+ links: [
939
+ {
940
+ label: "Docs",
941
+ href: "https://eslint.org/docs/latest/"
942
+ }
943
+ ]
944
+ },
945
+ {
946
+ category: "Linter",
947
+ label: "Prettier",
948
+ flag: "prettier",
949
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjU2IDI1NiI+PHJlY3Qgd2lkdGg9IjI0LjM4MSIgaGVpZ2h0PSIxMi4xOSIgeD0iMTgyLjg1NyIgeT0iNDguNzYyIiBmaWxsPSIjNTZCM0I0IiByeD0iNSIvPjxyZWN0IHdpZHRoPSI3My4xNDMiIGhlaWdodD0iMTIuMTkiIHk9IjI0My44MSIgZmlsbD0iI0VBNUU1RSIgcng9IjUiLz48cmVjdCB3aWR0aD0iNDguNzYyIiBoZWlnaHQ9IjEyLjE5IiB4PSIxNDYuMjg2IiB5PSIxNDYuMjg2IiBmaWxsPSIjQkY4NUJGIiByeD0iNSIvPjxyZWN0IHdpZHRoPSI2MC45NTIiIGhlaWdodD0iMTIuMTkiIHg9IjczLjE0MyIgeT0iMTQ2LjI4NiIgZmlsbD0iI0VBNUU1RSIgcng9IjUiLz48cmVjdCB3aWR0aD0iNjAuOTUyIiBoZWlnaHQ9IjEyLjE5IiB5PSIxNDYuMjg2IiBmaWxsPSIjNTZCM0I0IiByeD0iNSIvPjxyZWN0IHdpZHRoPSI3My4xNDMiIGhlaWdodD0iMTIuMTkiIHk9IjE5NS4wNDgiIGZpbGw9IiNCRjg1QkYiIHJ4PSI1Ii8+PHJlY3Qgd2lkdGg9IjczLjE0MyIgaGVpZ2h0PSIxMi4xOSIgeT0iOTcuNTI0IiBmaWxsPSIjQkY4NUJGIiByeD0iNSIvPjxyZWN0IHdpZHRoPSIxMzQuMDk1IiBoZWlnaHQ9IjEyLjE5IiB4PSI2MC45NTIiIHk9IjI0LjM4MSIgZmlsbD0iI0Y3QkEzRSIgcng9IjUiLz48cmVjdCB3aWR0aD0iNDguNzYyIiBoZWlnaHQ9IjEyLjE5IiB5PSIyNC4zODEiIGZpbGw9IiNFQTVFNUUiIHJ4PSI1Ii8+PHJlY3Qgd2lkdGg9IjI0LjM4MSIgaGVpZ2h0PSIxMi4xOSIgeD0iNDguNzYyIiB5PSIyMTkuNDI5IiBmaWxsPSIjRjdCQTNFIiByeD0iNSIvPjxyZWN0IHdpZHRoPSIyNC4zODEiIGhlaWdodD0iMTIuMTkiIHg9IjQ4Ljc2MiIgeT0iNzMuMTQzIiBmaWxsPSIjNTZCM0I0IiByeD0iNSIvPjxyZWN0IHdpZHRoPSIzNi41NzEiIGhlaWdodD0iMTIuMTkiIHk9IjIxOS40MjkiIGZpbGw9IiM1NkIzQjQiIHJ4PSI1Ii8+PHJlY3Qgd2lkdGg9IjM2LjU3MSIgaGVpZ2h0PSIxMi4xOSIgeT0iNzMuMTQzIiBmaWxsPSIjRjdCQTNFIiByeD0iNSIvPjxyZWN0IHdpZHRoPSIyNC4zODEiIGhlaWdodD0iMTIuMTkiIHg9IjE1OC40NzYiIHk9IjIxOS40MjkiIGZpbGw9IiNEMEQ0RDgiIG9wYWNpdHk9Ii41IiByeD0iNSIvPjxyZWN0IHdpZHRoPSI2MC45NTIiIGhlaWdodD0iMTIuMTkiIHg9Ijg1LjMzMyIgeT0iMjE5LjQyOSIgZmlsbD0iI0QwRDREOCIgb3BhY2l0eT0iLjUiIHJ4PSI1Ii8+PHJlY3Qgd2lkdGg9IjYwLjk1MiIgaGVpZ2h0PSIxMi4xOSIgeD0iMTk1LjA0OCIgeT0iMjE5LjQyOSIgZmlsbD0iI0QwRDREOCIgb3BhY2l0eT0iLjUiIHJ4PSI1Ii8+PHJlY3Qgd2lkdGg9IjEwOS43MTQiIGhlaWdodD0iMTIuMTkiIHg9Ijk3LjUyNCIgeT0iMTIxLjkwNSIgZmlsbD0iIzU2QjNCNCIgcng9IjUiLz48cmVjdCB3aWR0aD0iNDguNzYyIiBoZWlnaHQ9IjEyLjE5IiB4PSIzNi41NzEiIHk9IjEyMS45MDUiIGZpbGw9IiNGN0JBM0UiIHJ4PSI1Ii8+PHJlY3Qgd2lkdGg9IjI0LjM4MSIgaGVpZ2h0PSIxMi4xOSIgeT0iMTIxLjkwNSIgZmlsbD0iI0VBNUU1RSIgcng9IjUiLz48cmVjdCB3aWR0aD0iNjAuOTUyIiBoZWlnaHQ9IjEyLjE5IiB4PSIxMDkuNzE0IiB5PSI0OC43NjIiIGZpbGw9IiNCRjg1QkYiIHJ4PSI1Ii8+PHJlY3Qgd2lkdGg9Ijk3LjUyNCIgaGVpZ2h0PSIxMi4xOSIgeT0iNDguNzYyIiBmaWxsPSIjNTZCM0I0IiByeD0iNSIvPjxyZWN0IHdpZHRoPSIxMjEuOTA1IiBoZWlnaHQ9IjEyLjE5IiB4PSIzNi41NzEiIHk9IjE3MC42NjciIGZpbGw9IiNGN0JBM0UiIHJ4PSI1Ii8+PHJlY3Qgd2lkdGg9IjI0LjM4MSIgaGVpZ2h0PSIxMi4xOSIgeT0iMTcwLjY2NyIgZmlsbD0iI0JGODVCRiIgcng9IjUiLz48cmVjdCB3aWR0aD0iNzMuMTQzIiBoZWlnaHQ9IjEyLjE5IiB4PSIxNDYuMjg2IiB5PSI3My4xNDMiIGZpbGw9IiNFQTVFNUUiIHJ4PSI1Ii8+PHJlY3Qgd2lkdGg9IjczLjE0MyIgaGVpZ2h0PSIxMi4xOSIgeD0iMTQ2LjI4NiIgeT0iOTcuNTI0IiBmaWxsPSIjRjdCQTNFIiByeD0iNSIvPjxyZWN0IHdpZHRoPSIxNTguNDc2IiBoZWlnaHQ9IjEyLjE5IiBmaWxsPSIjNTZCM0I0IiByeD0iNSIvPjxyZWN0IHdpZHRoPSI4NS4zMzMiIGhlaWdodD0iMTIuMTkiIHg9IjE3MC42NjciIGZpbGw9IiNEMEQ0RDgiIG9wYWNpdHk9Ii41IiByeD0iNSIvPjxyZWN0IHdpZHRoPSIzNi41NzEiIGhlaWdodD0iMTIuMTkiIHg9IjE3MC42NjciIHk9IjE3MC42NjciIGZpbGw9IiNEMEQ0RDgiIG9wYWNpdHk9Ii41IiByeD0iNSIvPjxyZWN0IHdpZHRoPSIzNi41NzEiIGhlaWdodD0iMTIuMTkiIHg9IjIxOS40MjkiIHk9IjE3MC42NjciIGZpbGw9IiNEMEQ0RDgiIG9wYWNpdHk9Ii41IiByeD0iNSIvPjxyZWN0IHdpZHRoPSI0OC43NjIiIGhlaWdodD0iMTIuMTkiIHg9IjIwNy4yMzgiIHk9IjE0Ni4yODYiIGZpbGw9IiNEMEQ0RDgiIG9wYWNpdHk9Ii41IiByeD0iNSIvPjxyZWN0IHdpZHRoPSI0OC43NjIiIGhlaWdodD0iMTIuMTkiIHg9IjIwNy4yMzgiIHk9IjI0LjM4MSIgZmlsbD0iI0QwRDREOCIgb3BhY2l0eT0iLjUiIHJ4PSI1Ii8+PHJlY3Qgd2lkdGg9IjM2LjU3MSIgaGVpZ2h0PSIxMi4xOSIgeD0iMjE5LjQyOSIgeT0iMTIxLjkwNSIgZmlsbD0iI0QwRDREOCIgb3BhY2l0eT0iLjUiIHJ4PSI1Ii8+PHJlY3Qgd2lkdGg9IjM2LjU3MSIgaGVpZ2h0PSIxMi4xOSIgeD0iMjE5LjQyOSIgeT0iNDguNzYyIiBmaWxsPSIjRDBENEQ4IiBvcGFjaXR5PSIuNSIgcng9IjUiLz48cmVjdCB3aWR0aD0iMjQuMzgxIiBoZWlnaHQ9IjEyLjE5IiB4PSIyMzEuNjE5IiB5PSI3My4xNDMiIGZpbGw9IiNEMEQ0RDgiIG9wYWNpdHk9Ii41IiByeD0iNSIvPjxyZWN0IHdpZHRoPSIyNC4zODEiIGhlaWdodD0iMTIuMTkiIHg9IjIzMS42MTkiIHk9Ijk3LjUyNCIgZmlsbD0iI0QwRDREOCIgb3BhY2l0eT0iLjUiIHJ4PSI1Ii8+PHJlY3Qgd2lkdGg9IjEyMS45MDUiIGhlaWdodD0iMTIuMTkiIHg9IjEzNC4wOTUiIHk9IjE5NS4wNDgiIGZpbGw9IiNEMEQ0RDgiIG9wYWNpdHk9Ii41IiByeD0iNSIvPjxyZWN0IHdpZHRoPSIzNi41NzEiIGhlaWdodD0iMTIuMTkiIHg9Ijg1LjMzMyIgeT0iMTk1LjA0OCIgZmlsbD0iI0QwRDREOCIgb3BhY2l0eT0iLjUiIHJ4PSI1Ii8+PHJlY3Qgd2lkdGg9IjczLjE0MyIgaGVpZ2h0PSIxMi4xOSIgeD0iMTgyLjg1NyIgeT0iMjQzLjgxIiBmaWxsPSIjRDBENEQ4IiBvcGFjaXR5PSIuNSIgcng9IjUiLz48cmVjdCB3aWR0aD0iODUuMzMzIiBoZWlnaHQ9IjEyLjE5IiB4PSI4NS4zMzMiIHk9IjI0My44MSIgZmlsbD0iI0QwRDREOCIgb3BhY2l0eT0iLjUiIHJ4PSI1Ii8+PHJlY3Qgd2lkdGg9IjQ4Ljc2MiIgaGVpZ2h0PSIxMi4xOSIgeD0iODUuMzMzIiB5PSI3My4xNDMiIGZpbGw9IiNEMEQ0RDgiIG9wYWNpdHk9Ii41IiByeD0iNSIvPjxyZWN0IHdpZHRoPSI0OC43NjIiIGhlaWdodD0iMTIuMTkiIHg9Ijg1LjMzMyIgeT0iOTcuNTI0IiBmaWxsPSIjRDBENEQ4IiBvcGFjaXR5PSIuNSIgcng9IjUiLz48L3N2Zz4=",
950
+ url: "https://prettier.io",
951
+ tagline: "An opinionated code formatter",
952
+ repo: "prettier/prettier",
953
+ links: [
954
+ {
955
+ label: "Docs",
956
+ href: "https://prettier.io/docs/en/"
957
+ }
958
+ ]
959
+ },
960
+ {
961
+ category: "Linter",
962
+ label: "Biome",
963
+ flag: "biome",
964
+ image: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAnLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4nICdodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQnPjxzdmcgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyB2ZXJzaW9uPScxLjEnIHdpZHRoPSc0OHB4JyBoZWlnaHQ9JzQ4cHgnIHN0eWxlPSdzaGFwZS1yZW5kZXJpbmc6Z2VvbWV0cmljUHJlY2lzaW9uOyB0ZXh0LXJlbmRlcmluZzpnZW9tZXRyaWNQcmVjaXNpb247IGltYWdlLXJlbmRlcmluZzpvcHRpbWl6ZVF1YWxpdHk7IGZpbGwtcnVsZTpldmVub2RkOyBjbGlwLXJ1bGU6ZXZlbm9kZCcgeG1sbnM6eGxpbms9J2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsnPjxnPjxwYXRoIHN0eWxlPSdvcGFjaXR5OjEnIGZpbGw9JyNlNWIxMWMnIGQ9J00gMzEuNSw0MS41IEMgMjguODMzMyw0MS41IDI2LjE2NjcsNDEuNSAyMy41LDQxLjVDIDIzLjUsMzguODMzMyAyMy41LDM2LjE2NjcgMjMuNSwzMy41QyAyNS4yNjQ2LDMyLjUzODYgMjcuMjY0NiwzMi4yMDUzIDI5LjUsMzIuNUMgMjkuNzczMywzMC41NDkgMjkuMTA2NiwyOS4wNDkgMjcuNSwyOEMgMjMuODQ4NCwyNy41MDE0IDIwLjE4MTcsMjcuMzM0NyAxNi41LDI3LjVDIDE2LjUsMzIuNSAxNi41LDM3LjUgMTYuNSw0Mi41QyAxMy4xNjY3LDQyLjUgOS44MzMzMyw0Mi41IDYuNSw0Mi41QyA2LjUsMzQuNSA2LjUsMjYuNSA2LjUsMTguNUMgMTMuNSwxOC41IDIwLjUsMTguNSAyNy41LDE4LjVDIDI4LjU4NjIsMTguMzggMjkuMjUyOCwxNy43MTMzIDI5LjUsMTYuNUMgMjkuNDU3MywxNS41ODM2IDI5LjEyMzksMTQuOTE2OSAyOC41LDE0LjVDIDIxLjQ5MjEsMTQuNjY2MyAxNC40OTIxLDE0LjQ5OTYgNy41LDE0QyA2LjU0OTQ4LDEwLjk0MzMgNi4yMTYxNCw3Ljc3NjU5IDYuNSw0LjVDIDE0Ljg0LDQuMzMzNiAyMy4xNzMzLDQuNTAwMjcgMzEuNSw1QyAzOS44NjA5LDkuMjUxNDYgNDEuNTI3NSwxNS4yNTE1IDM2LjUsMjNDIDQxLjc1NiwyOC41OTM1IDQxLjc1NiwzNC4yNjAyIDM2LjUsNDBDIDM0Ljk3NTEsNDEuMDA4NiAzMy4zMDg0LDQxLjUwODYgMzEuNSw0MS41IFonLz48L2c+PGc+PHBhdGggc3R5bGU9J29wYWNpdHk6MC42ODInIGZpbGw9JyM5MjhlMzYnIGQ9J00gMjguNSwxNC41IEMgMjkuMTIzOSwxNC45MTY5IDI5LjQ1NzMsMTUuNTgzNiAyOS41LDE2LjVDIDI5LjI1MjgsMTcuNzEzMyAyOC41ODYyLDE4LjM4IDI3LjUsMTguNUMgMjguMjM0MSwxNy4yOTIxIDI4LjU2NzQsMTUuOTU4NyAyOC41LDE0LjUgWicvPjwvZz48Zz48cGF0aCBzdHlsZT0nb3BhY2l0eTowLjc1OCcgZmlsbD0nI2M0YTMyMycgZD0nTSAyMy41LDMzLjUgQyAyMy41LDM2LjE2NjcgMjMuNSwzOC44MzMzIDIzLjUsNDEuNUMgMjYuMTY2Nyw0MS41IDI4LjgzMzMsNDEuNSAzMS41LDQxLjVDIDI4LjcxMzEsNDIuNDc2NyAyNS43MTMxLDQyLjgxIDIyLjUsNDIuNUMgMjIuMTksMzkuMjg2OSAyMi41MjMzLDM2LjI4NjkgMjMuNSwzMy41IFonLz48L2c+PC9zdmc+Cg==",
965
+ url: "https://biomejs.dev",
966
+ spectrum: "bleeding_edge"
967
+ },
968
+ // Error tracking
969
+ {
970
+ category: "Error tracking",
971
+ label: "Sentry",
972
+ flag: "sentry",
973
+ image: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxLjEzZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjU2IDIyNyI+PHBhdGggZmlsbD0iIzM2MkQ1OSIgZD0iTTE0OC4zNjggMTIuNDAzYTIzLjkzNSAyMy45MzUgMCAwIDAtNDEuMDAzIDBMNzMuNjQgNzAuMTY1YzUyLjQyNiAyNi4xNzQgODcuMDUgNzguMTc3IDkwLjk3NSAxMzYuNjQyaC0yMy42NzljLTMuOTE4LTUwLjExMy0zNC4wNjEtOTQuNDEtNzkuMjM4LTExNi40NDhsLTMxLjIxMyA1My45N2E4MS41OTUgODEuNTk1IDAgMCAxIDQ3LjMwNyA2Mi4zNzVoLTU0LjM4YTMuODk1IDMuODk1IDAgMCAxLTMuMTc4LTUuNjlsMTUuMDY5LTI1LjYyNmE1NS4wNDYgNTUuMDQ2IDAgMCAwLTE3LjIyMS05LjczOEwzLjE2NyAxOTEuMjc3YTIzLjI2OSAyMy4yNjkgMCAwIDAgOC42NjIgMzEuOTgyYTIzLjg4NCAyMy44ODQgMCAwIDAgMTEuNTgzIDMuMDc1aDc0LjQ3MWE5OS40MzIgOTkuNDMyIDAgMCAwLTQxLjAwMy04OC43MmwxMS44NC0yMC41YzM1LjY3OSAyNC41MDQgNTUuNzU0IDY2LjAzOCA1Mi43OSAxMDkuMjJoNjMuMDk0YzIuOTktNjUuNDMtMjkuMDQ3LTEyNy41MTItODQuMTA3LTE2Mi45ODZsMjMuOTM1LTQxLjAwMmEzLjk0NyAzLjk0NyAwIDAgMSA1LjM4Mi0xLjM4NGMyLjcxNiAxLjQ4NiAxMDMuOTkzIDE3OC4yMDggMTA1Ljg5IDE4MC4yNThhMy44OTUgMy44OTUgMCAwIDEtMy40ODYgNS43OTJoLTI0LjM5NmMuMzA3IDYuNTI2LjMwNyAxMy4wMzUgMCAxOS41MjhoMjQuNDk5QTIzLjUyOCAyMy41MjggMCAwIDAgMjU2IDIwMi45MWEyMy4wMTUgMjMuMDE1IDAgMCAwLTMuMTc4LTExLjY4NUwxNDguMzY4IDEyLjQwM1oiLz48L3N2Zz4=",
974
+ url: "https://sentry.io"
975
+ },
976
+ {
977
+ category: "Error tracking",
978
+ label: "Logrocket",
979
+ flag: "logrocket",
980
+ image: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAuMDAgMC4wMCAxMTQ2LjAwIDE3ODMuMDAiPgo8cGF0aCBmaWxsPSIjNzE1MmExIiBkPSIKICBNIDM3Mi4yNCAxMjc5Ljc3CiAgUSAzNDYuNTQgMTI5OC44OCAzMjIuMTggMTMxOS42OAogIEMgMjkyLjkwIDEzNDQuNjYgMjYzLjgwIDEzNjkuNzYgMjM0LjEzIDEzOTQuMjkKICBDIDIwMi45MyAxNDIwLjA5IDE3NS40MyAxNDU1LjExIDEzMC4zNCAxNDQ3LjYyCiAgQyAxMDEuNDYgMTQ0Mi44MyA3NS4xMCAxNDIzLjM2IDY4LjE3IDEzOTMuOTYKICBDIDQ3LjM2IDEzMDUuNzggMjYuNDMgMTIxNy42MiA2LjQ0IDExMjkuMjUKICBRIDMuNjAgMTExNi42OCAyLjU1IDExMDkuNjQKICBDIC04Ljg3IDEwMzIuNDMgMjMuMTAgOTU1LjU1IDgzLjQ3IDkwNi44OQogIFEgMTM0Ljk3IDg2NS4zOCAxODcuNTMgODI1LjIxCiAgQyAxOTEuNDkgODIyLjE4IDE5My4yMSA4MTkuMDYgMTkyLjkxIDgxNC4yNQogIEMgMTc5LjY3IDYwMy40MyAyNDguMjYgMzk5LjYwIDM2MS40NiAyMjQuMjAKICBDIDM4My43MiAxODkuNjkgNDA4LjY2IDE1Ni40NyA0MzUuMDcgMTIzLjU3CiAgQyA0NzMuODUgNzUuMjQgNTE3LjU1IDMyLjM2IDU3MC42NiAwLjYwCiAgQSAwLjgxIDAuODAgLTQ1LjMgMCAxIDU3MS41MCAwLjU5CiAgQyA2NDguNjkgNDYuMTcgNzA1LjA0IDExNi4wMCA3NTYuNzcgMTg4LjU0CiAgUSA3NjIuODYgMTk3LjA3IDc2OC4yMSAyMDQuOTUKICBDIDg4OS44MiAzODQuMTEgOTY0LjI0IDYwMC4xNyA5NDkuNTkgODE4LjczCiAgQSAwLjk5IDAuOTggMjEuNSAwIDAgOTQ5Ljk1IDgxOS41NQogIEMgOTkyLjA4IDg1My4zOSAxMDM4LjgyIDg4OC43OSAxMDcyLjIxIDkxNy4wMwogIFEgMTA4OC4xMCA5MzAuNDYgMTEwMy42MyA5NTIuMzQKICBRIDExNDYuNzYgMTAxMy4wOSAxMTQ1LjI5IDEwODcuMjQKICBDIDExNDUuMDIgMTEwMS4wNiAxMTQyLjgyIDExMTQuMTUgMTEzOS42OCAxMTI5LjQ4CiAgQyAxMTIxLjQzIDEyMTguNzMgMTEwMi4yMSAxMzE1LjQ2IDEwODMuOTMgMTM5Ni45MwogIEMgMTA3My41NCAxNDQzLjIwIDEwMTMuNzMgMTQ2My4wMiA5NzQuNjAgMTQ0Mi4xMwogIFEgOTY4LjY2IDE0MzguOTYgOTU4LjcwIDE0MzAuODMKICBDIDg5Ni40OCAxMzc5Ljk2IDgzNC42MiAxMzI4LjcwIDc3Mi40OSAxMjc3Ljg5CiAgQSAwLjg1IDAuODQgNDMuMyAwIDAgNzcxLjM4IDEyNzcuOTIKICBDIDcxOS4xMSAxMzI1LjgyIDY1Mi4zMyAxMzU0Ljg4IDU4MS40NSAxMzU3LjY4CiAgQyA1MDUuMTMgMTM2MC42OSA0MzAuMjkgMTMzMC43MyAzNzMuMTQgMTI3OS44MQogIEEgMC43MSAwLjcxIDAuMCAwIDAgMzcyLjI0IDEyNzkuNzcKICBaCiAgTSA0MDkuOTcgNTkyLjcwCiAgQyA0MjEuNDggNjg1LjIxIDUwNy45OSA3NDIuODggNTk5LjI0IDcyOC40NgogIEMgNjM1LjgyIDcyMi42OCA2NjguMDcgNzA1LjQ4IDY5Mi45NCA2NzguNDQKICBDIDc1MC40OCA2MTUuODUgNzQ2LjQ4IDUyMC4yNiA2ODQuMTkgNDYyLjU1CiAgUSA2MzkuMjEgNDIwLjg5IDU3Ni4wMSA0MTguNjEKICBDIDQ4MC42NyA0MTUuMTggMzk3Ljg4IDQ5NS40NSA0MDkuOTcgNTkyLjcwCiAgWiIKLz4KPGVsbGlwc2UgZmlsbD0iIzcxNTJhMSIgY3g9IjAuMDAiIGN5PSIwLjAwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg1NjkuODYsNTc2LjU1KSByb3RhdGUoLTAuMSkiIHJ4PSI3OS41MCIgcnk9Ijc2LjQ1Ii8+CjxwYXRoIGZpbGw9IiM3MTUyYTEiIGQ9IgogIE0gNDYyLjgzIDE2MTkuNzkKICBBIDAuNzAgMC43MCAwLjAgMCAwIDQ2MS43MiAxNjE5LjYyCiAgUSA0NDguMTIgMTYzMy4wMCA0MzQuMzYgMTY0Ni4zNgogIFEgNDIwLjc0IDE2NTkuNTcgNDEzLjQ0IDE2NjUuMTkKICBDIDM5NC4yMCAxNjc5Ljk5IDM1OS43NCAxNjY3LjIxIDM1NC43NyAxNjQzLjI1CiAgUSAzNTQuMDYgMTYzOS44MyAzNTQuMDIgMTYzMy4yMQogIFEgMzUzLjUwIDE1NTIuNTQgMzU0LjA4IDE0NzEuODcKICBRIDM1NC4xNCAxNDYyLjk2IDM1NS41NiAxNDU4LjQzCiAgUSAzNTguMzEgMTQ0OS42OSAzNjUuMTYgMTQ0My45MAogIFEgMzg3LjA4IDE0MjUuMzggNDEyLjEyIDE0MzguMDgKICBDIDUwOS4xMSAxNDg3LjI5IDYzMi4zMyAxNDg2LjE0IDcyOS41MyAxNDM4LjUzCiAgUSA3MzYuNjkgMTQzNS4wMiA3NDEuMDEgMTQzNC4xMAogIEMgNzU4Ljk2IDE0MzAuMjcgNzgwLjcyIDE0MzkuNTggNzg2LjY1IDE0NTguMTQKICBRIDc4OC4yMCAxNDYzLjAwIDc4OC4yOCAxNDc0LjUzCiAgUSA3ODkuMDMgMTU5Mi4yMyA3ODguMzAgMTYzOS43NQogIFEgNzg4LjI2IDE2NDIuNjIgNzg2LjQ4IDE2NDcuMzkKICBDIDc3OS4xOCAxNjY3LjA2IDc1Mi4wNSAxNjc3LjQwIDczMy4zNyAxNjY3Ljc4CiAgQyA3MjguMTkgMTY2NS4xMSA3MjEuNTYgMTY1OS4wMCA3MTcuNjkgMTY1NS4zMQogIFEgNjk4Ljg2IDE2MzcuMzkgNjgwLjI4IDE2MTkuMzYKICBBIDAuNTAgMC41MCAwLjAgMCAwIDY3OS40OSAxNjE5LjQ5CiAgQyA2NTUuODUgMTY2NC42MSA2MzIuODkgMTcxMC4yMCA2MDguNzcgMTc1NS4xMwogIFEgNjAyLjU0IDE3NjYuNzQgNjAyLjM3IDE3NjYuOTkKICBDIDU5MC4yNCAxNzg1LjQzIDU1OS41NiAxNzg2LjkyIDU0NC4yNSAxNzcxLjg5CiAgUSA1NDAuODcgMTc2OC41OCA1MzYuNDIgMTc2MC4yNwogIEMgNTExLjQ0IDE3MTMuNjUgNDg3LjU5IDE2NjYuNDQgNDYyLjgzIDE2MTkuNzkKICBaIgovPgo8L3N2Zz4K",
981
+ url: "https://logrocket.com",
982
+ disabled: true
983
+ }
984
+ ];
985
+ var flags = features.map((f) => f.flag);
986
+ var cliFlags = features.filter((f) => !f.invisibleCli).map((f) => f.flag);
987
+
988
+ // ../features/dist/index.js
989
+ var BatiSet = class extends Set {
990
+ #servers;
991
+ // eslint-disable-next-line no-unused-private-class-members
992
+ #databases;
993
+ constructor(flags2, allFeatures) {
994
+ super(flags2);
995
+ this.#servers = new Set(allFeatures.filter((f) => f.category === "Server").map((f) => f.flag));
996
+ this.#databases = new Set(allFeatures.filter((f) => f.category === "Database").map((f) => f.flag));
997
+ }
998
+ hasOneOf(a) {
999
+ for (const x of this) if (a.has(x)) return true;
1000
+ return false;
1001
+ }
1002
+ get hasServer() {
1003
+ return this.hasOneOf(this.#servers);
1004
+ }
1005
+ get hasDatabase() {
1006
+ return this.has("sqlite") || this.has("drizzle");
1007
+ }
1008
+ get hasD1() {
1009
+ return this.has("cloudflare") && (this.has("sqlite") || this.has("drizzle"));
1010
+ }
1011
+ };
1012
+
1013
+ // ../features/dist/rules.js
1014
+ var RulesMessage = /* @__PURE__ */ ((RulesMessage2) => {
1015
+ RulesMessage2[RulesMessage2["ERROR_AUTH_R_SERVER"] = 0] = "ERROR_AUTH_R_SERVER";
1016
+ RulesMessage2[RulesMessage2["ERROR_COMPILED_R_REACT"] = 1] = "ERROR_COMPILED_R_REACT";
1017
+ RulesMessage2[RulesMessage2["ERROR_DRIZZLE_R_SERVER"] = 2] = "ERROR_DRIZZLE_R_SERVER";
1018
+ RulesMessage2[RulesMessage2["ERROR_DATA_R_SERVER"] = 3] = "ERROR_DATA_R_SERVER";
1019
+ RulesMessage2[RulesMessage2["ERROR_LUCIA_R_COMPAT_DATABASE"] = 4] = "ERROR_LUCIA_R_COMPAT_DATABASE";
1020
+ RulesMessage2[RulesMessage2["ERROR_CLOUDFLARE_R_COMPAT_SERVER"] = 5] = "ERROR_CLOUDFLARE_R_COMPAT_SERVER";
1021
+ RulesMessage2[RulesMessage2["ERROR_AWS_R_COMPAT_SERVER"] = 6] = "ERROR_AWS_R_COMPAT_SERVER";
1022
+ RulesMessage2[RulesMessage2["ERROR_MANTINE_R_REACT"] = 7] = "ERROR_MANTINE_R_REACT";
1023
+ RulesMessage2[RulesMessage2["ERROR_SHADCN_R_REACT"] = 8] = "ERROR_SHADCN_R_REACT";
1024
+ RulesMessage2[RulesMessage2["WARN_SHADCN_R_TAILWINDCSS"] = 9] = "WARN_SHADCN_R_TAILWINDCSS";
1025
+ RulesMessage2[RulesMessage2["INFO_HATTIP"] = 10] = "INFO_HATTIP";
1026
+ RulesMessage2[RulesMessage2["INFO_STACKBLITZ_COMPAT"] = 11] = "INFO_STACKBLITZ_COMPAT";
1027
+ return RulesMessage2;
1028
+ })(RulesMessage || {});
1029
+ function requires(message, ifPresent, mustAlsoInclude) {
1030
+ const m = Array.from(prepare(mustAlsoInclude));
1031
+ return (fts) => fts.has(ifPresent) && !m.every((r) => fts.has(r)) && message;
1032
+ }
1033
+ function includes(message, ifPresent) {
1034
+ return (fts) => fts.has(ifPresent) && message;
1035
+ }
1036
+ function filter(message, callback) {
1037
+ return (fts) => callback(fts) && message;
1038
+ }
1039
+ function prepare(fts) {
1040
+ const s = /* @__PURE__ */ new Set();
1041
+ for (const f of fts) {
1042
+ if (flags.includes(f)) {
1043
+ s.add(features.find((feat) => feat.flag === f).category);
1044
+ }
1045
+ s.add(f);
1046
+ }
1047
+ return s;
1048
+ }
1049
+ var rules_default = [
1050
+ requires(0, "Auth", ["Server"]),
1051
+ requires(1, "compiled-css", ["react"]),
1052
+ includes(10, "hattip"),
1053
+ requires(2, "drizzle", ["Server"]),
1054
+ requires(3, "Data fetching", ["Server"]),
1055
+ filter(5, (fts) => {
1056
+ if (fts.has("cloudflare")) {
1057
+ if (fts.has("hono") || fts.has("hattip")) {
1058
+ return false;
1059
+ }
1060
+ return fts.has("Server");
1061
+ }
1062
+ return false;
1063
+ }),
1064
+ filter(6, (fts) => {
1065
+ if (fts.has("aws")) {
1066
+ if (fts.has("hono") || fts.has("hattip")) {
1067
+ return false;
1068
+ }
1069
+ return true;
1070
+ }
1071
+ return false;
1072
+ }),
1073
+ filter(4, (fts) => {
1074
+ if (fts.has("lucia-auth")) {
1075
+ return !(fts.has("sqlite") || fts.has("drizzle"));
1076
+ }
1077
+ return false;
1078
+ }),
1079
+ filter(7, (fts) => {
1080
+ if (fts.has("mantine")) {
1081
+ return fts.has("vue") || fts.has("solid");
1082
+ }
1083
+ return false;
1084
+ }),
1085
+ filter(8, (fts) => {
1086
+ if (fts.has("shadcn-ui")) {
1087
+ return fts.has("vue") || fts.has("solid");
1088
+ }
1089
+ return false;
1090
+ }),
1091
+ filter(9, (fts) => {
1092
+ if (fts.has("shadcn-ui")) {
1093
+ return fts.has("daisyui") || fts.has("compiled-css");
1094
+ }
1095
+ return false;
1096
+ }),
1097
+ filter(11, (fts) => {
1098
+ return fts.has("drizzle") || fts.has("sqlite") || fts.has("cloudflare");
1099
+ })
1100
+ ];
1101
+ function execRules(fts, rulesMessages2) {
1102
+ const sfts = prepare(fts);
1103
+ const messages = [];
1104
+ for (const rule of rules_default) {
1105
+ const result = rule(sfts);
1106
+ if (typeof result === "number") {
1107
+ if (result in rulesMessages2) {
1108
+ messages.push(rulesMessages2[result]);
1109
+ } else {
1110
+ console.warn("No handler defined for rule", result);
1111
+ }
1112
+ }
1113
+ }
1114
+ return messages;
1115
+ }
330
1116
 
331
1117
  // ../../node_modules/.pnpm/citty@0.1.6/node_modules/citty/dist/index.mjs
332
1118
  function toArray(val) {
@@ -1677,7 +2463,7 @@ var createDefaultQueryTester = function(query, options) {
1677
2463
  // package.json
1678
2464
  var package_default = {
1679
2465
  name: "@batijs/cli",
1680
- version: "0.0.282",
2466
+ version: "0.0.287",
1681
2467
  type: "module",
1682
2468
  scripts: {
1683
2469
  "check-types": "tsc --noEmit",
@@ -1721,7 +2507,6 @@ var package_default = {
1721
2507
  };
1722
2508
 
1723
2509
  // rules.ts
1724
- import { RulesMessage } from "@batijs/features/rules";
1725
2510
  function error(value) {
1726
2511
  return {
1727
2512
  type: "error",
@@ -1782,7 +2567,7 @@ Choose one of them, or simply remove selected Server`
1782
2567
  var __filename = fileURLToPath(import.meta.url);
1783
2568
  var __dirname = dirname(__filename);
1784
2569
  var isWin2 = process.platform === "win32";
1785
- var pm = packageManager();
2570
+ var pm = Tps();
1786
2571
  function boilerplatesDir() {
1787
2572
  if (existsSync2(join(__dirname, "boilerplates", "boilerplates.json"))) {
1788
2573
  return join(__dirname, "boilerplates");
@@ -1815,14 +2600,14 @@ function findDescription(key) {
1815
2600
  return `Include ${feat.label}`;
1816
2601
  }
1817
2602
  }
1818
- function printOK(dist, flags) {
1819
- const arrow0 = withIcon("\u2192", blueBright);
1820
- const book0 = withIcon("\u{1F4DA}", blueBright);
1821
- const list3 = withIcon("-", void 0, 3);
1822
- const cmd3 = withIcon("$", gray, 3);
2603
+ function printOK(dist, flags2) {
2604
+ const arrow0 = OWr("\u2192", blueBright);
2605
+ const book0 = OWr("\u{1F4DA}", blueBright);
2606
+ const list3 = OWr("-", void 0, 3);
2607
+ const cmd3 = OWr("$", gray, 3);
1823
2608
  console.log(bold(`${green("\u2713")} Project created at ${cyan(dist)} with:`));
1824
2609
  console.log(list3(green("Vike")));
1825
- for (const key of flags) {
2610
+ for (const key of flags2) {
1826
2611
  const feature = features.find((f) => f.flag === key);
1827
2612
  if (!feature || !feature.label) continue;
1828
2613
  console.log(list3(green(feature.label)));
@@ -1939,9 +2724,9 @@ async function checkArguments(args) {
1939
2724
  }
1940
2725
  }
1941
2726
  }
1942
- function checkFlagsIncludesUiFramework(flags) {
2727
+ function checkFlagsIncludesUiFramework(flags2) {
1943
2728
  const uiFlags = features.filter((fs) => fs.category === "UI Framework").map((fs) => fs.flag);
1944
- const uiFlagFound = flags.some((f) => uiFlags.includes(f));
2729
+ const uiFlagFound = flags2.some((f) => uiFlags.includes(f));
1945
2730
  if (!uiFlagFound) {
1946
2731
  const lf = new Intl.ListFormat("en", {
1947
2732
  type: "disjunction"
@@ -1952,8 +2737,8 @@ function checkFlagsIncludesUiFramework(flags) {
1952
2737
  process.exit(5);
1953
2738
  }
1954
2739
  }
1955
- function checkFlagsExist(flags) {
1956
- const inValidOptions = flags.reduce((acc, flag) => {
2740
+ function checkFlagsExist(flags2) {
2741
+ const inValidOptions = flags2.reduce((acc, flag) => {
1957
2742
  if (!Object.prototype.hasOwnProperty.call(defaultDef, flag) && !features.some((f) => f.flag === flag)) {
1958
2743
  acc.push(flag);
1959
2744
  }
@@ -1967,8 +2752,8 @@ function checkFlagsExist(flags) {
1967
2752
  process.exit(5);
1968
2753
  }
1969
2754
  }
1970
- function checkRules(flags) {
1971
- const potentialRulesMessages = execRules(flags, rulesMessages);
2755
+ function checkRules(flags2) {
2756
+ const potentialRulesMessages = execRules(flags2, rulesMessages);
1972
2757
  const infos = potentialRulesMessages.filter((m) => m?.type === "info");
1973
2758
  const warnings = potentialRulesMessages.filter((m) => m?.type === "warning");
1974
2759
  const errors = potentialRulesMessages.filter((m) => m?.type === "error");
@@ -2012,14 +2797,14 @@ async function retrieveHooks(hooks) {
2012
2797
  }
2013
2798
  return map;
2014
2799
  }
2015
- function testFlags(flags, bl) {
2800
+ function testFlags(flags2, bl) {
2016
2801
  if (bl.config.if) {
2017
- return createDefaultQueryTester(bl.config.if)(flags.map((f) => ({ flag: f })));
2802
+ return createDefaultQueryTester(bl.config.if)(flags2.map((f) => ({ flag: f })));
2018
2803
  }
2019
2804
  return true;
2020
2805
  }
2021
2806
  function gitInit(cwd) {
2022
- const exists = which("git");
2807
+ const exists = export_which("git");
2023
2808
  if (!exists) return;
2024
2809
  try {
2025
2810
  execSync("git init", {
@@ -2060,7 +2845,7 @@ async function run() {
2060
2845
  await checkArguments(args);
2061
2846
  const sources = [];
2062
2847
  const hooks = [];
2063
- const flags = [
2848
+ const flags2 = [
2064
2849
  ...new Set(
2065
2850
  Object.entries(args).filter(([, val]) => val === true).map(([key]) => {
2066
2851
  const flag = [key];
@@ -2072,9 +2857,9 @@ async function run() {
2072
2857
  }).flat(1)
2073
2858
  )
2074
2859
  ];
2075
- checkFlagsExist(flags);
2076
- checkFlagsIncludesUiFramework(flags);
2077
- checkRules(flags);
2860
+ checkFlagsExist(flags2);
2861
+ checkFlagsIncludesUiFramework(flags2);
2862
+ checkRules(flags2);
2078
2863
  boilerplates.sort((b1, b2) => {
2079
2864
  if (b1.config.enforce === "pre") return -1;
2080
2865
  if (b1.config.enforce === "post") return 1;
@@ -2083,7 +2868,7 @@ async function run() {
2083
2868
  return 0;
2084
2869
  });
2085
2870
  for (const bl of boilerplates) {
2086
- if (testFlags(flags, bl)) {
2871
+ if (testFlags(flags2, bl)) {
2087
2872
  if (bl.subfolders.includes("files")) {
2088
2873
  sources.push(join(dir, bl.folder, "files"));
2089
2874
  }
@@ -2094,7 +2879,7 @@ async function run() {
2094
2879
  }
2095
2880
  const hooksMap = await retrieveHooks(hooks);
2096
2881
  const meta = {
2097
- BATI: new BatiSet(flags, features),
2882
+ BATI: new BatiSet(flags2, features),
2098
2883
  BATI_TEST: Boolean(process.env.BATI_TEST)
2099
2884
  };
2100
2885
  await main(
@@ -2107,7 +2892,7 @@ async function run() {
2107
2892
  if (!args["skip-git"]) {
2108
2893
  gitInit(args.project);
2109
2894
  }
2110
- printOK(args.project, flags);
2895
+ printOK(args.project, flags2);
2111
2896
  for (const onafter of hooksMap.get("after") ?? []) {
2112
2897
  await onafter(meta);
2113
2898
  }