@krizaka/org 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // package.json
2
2
  var package_default = {
3
3
  name: "@krizaka/org",
4
- version: "0.5.0",
4
+ version: "0.7.0",
5
5
  description: "The public facts about Krizaka, in one validated JSON that every footer, site and app reads: legal name, NEQ, \xAB Fait \xE0 Montr\xE9al \xBB in French and English, brand marks, default avatars and banners, the live products and sites, the public contact, the footer line and the mobile apps' public runtime config. Typed data, JSON Schema, and the files published on the CDN.",
6
6
  keywords: [
7
7
  "krizaka",
@@ -33,8 +33,12 @@ var package_default = {
33
33
  "./apps/*.json": "./dist/apps/*.json",
34
34
  "./package.json": "./package.json"
35
35
  },
36
+ bin: {
37
+ "krizaka-code-names": "./bin/krizaka-code-names.mjs"
38
+ },
36
39
  files: [
37
40
  "dist",
41
+ "bin",
38
42
  "README.md",
39
43
  "LICENSE"
40
44
  ],
@@ -64,8 +68,20 @@ var package_default = {
64
68
 
65
69
  // src/defaults.ts
66
70
  var BASE = "https://krizaka-assets.b-cdn.net/defaults/v1";
67
- var DEFAULT_KINDS = ["person", "folder", "organisation", "shop", "banner"];
68
- var SIZES = { person: [256, 512, 1024], folder: [256, 512, 1024], organisation: [256, 512, 1024], shop: [256, 512, 1024], banner: [960, 1920] };
71
+ var DEFAULT_KINDS = [
72
+ "person",
73
+ "folder",
74
+ "organisation",
75
+ "shop",
76
+ "banner"
77
+ ];
78
+ var SIZES = {
79
+ person: [256, 512, 1024],
80
+ folder: [256, 512, 1024],
81
+ organisation: [256, 512, 1024],
82
+ shop: [256, 512, 1024],
83
+ banner: [960, 1920]
84
+ };
69
85
  var DISABLED_DEFAULTS = /* @__PURE__ */ new Set(["banner/the-neon-flamingo"]);
70
86
  var item = (kind, id, alt, drawn) => ({
71
87
  id,
@@ -78,38 +94,194 @@ var item = (kind, id, alt, drawn) => ({
78
94
  });
79
95
  var tones = (kind, id, alt) => Array.from({ length: 6 }, (_, i) => item(kind, `${id}-${i + 1}`, alt(i + 1), true));
80
96
  var PEOPLE = [
81
- ["boom-bap", { en: "Illustration: a rapper in a denim jacket and beanie, microphone in hand, in a rainy Montr\xE9al alley at night", fr: "Illustration : un rappeur en veste de jean et tuque, micro \xE0 la main, dans une ruelle de Montr\xE9al sous la pluie, la nuit" }],
82
- ["rasta-creative", { en: "A smiling man with long dreadlocks in a paint-stained denim jacket, in an artist's workshop", fr: "Un homme souriant aux longues dreadlocks, en veste de jean tach\xE9e de peinture, dans un atelier d'artiste" }],
83
- ["mile-end-hipster", { en: "A smiling person with round glasses and an orange beanie at a leatherworking bench, in a brick workshop", fr: "Une personne souriante \xE0 lunettes rondes et tuque orange, \xE0 son \xE9tabli de cuir, dans un atelier de briques" }],
84
- ["tech-architect", { en: "A person in a dark hoodie typing at a keyboard, between screens of code and a server rack", fr: "Une personne en chandail \xE0 capuchon sombre qui tape au clavier, entre des \xE9crans de code et une baie de serveurs" }],
85
- ["electronic-dj", { en: "A DJ with headphones behind synthesizers and a mixing desk, in a club with violet lights", fr: "Un DJ casque aux oreilles derri\xE8re des synth\xE9tiseurs et une table de mixage, dans un club aux lumi\xE8res violettes" }],
86
- ["visual-artist", { en: "A smiling painter with violet hair and big glasses, palette in hand, in a studio full of canvases", fr: "Une peintre souriante aux cheveux violets et aux grosses lunettes, palette \xE0 la main, dans un atelier plein de toiles" }],
87
- ["salon-tattoo-maker", { en: "A tattoo artist with tattooed arms working on a client in a warm shop with wooden shelves", fr: "Une tatoueuse aux bras tatou\xE9s au travail sur un client, dans un salon chaleureux aux \xE9tag\xE8res de bois" }],
88
- ["wise-auditor", { en: "A grey-haired person with glasses at a desk of old books and a lamp, a pen over open notes", fr: "Une personne aux cheveux gris et \xE0 lunettes \xE0 un bureau de vieux livres et de lampe, un stylo sur des notes ouvertes" }],
89
- ["digital-creator", { en: "A laughing streamer with a microphone in a purple-lit studio under a neon \xAB Creator Zone \xBB sign", fr: "Une diffuseuse qui rit devant un micro, dans un studio violet sous une enseigne n\xE9on \xAB Creator Zone \xBB" }],
90
- ["studio-maker", { en: "A potter in a linen apron holding a clay bowl, in a bright ceramics studio with plants", fr: "Une poti\xE8re en tablier de lin tenant un bol d'argile, dans un atelier de c\xE9ramique lumineux et plein de plantes" }],
91
- ["community-lead", { en: "A smiling person with curly hair and a grey coat at a wooden table, a community space behind them", fr: "Une personne souriante aux cheveux boucl\xE9s et au manteau gris, \xE0 une table de bois, devant un espace communautaire" }],
92
- ["ai-builder", { en: "A thoughtful person with blue-tinted glasses at a desk, screens of a neural network and code behind", fr: "Une personne pensive aux lunettes teint\xE9es de bleu \xE0 son bureau, devant des \xE9crans de r\xE9seau neuronal et de code" }]
97
+ [
98
+ "boom-bap",
99
+ {
100
+ en: "Illustration: a rapper in a denim jacket and beanie, microphone in hand, in a rainy Montr\xE9al alley at night",
101
+ fr: "Illustration : un rappeur en veste de jean et tuque, micro \xE0 la main, dans une ruelle de Montr\xE9al sous la pluie, la nuit"
102
+ }
103
+ ],
104
+ [
105
+ "rasta-creative",
106
+ {
107
+ en: "A smiling man with long dreadlocks in a paint-stained denim jacket, in an artist's workshop",
108
+ fr: "Un homme souriant aux longues dreadlocks, en veste de jean tach\xE9e de peinture, dans un atelier d'artiste"
109
+ }
110
+ ],
111
+ [
112
+ "mile-end-hipster",
113
+ {
114
+ en: "A smiling person with round glasses and an orange beanie at a leatherworking bench, in a brick workshop",
115
+ fr: "Une personne souriante \xE0 lunettes rondes et tuque orange, \xE0 son \xE9tabli de cuir, dans un atelier de briques"
116
+ }
117
+ ],
118
+ [
119
+ "tech-architect",
120
+ {
121
+ en: "A person in a dark hoodie typing at a keyboard, between screens of code and a server rack",
122
+ fr: "Une personne en chandail \xE0 capuchon sombre qui tape au clavier, entre des \xE9crans de code et une baie de serveurs"
123
+ }
124
+ ],
125
+ [
126
+ "electronic-dj",
127
+ {
128
+ en: "A DJ with headphones behind synthesizers and a mixing desk, in a club with violet lights",
129
+ fr: "Un DJ casque aux oreilles derri\xE8re des synth\xE9tiseurs et une table de mixage, dans un club aux lumi\xE8res violettes"
130
+ }
131
+ ],
132
+ [
133
+ "visual-artist",
134
+ {
135
+ en: "A smiling painter with violet hair and big glasses, palette in hand, in a studio full of canvases",
136
+ fr: "Une peintre souriante aux cheveux violets et aux grosses lunettes, palette \xE0 la main, dans un atelier plein de toiles"
137
+ }
138
+ ],
139
+ [
140
+ "salon-tattoo-maker",
141
+ {
142
+ en: "A tattoo artist with tattooed arms working on a client in a warm shop with wooden shelves",
143
+ fr: "Une tatoueuse aux bras tatou\xE9s au travail sur un client, dans un salon chaleureux aux \xE9tag\xE8res de bois"
144
+ }
145
+ ],
146
+ [
147
+ "wise-auditor",
148
+ {
149
+ en: "A grey-haired person with glasses at a desk of old books and a lamp, a pen over open notes",
150
+ fr: "Une personne aux cheveux gris et \xE0 lunettes \xE0 un bureau de vieux livres et de lampe, un stylo sur des notes ouvertes"
151
+ }
152
+ ],
153
+ [
154
+ "digital-creator",
155
+ {
156
+ en: "A laughing streamer with a microphone in a purple-lit studio under a neon \xAB Creator Zone \xBB sign",
157
+ fr: "Une diffuseuse qui rit devant un micro, dans un studio violet sous une enseigne n\xE9on \xAB Creator Zone \xBB"
158
+ }
159
+ ],
160
+ [
161
+ "studio-maker",
162
+ {
163
+ en: "A potter in a linen apron holding a clay bowl, in a bright ceramics studio with plants",
164
+ fr: "Une poti\xE8re en tablier de lin tenant un bol d'argile, dans un atelier de c\xE9ramique lumineux et plein de plantes"
165
+ }
166
+ ],
167
+ [
168
+ "community-lead",
169
+ {
170
+ en: "A smiling person with curly hair and a grey coat at a wooden table, a community space behind them",
171
+ fr: "Une personne souriante aux cheveux boucl\xE9s et au manteau gris, \xE0 une table de bois, devant un espace communautaire"
172
+ }
173
+ ],
174
+ [
175
+ "ai-builder",
176
+ {
177
+ en: "A thoughtful person with blue-tinted glasses at a desk, screens of a neural network and code behind",
178
+ fr: "Une personne pensive aux lunettes teint\xE9es de bleu \xE0 son bureau, devant des \xE9crans de r\xE9seau neuronal et de code"
179
+ }
180
+ ]
93
181
  ];
94
182
  var BANNERS = [
95
- ["montreal-winter-night", { en: "Illustration: a snowy night in downtown Montr\xE9al, lit shop fronts and walkers", fr: "Illustration : une nuit de neige au centre-ville de Montr\xE9al, devantures \xE9clair\xE9es et passants" }],
96
- ["industrial-heritage", { en: "Dark blue skyline of old brick buildings with lit orange windows under a full moon", fr: "Silhouette bleu nuit de vieux immeubles de briques aux fen\xEAtres orang\xE9es, sous la pleine lune" }],
97
- ["creator-loft-studio", { en: "A dark loft desk with a plant, a code window and a mixing board", fr: "Un bureau de loft sombre avec une plante, une fen\xEAtre de code et une table de mixage" }],
98
- ["abstract-digital-flow", { en: "Flowing teal, violet and orange lines linking glowing points on a dark background", fr: "Des lignes ondulantes turquoise, violettes et orange reliant des points lumineux sur fond sombre" }],
99
- ["paperwork-and-ink", { en: "Two dark document cards with colored stamps on a night-blue grid", fr: "Deux cartes de documents sombres tamponn\xE9es de couleur sur une grille bleu nuit" }],
100
- ["nightlife-music-visual", { en: "A large glowing vinyl record with a pink label beside a small level meter, in violet light", fr: "Un grand disque vinyle lumineux \xE0 l'\xE9tiquette rose pr\xE8s d'un petit indicateur de niveau, en lumi\xE8re violette" }],
101
- ["the-mascot-flock", { en: "The Krizaka mascots \u2014 an owl, a beaver and a flamingo \u2014 standing on a shelf in the dark", fr: "Les mascottes de Krizaka \u2014 un hibou, un castor et un flamant \u2014 debout sur une \xE9tag\xE8re dans le noir" }],
102
- ["abstract-stripes", { en: "Diagonal teal, indigo, violet and orange stripes with a white star and \xAB Montr\xE9al // 514 \xBB", fr: "Des bandes diagonales turquoise, indigo, violettes et orange avec une \xE9toile blanche et \xAB Montr\xE9al // 514 \xBB" }],
103
- ["open-source-horizon", { en: "A dark terminal window on a grid, a faint horizon behind", fr: "Une fen\xEAtre de terminal sombre sur une grille, un horizon p\xE2le derri\xE8re" }],
104
- ["cafe-maker-studio", { en: "A warm dark brown scene with a card reading \xAB Fabriqu\xE9 \xE0 Montr\xE9al \xBB", fr: "Une sc\xE8ne brun fonc\xE9 chaleureuse avec une carte \xAB Fabriqu\xE9 \xE0 Montr\xE9al \xBB" }],
105
- ["the-neon-flamingo", { en: "A pink neon flamingo outline on black, with a violet halo", fr: "Le contour d'un flamant rose en n\xE9on sur fond noir, avec un halo violet" }],
106
- ["cooperative-network", { en: "Small linked glowing points over a dark hill at dusk", fr: "De petits points lumineux reli\xE9s au-dessus d'une colline sombre au cr\xE9puscule" }]
183
+ [
184
+ "montreal-winter-night",
185
+ {
186
+ en: "Illustration: a snowy night in downtown Montr\xE9al, lit shop fronts and walkers",
187
+ fr: "Illustration : une nuit de neige au centre-ville de Montr\xE9al, devantures \xE9clair\xE9es et passants"
188
+ }
189
+ ],
190
+ [
191
+ "industrial-heritage",
192
+ {
193
+ en: "Dark blue skyline of old brick buildings with lit orange windows under a full moon",
194
+ fr: "Silhouette bleu nuit de vieux immeubles de briques aux fen\xEAtres orang\xE9es, sous la pleine lune"
195
+ }
196
+ ],
197
+ [
198
+ "creator-loft-studio",
199
+ {
200
+ en: "A dark loft desk with a plant, a code window and a mixing board",
201
+ fr: "Un bureau de loft sombre avec une plante, une fen\xEAtre de code et une table de mixage"
202
+ }
203
+ ],
204
+ [
205
+ "abstract-digital-flow",
206
+ {
207
+ en: "Flowing teal, violet and orange lines linking glowing points on a dark background",
208
+ fr: "Des lignes ondulantes turquoise, violettes et orange reliant des points lumineux sur fond sombre"
209
+ }
210
+ ],
211
+ [
212
+ "paperwork-and-ink",
213
+ {
214
+ en: "Two dark document cards with colored stamps on a night-blue grid",
215
+ fr: "Deux cartes de documents sombres tamponn\xE9es de couleur sur une grille bleu nuit"
216
+ }
217
+ ],
218
+ [
219
+ "nightlife-music-visual",
220
+ {
221
+ en: "A large glowing vinyl record with a pink label beside a small level meter, in violet light",
222
+ fr: "Un grand disque vinyle lumineux \xE0 l'\xE9tiquette rose pr\xE8s d'un petit indicateur de niveau, en lumi\xE8re violette"
223
+ }
224
+ ],
225
+ [
226
+ "the-mascot-flock",
227
+ {
228
+ en: "The Krizaka mascots \u2014 an owl, a beaver and a flamingo \u2014 standing on a shelf in the dark",
229
+ fr: "Les mascottes de Krizaka \u2014 un hibou, un castor et un flamant \u2014 debout sur une \xE9tag\xE8re dans le noir"
230
+ }
231
+ ],
232
+ [
233
+ "abstract-stripes",
234
+ {
235
+ en: "Diagonal teal, indigo, violet and orange stripes with a white star and \xAB Montr\xE9al // 514 \xBB",
236
+ fr: "Des bandes diagonales turquoise, indigo, violettes et orange avec une \xE9toile blanche et \xAB Montr\xE9al // 514 \xBB"
237
+ }
238
+ ],
239
+ [
240
+ "open-source-horizon",
241
+ {
242
+ en: "A dark terminal window on a grid, a faint horizon behind",
243
+ fr: "Une fen\xEAtre de terminal sombre sur une grille, un horizon p\xE2le derri\xE8re"
244
+ }
245
+ ],
246
+ [
247
+ "cafe-maker-studio",
248
+ {
249
+ en: "A warm dark brown scene with a card reading \xAB Fabriqu\xE9 \xE0 Montr\xE9al \xBB",
250
+ fr: "Une sc\xE8ne brun fonc\xE9 chaleureuse avec une carte \xAB Fabriqu\xE9 \xE0 Montr\xE9al \xBB"
251
+ }
252
+ ],
253
+ [
254
+ "the-neon-flamingo",
255
+ {
256
+ en: "A pink neon flamingo outline on black, with a violet halo",
257
+ fr: "Le contour d'un flamant rose en n\xE9on sur fond noir, avec un halo violet"
258
+ }
259
+ ],
260
+ [
261
+ "cooperative-network",
262
+ {
263
+ en: "Small linked glowing points over a dark hill at dusk",
264
+ fr: "De petits points lumineux reli\xE9s au-dessus d'une colline sombre au cr\xE9puscule"
265
+ }
266
+ ]
107
267
  ];
108
268
  var GLYPH_ALT = {
109
- person: (n) => ({ en: `Default profile picture: a silhouette, tone ${n}`, fr: `Photo de profil par d\xE9faut : une silhouette, teinte ${n}` }),
110
- folder: (n) => ({ en: `Default folder picture: a folder, tone ${n}`, fr: `Image de dossier par d\xE9faut : un dossier, teinte ${n}` }),
111
- organisation: (n) => ({ en: `Default organisation picture: a building, tone ${n}`, fr: `Image d'organisation par d\xE9faut : un immeuble, teinte ${n}` }),
112
- shop: (n) => ({ en: `Default shop picture: a storefront, tone ${n}`, fr: `Image de boutique par d\xE9faut : une devanture, teinte ${n}` })
269
+ person: (n) => ({
270
+ en: `Default profile picture: a silhouette, tone ${n}`,
271
+ fr: `Photo de profil par d\xE9faut : une silhouette, teinte ${n}`
272
+ }),
273
+ folder: (n) => ({
274
+ en: `Default folder picture: a folder, tone ${n}`,
275
+ fr: `Image de dossier par d\xE9faut : un dossier, teinte ${n}`
276
+ }),
277
+ organisation: (n) => ({
278
+ en: `Default organisation picture: a building, tone ${n}`,
279
+ fr: `Image d'organisation par d\xE9faut : un immeuble, teinte ${n}`
280
+ }),
281
+ shop: (n) => ({
282
+ en: `Default shop picture: a storefront, tone ${n}`,
283
+ fr: `Image de boutique par d\xE9faut : une devanture, teinte ${n}`
284
+ })
113
285
  };
114
286
  var defaults = {
115
287
  version: "v1",
@@ -119,7 +291,10 @@ var defaults = {
119
291
  description: "defaultFor(kind, seed) = items[fnv1a32(String(seed)) mod items.length] of the kind's list, in the order of the JSON; the same seed always gives the same item, in every app."
120
292
  },
121
293
  kinds: {
122
- person: [...tones("person", "silhouette", GLYPH_ALT.person), ...PEOPLE.map(([id, alt]) => item("person", id, alt, false))],
294
+ person: [
295
+ ...tones("person", "silhouette", GLYPH_ALT.person),
296
+ ...PEOPLE.map(([id, alt]) => item("person", id, alt, false))
297
+ ],
123
298
  folder: tones("folder", "folder", GLYPH_ALT.folder),
124
299
  organisation: tones("organisation", "organisation", GLYPH_ALT.organisation),
125
300
  shop: tones("shop", "shop", GLYPH_ALT.shop),
@@ -168,7 +343,13 @@ var mark = (kind, theme) => ({
168
343
  png1024: cdn(`brand/krizaka/${kind}-${theme}-1024.png`)
169
344
  });
170
345
  var TONES = [1, 2, 3, 4, 5, 6];
171
- var avatarAlt = (kind, n) => kind === "person" ? { fr: `Photo de profil par d\xE9faut : silhouette, teinte ${n}`, en: `Default profile picture: silhouette, tone ${n}` } : { fr: `Photo de profil par d\xE9faut : disque uni, teinte ${n}`, en: `Default profile picture: plain disc, tone ${n}` };
346
+ var avatarAlt = (kind, n) => kind === "person" ? {
347
+ fr: `Photo de profil par d\xE9faut : silhouette, teinte ${n}`,
348
+ en: `Default profile picture: silhouette, tone ${n}`
349
+ } : {
350
+ fr: `Photo de profil par d\xE9faut : disque uni, teinte ${n}`,
351
+ en: `Default profile picture: plain disc, tone ${n}`
352
+ };
172
353
  var defaults2 = ["person", "plain"].flatMap(
173
354
  (kind) => TONES.map((n) => ({
174
355
  id: `${kind}-${n}`,
@@ -179,11 +360,34 @@ var defaults2 = ["person", "plain"].flatMap(
179
360
  alt: avatarAlt(kind, n)
180
361
  }))
181
362
  );
363
+ var GITHUB = "https://github.com/krizaka";
364
+ var gh = (repo) => `${GITHUB}/${repo}`;
365
+ var FAMILY_ROWS = [
366
+ ["krizaka", "Krizaka", "Krizaka", "krizaka", "released", "https://www.krizaka.com", gh("krizaka-com")],
367
+ ["blog", "Blog", "Blog", "krizaka", "released", "https://blog.krizaka.com", gh("krizaka-blog")],
368
+ ["orazaka", "Orazaka", "Orazaka", "products", "development", "https://www.orazaka.com", gh("orazaka")],
369
+ ["yomizaka", "Yomizaka", "Yomizaka", "products", "development", "https://www.yomizaka.com", gh("yomizaka")],
370
+ ["akinaza", "Akinaza", "Akinaza", "products", "development", "https://www.akinaza.com", gh("akinaza")],
371
+ ["ui", "Krizaka UI", "UI", "open-source", "development", "https://ui.krizaka.com", gh("krizaka-ui")],
372
+ ["java", "Krizaka Java", "Java", "open-source", "development", "https://java.krizaka.com", gh("krizaka-build")],
373
+ ["ts", "Krizaka TypeScript", "TypeScript", "open-source", "development", "https://ts.krizaka.com", gh("krizaka-ts")],
374
+ ["lab", "Krizaka Lab", "Lab", "open-source", "development", "https://lab.krizaka.com", gh("krizaka-lab")],
375
+ ["github", "GitHub", "GitHub", "github", "released", GITHUB, null]
376
+ ];
377
+ var family = FAMILY_ROWS.map(([id, name, short, group, status, url, repo]) => ({
378
+ id,
379
+ name,
380
+ short,
381
+ group,
382
+ status,
383
+ url,
384
+ repo
385
+ }));
182
386
  var org = {
183
387
  $schema: ORG_SCHEMA_URL,
184
388
  schemaVersion: 2,
185
389
  version: package_default.version,
186
- updatedAt: "2026-10-26",
390
+ updatedAt: "2026-10-30",
187
391
  company: {
188
392
  legalName: "Technologies Krizaka Inc.",
189
393
  tradeName: "Krizaka",
@@ -210,27 +414,57 @@ var org = {
210
414
  },
211
415
  defaults,
212
416
  products: [
213
- { id: "orazaka", name: "Orazaka", status: "development", url: "https://dev.orazaka.com", repo: "https://github.com/krizaka/orazaka" },
214
- { id: "yomizaka", name: "Yomizaka", status: "development", url: "https://dev.yomizaka.com", repo: "https://github.com/krizaka/yomizaka" },
215
- { id: "akinaza", name: "Akinaza", status: "development", url: "https://dev.akinaza.com", repo: "https://github.com/krizaka/akinaza" }
417
+ {
418
+ id: "orazaka",
419
+ name: "Orazaka",
420
+ status: "development",
421
+ url: "https://www.orazaka.com",
422
+ repo: "https://github.com/krizaka/orazaka"
423
+ },
424
+ {
425
+ id: "yomizaka",
426
+ name: "Yomizaka",
427
+ status: "development",
428
+ url: "https://www.yomizaka.com",
429
+ repo: "https://github.com/krizaka/yomizaka"
430
+ },
431
+ {
432
+ id: "akinaza",
433
+ name: "Akinaza",
434
+ status: "development",
435
+ url: "https://www.akinaza.com",
436
+ repo: "https://github.com/krizaka/akinaza"
437
+ }
216
438
  ],
217
439
  sites: [
218
440
  { id: "www", name: "krizaka.com", url: "https://www.krizaka.com" },
219
441
  { id: "ui", name: "Krizaka UI", url: "https://ui.krizaka.com" },
220
442
  { id: "java", name: "Krizaka Java", url: "https://java.krizaka.com" },
221
- { id: "ts", name: "Krizaka TS", url: "https://ts.krizaka.com" },
443
+ { id: "ts", name: "Krizaka TypeScript", url: "https://ts.krizaka.com" },
222
444
  { id: "motion", name: "Krizaka Lab", url: "https://lab.krizaka.com" },
223
445
  { id: "blog", name: "Blog", url: "https://blog.krizaka.com" }
224
446
  ],
447
+ family,
225
448
  contact: {
226
449
  page: { fr: "https://www.krizaka.com/fr/contact", en: "https://www.krizaka.com/en/contact" },
227
450
  email: null
228
451
  },
229
452
  footer: {
230
- line: { fr: "Une entreprise de Technologies Krizaka \xB7 Fait \xE0 Montr\xE9al", en: "A Technologies Krizaka company \xB7 Made in Montr\xE9al" },
453
+ line: {
454
+ fr: "Une entreprise de Technologies Krizaka \xB7 Fait \xE0 Montr\xE9al",
455
+ en: "A Technologies Krizaka company \xB7 Made in Montr\xE9al"
456
+ },
231
457
  legal: [
232
- { id: "privacy", label: { fr: "Confidentialit\xE9", en: "Privacy" }, url: { fr: "https://www.krizaka.com/fr/privacy", en: "https://www.krizaka.com/en/privacy" } },
233
- { id: "terms", label: { fr: "Conditions", en: "Terms" }, url: { fr: "https://www.krizaka.com/fr/terms", en: "https://www.krizaka.com/en/terms" } }
458
+ {
459
+ id: "privacy",
460
+ label: { fr: "Confidentialit\xE9", en: "Privacy" },
461
+ url: { fr: "https://www.krizaka.com/fr/privacy", en: "https://www.krizaka.com/en/privacy" }
462
+ },
463
+ {
464
+ id: "terms",
465
+ label: { fr: "Conditions", en: "Terms" },
466
+ url: { fr: "https://www.krizaka.com/fr/terms", en: "https://www.krizaka.com/en/terms" }
467
+ }
234
468
  ]
235
469
  }
236
470
  };
@@ -254,32 +488,336 @@ var apps = {
254
488
  akinaza: app("akinaza", "https://dev.akinaza.com")
255
489
  };
256
490
 
491
+ // src/brands.ts
492
+ var ENDORSEMENT = { en: "by Krizaka", fr: "par Krizaka" };
493
+ var brand = (codeName, commercialName, kind, domains, formerly) => ({
494
+ codeName,
495
+ commercialName,
496
+ kind,
497
+ endorsement: ENDORSEMENT,
498
+ domains,
499
+ formerly: formerly ? { en: `${formerly} is now ${commercialName}`, fr: `${formerly} s\u2019appelle d\xE9sormais ${commercialName}` } : null
500
+ });
501
+ var brands = [
502
+ brand(
503
+ "yomizaka",
504
+ "Verikora",
505
+ "product",
506
+ { site: "https://www.verikora.com", app: null, shop: null, dev: "https://dev.verikora.com" },
507
+ "Yomizaka"
508
+ ),
509
+ brand(
510
+ "akinaza",
511
+ "Folioviv",
512
+ "product",
513
+ {
514
+ site: "https://www.folioviv.com",
515
+ app: "https://folioviv.app",
516
+ shop: "https://folioviv.shop",
517
+ dev: "https://dev.folioviv.com"
518
+ },
519
+ "Akinaza"
520
+ ),
521
+ brand(
522
+ "orazaka",
523
+ "Sovkora",
524
+ "product",
525
+ { site: "https://www.sovkora.com", app: null, shop: null, dev: "https://dev.sovkora.com" },
526
+ "Orazaka"
527
+ ),
528
+ // Kachizaka is the code name of the managed storage (Krizaka ECM, krizaka-internal#1916); it was never public.
529
+ brand("kachizaka", "Kridoc", "service", { site: "https://www.kridoc.com", app: null, shop: null, dev: null }, null)
530
+ ];
531
+ var brandOf = (codeName) => {
532
+ const found = brands.find((b) => b.codeName === codeName);
533
+ if (!found) throw new Error(`Unknown Krizaka code name "${codeName}".`);
534
+ return found;
535
+ };
536
+ var DISPLAY_NAME_MAX = 30;
537
+ var displayName = (codeName, chosen) => {
538
+ const own = chosen?.trim() ?? "";
539
+ if (own.length === 0 || own.length > DISPLAY_NAME_MAX || codeNamePattern().test(own))
540
+ return brandOf(codeName).commercialName;
541
+ return own;
542
+ };
543
+ var lockup = (codeName, locale, chosen) => {
544
+ const { endorsement } = brandOf(codeName);
545
+ return `${displayName(codeName, chosen)} ${locale === "fr" ? endorsement.fr : endorsement.en}`;
546
+ };
547
+ var CODE_NAMES = brands.map((b) => b.codeName);
548
+ var FORMER_WORDINGS = [[/\bkrizaka\s+ecm\b/gi, "Kridoc"]];
549
+ var codeNameMap = () => Object.fromEntries(brands.map((b) => [b.codeName, b.commercialName]));
550
+ var codeNamePattern = (flags = "i") => new RegExp(String.raw`\b(${CODE_NAMES.join("|")})\b`, flags);
551
+ var HOST_ENDINGS = [".com", ".app", ".shop", ".dev"];
552
+ var LEADING = /* @__PURE__ */ new Set(["(", "\xAB", '"', "'"]);
553
+ var TRAILING = /* @__PURE__ */ new Set([".", ",", ";", ":", "!", "?", ")", "]", "\xBB", '"', "'"]);
554
+ var trimPunctuation = (raw) => {
555
+ let start = 0;
556
+ let end = raw.length;
557
+ while (start < end && LEADING.has(raw[start] ?? "")) start++;
558
+ while (end > start && TRAILING.has(raw[end - 1] ?? "")) end--;
559
+ return raw.slice(start, end);
560
+ };
561
+ var allowedToken = (raw) => {
562
+ const token = trimPunctuation(raw);
563
+ const lower = token.toLowerCase();
564
+ return token.includes("://") && URL.canParse(token) || lower.startsWith("@krizaka/") || lower.startsWith("com.krizaka") || lower.startsWith("krizaka/") || HOST_ENDINGS.some((end) => lower.endsWith(end) && lower.includes("."));
565
+ };
566
+ var CODE_SPAN = /`[^`\n]*`/g;
567
+ var blankAllowed = (text) => {
568
+ let out = text;
569
+ for (const brand2 of brands) {
570
+ for (const line of brand2.formerly ? [brand2.formerly.en, brand2.formerly.fr] : [])
571
+ out = out.split(line).join(" ".repeat(line.length));
572
+ }
573
+ out = out.replace(CODE_SPAN, (m) => " ".repeat(m.length));
574
+ return out.replace(/\S+/g, (m) => allowedToken(m) ? " ".repeat(m.length) : m);
575
+ };
576
+ var findCodeNames = (text) => {
577
+ const scanned = blankAllowed(text);
578
+ const map = codeNameMap();
579
+ const hits = [];
580
+ const around = (i, n) => text.slice(Math.max(0, i - 20), i + n + 20).replace(/\s+/g, " ").trim();
581
+ for (const m of scanned.matchAll(codeNamePattern("gi"))) {
582
+ hits.push({ word: m[0], use: map[m[0].toLowerCase()] ?? "", context: around(m.index ?? 0, m[0].length) });
583
+ }
584
+ for (const [re, use] of FORMER_WORDINGS) {
585
+ for (const m of scanned.matchAll(re)) hits.push({ word: m[0], use, context: around(m.index ?? 0, m[0].length) });
586
+ }
587
+ return hits;
588
+ };
589
+ var stripBlocks = (text, open, close) => {
590
+ let out = "";
591
+ let at = 0;
592
+ for (; ; ) {
593
+ const start = text.indexOf(open, at);
594
+ if (start < 0) return out + text.slice(at);
595
+ out += `${text.slice(at, start)} `;
596
+ const end = text.indexOf(close, start + open.length);
597
+ if (end < 0) return out;
598
+ at = end + close.length;
599
+ }
600
+ };
601
+ var SKIPPED_ELEMENTS = ["script", "style", "pre", "code", "svg"];
602
+ var openingOf = (lower, name, at) => {
603
+ for (let i = lower.indexOf(`<${name}`, at); i >= 0; i = lower.indexOf(`<${name}`, i + 1)) {
604
+ if (!/[a-z0-9-]/.test(lower[i + name.length + 1] ?? " ")) return i;
605
+ }
606
+ return -1;
607
+ };
608
+ var nextSkipped = (lower, at) => {
609
+ let found = [-1, ""];
610
+ for (const name of SKIPPED_ELEMENTS) {
611
+ const i = openingOf(lower, name, at);
612
+ if (i >= 0 && (found[0] < 0 || i < found[0])) found = [i, name];
613
+ }
614
+ return found;
615
+ };
616
+ var stripTags = (html) => {
617
+ let out = "";
618
+ let at = 0;
619
+ for (let open = html.indexOf("<"); open >= 0; open = html.indexOf("<", at)) {
620
+ const close = html.indexOf(">", open + 1);
621
+ if (close < 0) break;
622
+ out += `${html.slice(at, open)} `;
623
+ at = close + 1;
624
+ }
625
+ return out + html.slice(at);
626
+ };
627
+ var stripElements = (html) => {
628
+ const lower = html.toLowerCase();
629
+ let out = "";
630
+ let at = 0;
631
+ while (at < html.length) {
632
+ const [next, tag] = nextSkipped(lower, at);
633
+ if (next < 0) return out + html.slice(at);
634
+ out += `${html.slice(at, next)} `;
635
+ const end = lower.indexOf(`</${tag}>`, next);
636
+ if (end < 0) return out;
637
+ at = end + tag.length + 3;
638
+ }
639
+ return out;
640
+ };
641
+ var visibleText = (html) => {
642
+ const attrs = [];
643
+ for (const m of html.matchAll(/<meta\b[^>]*>/gi)) {
644
+ if (/\b(?:name|property)\s*=\s*["'](?:description|og:[\w:]+|twitter:[\w:]+|application-name|apple-mobile-web-app-title)["']/i.test(
645
+ m[0]
646
+ )) {
647
+ const content = /\bcontent\s*=\s*"([^"]*)"|\bcontent\s*=\s*'([^']*)'/i.exec(m[0]);
648
+ if (content) attrs.push(content[1] ?? content[2] ?? "");
649
+ }
650
+ }
651
+ for (const m of html.matchAll(/\b(?:alt|title|aria-label)\s*=\s*"([^"]*)"/gi)) attrs.push(m[1] ?? "");
652
+ const body = stripTags(stripElements(stripBlocks(html, "<!--", "-->"))).replaceAll("&nbsp;", " ").replaceAll("&amp;", "&");
653
+ return [body, ...attrs].join("\n");
654
+ };
655
+ var catalogueValues = (catalogue, path = "") => {
656
+ if (typeof catalogue === "string") return [[path, catalogue]];
657
+ if (Array.isArray(catalogue)) return catalogue.flatMap((v, i) => catalogueValues(v, `${path}[${i}]`));
658
+ if (catalogue && typeof catalogue === "object") {
659
+ return Object.entries(catalogue).flatMap(([k, v]) => catalogueValues(v, path ? `${path}.${k}` : k));
660
+ }
661
+ return [];
662
+ };
663
+
257
664
  // src/cast.ts
258
665
  var CAST_VERSION = 1;
259
666
  var CAST = [
260
667
  // The same three people as the deployed QA accounts (Eric, Mira, Camille) in each product, so a laptop and the dev deployment hold the same names.
261
- { id: "eric", product: "yomizaka", firstName: "\xC9ric", displayName: "\xC9ric Tremblay", role: "member", locale: "fr", avatar: "community-lead", workspace: "rosemont-villeray" },
262
- { id: "mira", product: "yomizaka", firstName: "Mira", displayName: "Mira Haddad", role: "admin", locale: "fr", avatar: "ai-builder", workspace: "administration" },
263
- { id: "camille", product: "yomizaka", firstName: "Camille", displayName: "Camille Tremblay", role: "member", locale: "fr", avatar: "visual-artist", workspace: "rosemont-villeray" },
668
+ {
669
+ id: "eric",
670
+ product: "yomizaka",
671
+ firstName: "\xC9ric",
672
+ displayName: "\xC9ric Tremblay",
673
+ role: "member",
674
+ locale: "fr",
675
+ avatar: "community-lead",
676
+ workspace: "rosemont-villeray"
677
+ },
678
+ {
679
+ id: "mira",
680
+ product: "yomizaka",
681
+ firstName: "Mira",
682
+ displayName: "Mira Haddad",
683
+ role: "admin",
684
+ locale: "fr",
685
+ avatar: "ai-builder",
686
+ workspace: "administration"
687
+ },
688
+ {
689
+ id: "camille",
690
+ product: "yomizaka",
691
+ firstName: "Camille",
692
+ displayName: "Camille Tremblay",
693
+ role: "member",
694
+ locale: "fr",
695
+ avatar: "visual-artist",
696
+ workspace: "rosemont-villeray"
697
+ },
264
698
  // Orazaka: the accounts already deployed on dev. Éric is the user (ORAZAKA_USER_*, APP_QA_ORAZAKA_PERSONA_*), Mira the administrator
265
699
  // (ORAZAKA_ADMIN_*, APP_QA_ORAZAKA_MIRA_*), Krizaka the company as an SME customer (APP_QA_ORAZAKA_KRIZAKA_*). The greeting reads the name: never « qa_user ».
266
- { id: "eric", product: "orazaka", firstName: "\xC9ric", displayName: "\xC9ric Tremblay", role: "member", locale: "fr", avatar: "community-lead", workspace: "demo" },
267
- { id: "mira", product: "orazaka", firstName: "Mira", displayName: "Mira Haddad", role: "admin", locale: "fr", avatar: "ai-builder", workspace: "administration" },
268
- { id: "krizaka", product: "orazaka", firstName: "Krizaka", displayName: "Krizaka", role: "member", locale: "fr", avatar: "tech-architect", workspace: "demo" },
700
+ {
701
+ id: "eric",
702
+ product: "orazaka",
703
+ firstName: "\xC9ric",
704
+ displayName: "\xC9ric Tremblay",
705
+ role: "member",
706
+ locale: "fr",
707
+ avatar: "community-lead",
708
+ workspace: "demo"
709
+ },
710
+ {
711
+ id: "mira",
712
+ product: "orazaka",
713
+ firstName: "Mira",
714
+ displayName: "Mira Haddad",
715
+ role: "admin",
716
+ locale: "fr",
717
+ avatar: "ai-builder",
718
+ workspace: "administration"
719
+ },
720
+ {
721
+ id: "krizaka",
722
+ product: "orazaka",
723
+ firstName: "Krizaka",
724
+ displayName: "Krizaka",
725
+ role: "member",
726
+ locale: "fr",
727
+ avatar: "tech-architect",
728
+ workspace: "demo"
729
+ },
269
730
  // Akinaza: Éric owns the Krizaka studio, Léa is the Saint-Henri walker, Camille is her first client, Mira administers.
270
- { id: "eric", product: "akinaza", firstName: "\xC9ric", displayName: "\xC9ric Tremblay", role: "owner", locale: "fr", avatar: "community-lead", banner: "creator-loft-studio", workspace: "krizaka-studio" },
271
- { id: "mira", product: "akinaza", firstName: "Mira", displayName: "Mira Haddad", role: "admin", locale: "fr", avatar: "ai-builder", workspace: "administration" },
272
- { id: "lea", product: "akinaza", firstName: "L\xE9a", displayName: "L\xE9a Beaulieu", role: "owner", locale: "fr", avatar: "studio-maker", banner: "cafe-maker-studio", workspace: "saint-henri" },
273
- { id: "camille", product: "akinaza", firstName: "Camille", displayName: "Camille Tremblay", role: "client", locale: "fr", avatar: "visual-artist", workspace: "saint-henri" },
274
- { id: "jordan", product: "akinaza", firstName: "Jordan", displayName: "Jordan Lee", role: "client", locale: "en", avatar: "tech-architect", workspace: "saint-henri" },
275
- { id: "nadia", product: "akinaza", firstName: "Nadia", displayName: "Nadia Benali", role: "client", locale: "fr", avatar: "digital-creator", workspace: "saint-henri" },
276
- { id: "etienne", product: "akinaza", firstName: "\xC9tienne", displayName: "\xC9tienne Gagnon", role: "client", locale: "fr", avatar: "boom-bap", workspace: "saint-henri" },
277
- { id: "sofia", product: "akinaza", firstName: "Sofia", displayName: "Sofia Rossi", role: "client", locale: "en", avatar: "salon-tattoo-maker", workspace: "saint-henri" }
731
+ {
732
+ id: "eric",
733
+ product: "akinaza",
734
+ firstName: "\xC9ric",
735
+ displayName: "\xC9ric Tremblay",
736
+ role: "owner",
737
+ locale: "fr",
738
+ avatar: "community-lead",
739
+ banner: "creator-loft-studio",
740
+ workspace: "krizaka-studio"
741
+ },
742
+ {
743
+ id: "mira",
744
+ product: "akinaza",
745
+ firstName: "Mira",
746
+ displayName: "Mira Haddad",
747
+ role: "admin",
748
+ locale: "fr",
749
+ avatar: "ai-builder",
750
+ workspace: "administration"
751
+ },
752
+ {
753
+ id: "lea",
754
+ product: "akinaza",
755
+ firstName: "L\xE9a",
756
+ displayName: "L\xE9a Beaulieu",
757
+ role: "owner",
758
+ locale: "fr",
759
+ avatar: "studio-maker",
760
+ banner: "cafe-maker-studio",
761
+ workspace: "saint-henri"
762
+ },
763
+ {
764
+ id: "camille",
765
+ product: "akinaza",
766
+ firstName: "Camille",
767
+ displayName: "Camille Tremblay",
768
+ role: "client",
769
+ locale: "fr",
770
+ avatar: "visual-artist",
771
+ workspace: "saint-henri"
772
+ },
773
+ {
774
+ id: "jordan",
775
+ product: "akinaza",
776
+ firstName: "Jordan",
777
+ displayName: "Jordan Lee",
778
+ role: "client",
779
+ locale: "en",
780
+ avatar: "tech-architect",
781
+ workspace: "saint-henri"
782
+ },
783
+ {
784
+ id: "nadia",
785
+ product: "akinaza",
786
+ firstName: "Nadia",
787
+ displayName: "Nadia Benali",
788
+ role: "client",
789
+ locale: "fr",
790
+ avatar: "digital-creator",
791
+ workspace: "saint-henri"
792
+ },
793
+ {
794
+ id: "etienne",
795
+ product: "akinaza",
796
+ firstName: "\xC9tienne",
797
+ displayName: "\xC9tienne Gagnon",
798
+ role: "client",
799
+ locale: "fr",
800
+ avatar: "boom-bap",
801
+ workspace: "saint-henri"
802
+ },
803
+ {
804
+ id: "sofia",
805
+ product: "akinaza",
806
+ firstName: "Sofia",
807
+ displayName: "Sofia Rossi",
808
+ role: "client",
809
+ locale: "en",
810
+ avatar: "salon-tattoo-maker",
811
+ workspace: "saint-henri"
812
+ }
278
813
  ];
279
814
  var castOf = (product) => CAST.filter((p) => p.product === product);
280
815
  function persona(product, id) {
281
816
  const found = CAST.find((p) => p.product === product && p.id === id);
282
- if (!found) throw new Error(`cast: no persona "${id}" in ${product} (known: ${castOf(product).map((p) => p.id).join(", ")})`);
817
+ if (!found)
818
+ throw new Error(
819
+ `cast: no persona "${id}" in ${product} (known: ${castOf(product).map((p) => p.id).join(", ")})`
820
+ );
283
821
  return found;
284
822
  }
285
823
  function personaByRole(product, role) {
@@ -314,7 +852,12 @@ var mark2 = {
314
852
  properties: { svg: httpsUrl, png64: httpsUrl, png256: httpsUrl, png512: httpsUrl, png1024: httpsUrl }
315
853
  };
316
854
  var slug = { type: "string", pattern: "^[a-z0-9]+(-[a-z0-9]+)*$" };
317
- var themed = { type: "object", additionalProperties: false, required: ["dark", "light"], properties: { dark: mark2, light: mark2 } };
855
+ var themed = {
856
+ type: "object",
857
+ additionalProperties: false,
858
+ required: ["dark", "light"],
859
+ properties: { dark: mark2, light: mark2 }
860
+ };
318
861
  var date = { type: "string", pattern: "^\\d{4}-\\d{2}-\\d{2}$" };
319
862
  var semver = { type: "string", pattern: "^\\d+\\.\\d+\\.\\d+$" };
320
863
  var defaultItems = {
@@ -333,7 +876,15 @@ var defaultItems = {
333
876
  type: "object",
334
877
  additionalProperties: false,
335
878
  required: ["webp"],
336
- properties: { svg: httpsUrl, webp: { type: "object", minProperties: 1, propertyNames: { pattern: "^\\d+$" }, additionalProperties: httpsUrl } }
879
+ properties: {
880
+ svg: httpsUrl,
881
+ webp: {
882
+ type: "object",
883
+ minProperties: 1,
884
+ propertyNames: { pattern: "^\\d+$" },
885
+ additionalProperties: httpsUrl
886
+ }
887
+ }
337
888
  }
338
889
  }
339
890
  }
@@ -344,7 +895,21 @@ var orgSchema = {
344
895
  title: "Krizaka organisation \u2014 public facts",
345
896
  type: "object",
346
897
  additionalProperties: false,
347
- required: ["$schema", "schemaVersion", "version", "updatedAt", "company", "brand", "people", "defaults", "products", "sites", "contact", "footer"],
898
+ required: [
899
+ "$schema",
900
+ "schemaVersion",
901
+ "version",
902
+ "updatedAt",
903
+ "company",
904
+ "brand",
905
+ "people",
906
+ "defaults",
907
+ "products",
908
+ "sites",
909
+ "family",
910
+ "contact",
911
+ "footer"
912
+ ],
348
913
  properties: {
349
914
  $schema: { type: "string" },
350
915
  schemaVersion: { enum: [1, 2] },
@@ -369,7 +934,15 @@ var orgSchema = {
369
934
  type: "object",
370
935
  additionalProperties: false,
371
936
  required: ["name", "logo", "mark", "favicon", "appleTouchIcon", "socialPreview", "manifest"],
372
- properties: { name: { type: "string", minLength: 1 }, logo: themed, mark: themed, favicon: httpsUrl, appleTouchIcon: httpsUrl, socialPreview: httpsUrl, manifest: httpsUrl }
937
+ properties: {
938
+ name: { type: "string", minLength: 1 },
939
+ logo: themed,
940
+ mark: themed,
941
+ favicon: httpsUrl,
942
+ appleTouchIcon: httpsUrl,
943
+ socialPreview: httpsUrl,
944
+ manifest: httpsUrl
945
+ }
373
946
  },
374
947
  people: {
375
948
  type: "object",
@@ -382,12 +955,24 @@ var orgSchema = {
382
955
  type: "object",
383
956
  additionalProperties: false,
384
957
  required: ["id", "kind", "svg", "webp256", "webp512", "alt"],
385
- properties: { id: slug, kind: { enum: ["person", "plain"] }, svg: httpsUrl, webp256: httpsUrl, webp512: httpsUrl, alt: localized }
958
+ properties: {
959
+ id: slug,
960
+ kind: { enum: ["person", "plain"] },
961
+ svg: httpsUrl,
962
+ webp256: httpsUrl,
963
+ webp512: httpsUrl,
964
+ alt: localized
965
+ }
386
966
  }
387
967
  },
388
968
  banners: {
389
969
  type: "array",
390
- items: { type: "object", additionalProperties: false, required: ["id", "url", "alt"], properties: { id: slug, url: httpsUrl, alt: localized } }
970
+ items: {
971
+ type: "object",
972
+ additionalProperties: false,
973
+ required: ["id", "url", "alt"],
974
+ properties: { id: slug, url: httpsUrl, alt: localized }
975
+ }
391
976
  }
392
977
  }
393
978
  },
@@ -398,12 +983,19 @@ var orgSchema = {
398
983
  properties: {
399
984
  version: { type: "string", pattern: "^v\\d+$" },
400
985
  base: httpsUrl,
401
- rule: { type: "object", additionalProperties: false, required: ["pick", "description"], properties: { pick: { const: "fnv1a32-modulo" }, description: { type: "string", minLength: 1 } } },
986
+ rule: {
987
+ type: "object",
988
+ additionalProperties: false,
989
+ required: ["pick", "description"],
990
+ properties: { pick: { const: "fnv1a32-modulo" }, description: { type: "string", minLength: 1 } }
991
+ },
402
992
  kinds: {
403
993
  type: "object",
404
994
  additionalProperties: false,
405
995
  required: ["person", "folder", "organisation", "shop", "banner"],
406
- properties: Object.fromEntries(["person", "folder", "organisation", "shop", "banner"].map((kind) => [kind, defaultItems]))
996
+ properties: Object.fromEntries(
997
+ ["person", "folder", "organisation", "shop", "banner"].map((kind) => [kind, defaultItems])
998
+ )
407
999
  }
408
1000
  }
409
1001
  },
@@ -414,20 +1006,55 @@ var orgSchema = {
414
1006
  type: "object",
415
1007
  additionalProperties: false,
416
1008
  required: ["id", "name", "status", "url", "repo"],
417
- properties: { id: slug, name: { type: "string", minLength: 1 }, status: { enum: ["development", "devPreview"] }, url: httpsUrl, repo: httpsUrl }
1009
+ properties: {
1010
+ id: slug,
1011
+ name: { type: "string", minLength: 1 },
1012
+ status: { enum: ["development", "devPreview"] },
1013
+ url: httpsUrl,
1014
+ repo: httpsUrl
1015
+ }
418
1016
  }
419
1017
  },
420
1018
  sites: {
421
1019
  type: "array",
422
1020
  minItems: 1,
423
- items: { type: "object", additionalProperties: false, required: ["id", "name", "url"], properties: { id: slug, name: { type: "string", minLength: 1 }, url: httpsUrl } }
1021
+ items: {
1022
+ type: "object",
1023
+ additionalProperties: false,
1024
+ required: ["id", "name", "url"],
1025
+ properties: { id: slug, name: { type: "string", minLength: 1 }, url: httpsUrl }
1026
+ }
1027
+ },
1028
+ family: {
1029
+ type: "array",
1030
+ minItems: 1,
1031
+ items: {
1032
+ type: "object",
1033
+ additionalProperties: false,
1034
+ required: ["id", "name", "short", "group", "status", "url", "repo"],
1035
+ properties: {
1036
+ id: slug,
1037
+ name: { type: "string", minLength: 1 },
1038
+ short: { type: "string", minLength: 1 },
1039
+ group: { enum: ["krizaka", "products", "open-source", "github"] },
1040
+ status: { enum: ["released", "development"] },
1041
+ releasedAt: { type: "string", pattern: "^\\d{4}-\\d{2}-\\d{2}$" },
1042
+ url: httpsUrl,
1043
+ repo: { anyOf: [httpsUrl, { type: "null" }] }
1044
+ }
1045
+ }
424
1046
  },
425
1047
  contact: {
426
1048
  type: "object",
427
1049
  additionalProperties: false,
428
1050
  required: ["page", "email"],
429
1051
  properties: {
430
- page: { type: "object", additionalProperties: false, required: ["fr", "en"], properties: { fr: httpsUrl, en: httpsUrl } },
1052
+ page: {
1053
+ type: "object",
1054
+ additionalProperties: false,
1055
+ required: ["fr", "en"],
1056
+ properties: { fr: httpsUrl, en: httpsUrl }
1057
+ },
431
1058
  email: { type: ["string", "null"], format: "email" }
432
1059
  }
433
1060
  },
@@ -444,7 +1071,16 @@ var orgSchema = {
444
1071
  type: "object",
445
1072
  additionalProperties: false,
446
1073
  required: ["id", "label", "url"],
447
- properties: { id: { enum: ["privacy", "terms"] }, label: localized, url: { type: "object", additionalProperties: false, required: ["fr", "en"], properties: { fr: httpsUrl, en: httpsUrl } } }
1074
+ properties: {
1075
+ id: { enum: ["privacy", "terms"] },
1076
+ label: localized,
1077
+ url: {
1078
+ type: "object",
1079
+ additionalProperties: false,
1080
+ required: ["fr", "en"],
1081
+ properties: { fr: httpsUrl, en: httpsUrl }
1082
+ }
1083
+ }
448
1084
  }
449
1085
  }
450
1086
  }
@@ -477,30 +1113,48 @@ var appSchema = {
477
1113
  // src/index.ts
478
1114
  var localized2 = (text, locale) => locale === "fr" ? text.fr : text.en;
479
1115
  var footerLine = (locale) => localized2(org.footer.line, locale);
1116
+ var familyEntry = (id) => {
1117
+ const entry = org.family.find((e) => e.id === id);
1118
+ if (!entry) throw new Error(`Unknown Krizaka family entry "${id}".`);
1119
+ return entry;
1120
+ };
1121
+ var familyName = (id) => familyEntry(id).name;
480
1122
  export {
481
1123
  APP_SCHEMA_URL,
482
1124
  CAST,
483
1125
  CAST_VERSION,
484
1126
  CDN,
1127
+ CODE_NAMES,
485
1128
  DEFAULT_KINDS,
1129
+ DISPLAY_NAME_MAX,
486
1130
  ORG_SCHEMA_URL,
487
1131
  ORG_URL,
488
1132
  appSchema,
489
1133
  apps,
1134
+ brandOf,
1135
+ brands,
490
1136
  castMedia,
491
1137
  castOf,
1138
+ catalogueValues,
1139
+ codeNameMap,
492
1140
  defaultFor,
493
1141
  defaultUrl,
494
1142
  defaults,
1143
+ displayName,
1144
+ familyEntry,
1145
+ familyName,
495
1146
  fetchDefaults,
1147
+ findCodeNames,
496
1148
  footerLine,
497
1149
  listDefaults,
498
1150
  localized2 as localized,
1151
+ lockup,
499
1152
  org,
500
1153
  orgSchema,
501
1154
  persona,
502
1155
  personaByRole,
503
1156
  seedFingerprint,
504
- seedHash
1157
+ seedHash,
1158
+ visibleText
505
1159
  };
506
1160
  //# sourceMappingURL=index.js.map