taleem-browser 0.2.0 → 1.0.0-rc.1

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.
@@ -20,34 +20,25 @@ var TaleemBrowser = (() => {
20
20
  // src/index.js
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- TALEEM_BROWSER_VERSION: () => TALEEM_BROWSER_VERSION,
24
- TALEEM_CSS_URL: () => TALEEM_CSS_URL,
25
23
  createTaleemBrowser: () => createTaleemBrowser
26
24
  });
27
25
 
28
26
  // node_modules/taleem-slides/src/slides/TitleSlide.js
29
27
  var TitleSlide = {
30
28
  type: "titleSlide",
31
- /**
32
- * Build a TitleSlide from raw deck JSON
33
- */
34
- fromJSON(rawSlide, index) {
35
- if (!Array.isArray(rawSlide.data)) {
36
- throw new Error(`TitleSlide: data must be an array`);
37
- }
38
- const titleItem = rawSlide.data.find((d) => d.name === "title");
39
- if (!titleItem || typeof titleItem.content !== "string") {
40
- throw new Error(`TitleSlide: missing or invalid title content`);
29
+ fromJSON(raw) {
30
+ const title = raw.data?.find((d) => d.name === "title")?.content;
31
+ if (!title) {
32
+ throw new Error("titleSlide: requires title");
41
33
  }
42
- const title = titleItem.content;
43
34
  return Object.freeze({
44
35
  type: "titleSlide",
45
36
  render() {
46
37
  return `
47
- <div class="slide titleSlide">
48
- <h1>${title}</h1>
49
- </div>
50
- `;
38
+ <section class="slide titleSlide">
39
+ <h1>${title}</h1>
40
+ </section>
41
+ `;
51
42
  }
52
43
  });
53
44
  }
@@ -66,11 +57,11 @@ var TaleemBrowser = (() => {
66
57
  type: "titleAndSubtitle",
67
58
  render() {
68
59
  return `
69
- <section class="slide titleAndSubtitle">
70
- <h1>${title}</h1>
71
- <h2>${subtitle}</h2>
72
- </section>
73
- `;
60
+ <section class="slide titleAndSubtitle">
61
+ <h1>${title}</h1>
62
+ <h2>${subtitle}</h2>
63
+ </section>
64
+ `;
74
65
  }
75
66
  });
76
67
  }
@@ -89,11 +80,11 @@ var TaleemBrowser = (() => {
89
80
  type: "titleAndPara",
90
81
  render() {
91
82
  return `
92
- <section class="slide titleAndPara">
93
- <h1>${title}</h1>
94
- <p>${para}</p>
95
- </section>
96
- `;
83
+ <section class="slide titleAndPara">
84
+ <h1>${title}</h1>
85
+ <p>${para}</p>
86
+ </section>
87
+ `;
97
88
  }
98
89
  });
99
90
  }
@@ -109,14 +100,19 @@ var TaleemBrowser = (() => {
109
100
  }
110
101
  return Object.freeze({
111
102
  type: "bulletList",
112
- render() {
103
+ bullets,
104
+ render({ visibleCount = bullets.length, activeIndex = null } = {}) {
113
105
  return `
114
- <section class="slide bulletList">
115
- <ul>
116
- ${bullets.map((b) => `<li>${b}</li>`).join("")}
117
- </ul>
118
- </section>
119
- `;
106
+ <section class="slide bulletList">
107
+ <ul>
108
+ ${bullets.map((text, i) => {
109
+ if (i >= visibleCount) return "";
110
+ const cls = i === activeIndex ? "is-active" : activeIndex !== null && i < activeIndex ? "is-dim" : "";
111
+ return `<li class="${cls}">${text}</li>`;
112
+ }).join("")}
113
+ </ul>
114
+ </section>
115
+ `;
120
116
  }
121
117
  });
122
118
  }
@@ -129,17 +125,21 @@ var TaleemBrowser = (() => {
129
125
  const left = raw.data?.filter((d) => d.name === "left").map((d) => d.content);
130
126
  const right = raw.data?.filter((d) => d.name === "right").map((d) => d.content);
131
127
  if (!left?.length || !right?.length) {
132
- throw new Error("twoColumnText: requires left and right columns");
128
+ throw new Error("twoColumnText: requires left and right");
133
129
  }
134
130
  return Object.freeze({
135
131
  type: "twoColumnText",
136
132
  render() {
137
133
  return `
138
- <section class="slide twoColumnText">
139
- <div class="col left">${left.join("<br/>")}</div>
140
- <div class="col right">${right.join("<br/>")}</div>
141
- </section>
142
- `;
134
+ <section class="slide twoColumnText">
135
+ <div class="col left">
136
+ ${left.map((v) => `<div>${v}</div>`).join("")}
137
+ </div>
138
+ <div class="col right">
139
+ ${right.map((v) => `<div>${v}</div>`).join("")}
140
+ </div>
141
+ </section>
142
+ `;
143
143
  }
144
144
  });
145
145
  }
@@ -153,12 +153,13 @@ var TaleemBrowser = (() => {
153
153
  if (!src) throw new Error("imageSlide: image required");
154
154
  return Object.freeze({
155
155
  type: "imageSlide",
156
+ src,
156
157
  render() {
157
158
  return `
158
- <section class="slide imageSlide">
159
- <img src="${src}" alt="" />
160
- </section>
161
- `;
159
+ <section class="slide imageSlide">
160
+ <img src="${src}" alt="" />
161
+ </section>
162
+ `;
162
163
  }
163
164
  });
164
165
  }
@@ -174,12 +175,13 @@ var TaleemBrowser = (() => {
174
175
  }
175
176
  return Object.freeze({
176
177
  type: "fillImage",
178
+ image,
177
179
  render() {
178
180
  return `
179
- <section class="slide fillImage">
180
- <img src="${image}" alt="" />
181
- </section>
182
- `;
181
+ <section class="slide fillImage">
182
+ <img src="${image}" alt="" />
183
+ </section>
184
+ `;
183
185
  }
184
186
  });
185
187
  }
@@ -196,13 +198,15 @@ var TaleemBrowser = (() => {
196
198
  }
197
199
  return Object.freeze({
198
200
  type: "imageWithTitle",
201
+ src,
202
+ title,
199
203
  render() {
200
204
  return `
201
- <section class="slide imageWithTitle">
202
- <img src="${src}" alt="" />
203
- <h1>${title}</h1>
204
- </section>
205
- `;
205
+ <section class="slide imageWithTitle">
206
+ <img src="${src}" alt="" />
207
+ <h1>${title}</h1>
208
+ </section>
209
+ `;
206
210
  }
207
211
  });
208
212
  }
@@ -219,13 +223,15 @@ var TaleemBrowser = (() => {
219
223
  }
220
224
  return Object.freeze({
221
225
  type: "imageWithCaption",
226
+ src,
227
+ caption,
222
228
  render() {
223
229
  return `
224
- <figure class="slide imageWithCaption">
225
- <img src="${src}" alt="" />
226
- <figcaption>${caption}</figcaption>
227
- </figure>
228
- `;
230
+ <figure class="slide imageWithCaption">
231
+ <img src="${src}" alt="" />
232
+ <figcaption>${caption}</figcaption>
233
+ </figure>
234
+ `;
229
235
  }
230
236
  });
231
237
  }
@@ -237,20 +243,24 @@ var TaleemBrowser = (() => {
237
243
  fromJSON(raw) {
238
244
  const image = raw.data?.find((d) => d.name === "image")?.content;
239
245
  const bullets = raw.data?.filter((d) => d.name === "bullet").map((d) => d.content);
240
- if (!image || !bullets?.length) {
246
+ if (!image || !bullets || bullets.length === 0) {
241
247
  throw new Error("imageLeftBulletsRight: image and bullets required");
242
248
  }
243
249
  return Object.freeze({
244
250
  type: "imageLeftBulletsRight",
245
- render() {
251
+ image,
252
+ bullets,
253
+ render({ visibleCount = bullets.length } = {}) {
246
254
  return `
247
- <section class="slide imageLeftBulletsRight">
248
- <img src="${image}" alt="" />
249
- <ul>
250
- ${bullets.map((b) => `<li>${b}</li>`).join("")}
251
- </ul>
252
- </section>
253
- `;
255
+ <section class="slide imageLeftBulletsRight">
256
+ <img src="${image}" alt="" />
257
+ <ul>
258
+ ${bullets.map(
259
+ (text, i) => i < visibleCount ? `<li>${text}</li>` : ""
260
+ ).join("")}
261
+ </ul>
262
+ </section>
263
+ `;
254
264
  }
255
265
  });
256
266
  }
@@ -262,20 +272,24 @@ var TaleemBrowser = (() => {
262
272
  fromJSON(raw) {
263
273
  const image = raw.data?.find((d) => d.name === "image")?.content;
264
274
  const bullets = raw.data?.filter((d) => d.name === "bullet").map((d) => d.content);
265
- if (!image || !bullets?.length) {
275
+ if (!image || !bullets || bullets.length === 0) {
266
276
  throw new Error("imageRightBulletsLeft: image and bullets required");
267
277
  }
268
278
  return Object.freeze({
269
279
  type: "imageRightBulletsLeft",
270
- render() {
280
+ image,
281
+ bullets,
282
+ render({ visibleCount = bullets.length } = {}) {
271
283
  return `
272
- <section class="slide imageRightBulletsLeft">
273
- <ul>
274
- ${bullets.map((b) => `<li>${b}</li>`).join("")}
275
- </ul>
276
- <img src="${image}" alt="" />
277
- </section>
278
- `;
284
+ <section class="slide imageRightBulletsLeft">
285
+ <ul>
286
+ ${bullets.map(
287
+ (text, i) => i < visibleCount ? `<li>${text}</li>` : ""
288
+ ).join("")}
289
+ </ul>
290
+ <img src="${image}" alt="" />
291
+ </section>
292
+ `;
279
293
  }
280
294
  });
281
295
  }
@@ -285,20 +299,26 @@ var TaleemBrowser = (() => {
285
299
  var TableSlide = {
286
300
  type: "table",
287
301
  fromJSON(raw) {
288
- const rows = raw.data?.filter((d) => d.name === "row").map((d) => d.content);
289
- if (!rows || rows.length === 0) {
290
- throw new Error("table: requires at least one row");
302
+ const headers = raw.data?.find((d) => d.name === "header")?.content;
303
+ const rows = raw.data?.find((d) => d.name === "row")?.content;
304
+ if (!headers || !rows?.length) {
305
+ throw new Error("table: requires headers and at least one row");
291
306
  }
292
307
  return Object.freeze({
293
308
  type: "table",
294
309
  render() {
295
310
  return `
296
- <table class="slide table">
311
+ <table class="slide table">
312
+ <thead>
313
+ <tr>${headers.map((h) => `<th>${h}</th>`).join("")}</tr>
314
+ </thead>
315
+ <tbody>
297
316
  ${rows.map(
298
- (row) => `<tr>${row.map((cell) => `<td>${cell}</td>`).join("")}</tr>`
317
+ (r) => `<tr>${r.map((c) => `<td>${c}</td>`).join("")}</tr>`
299
318
  ).join("")}
300
- </table>
301
- `;
319
+ </tbody>
320
+ </table>
321
+ `;
302
322
  }
303
323
  });
304
324
  }
@@ -309,19 +329,21 @@ var TaleemBrowser = (() => {
309
329
  type: "statistic",
310
330
  fromJSON(raw) {
311
331
  const label = raw.data?.find((d) => d.name === "label")?.content;
312
- const value = raw.data?.find((d) => d.name === "value")?.content;
313
- if (!label || value === void 0) {
314
- throw new Error("statistic: requires label and value");
332
+ const number = raw.data?.find((d) => d.name === "number")?.content;
333
+ if (!label || number === void 0) {
334
+ throw new Error("statistic: requires number and label");
315
335
  }
316
336
  return Object.freeze({
317
337
  type: "statistic",
338
+ label,
339
+ number,
318
340
  render() {
319
341
  return `
320
- <section class="slide statistic">
321
- <div class="stat-value">${value}</div>
322
- <div class="stat-label">${label}</div>
323
- </section>
324
- `;
342
+ <section class="slide statistic">
343
+ <div class="stat-value">${number}</div>
344
+ <div class="stat-label">${label}</div>
345
+ </section>
346
+ `;
325
347
  }
326
348
  });
327
349
  }
@@ -331,18 +353,22 @@ var TaleemBrowser = (() => {
331
353
  var BigNumberSlide = {
332
354
  type: "bigNumber",
333
355
  fromJSON(raw) {
334
- const value = raw.data?.find((d) => d.name === "number")?.content;
356
+ const number = raw.data?.find((d) => d.name === "number")?.content;
335
357
  const label = raw.data?.find((d) => d.name === "label")?.content;
336
- if (!value) throw new Error("bigNumber: number required");
358
+ if (!number) {
359
+ throw new Error("bigNumber: number required");
360
+ }
337
361
  return Object.freeze({
338
362
  type: "bigNumber",
363
+ number,
364
+ label,
339
365
  render() {
340
366
  return `
341
- <section class="slide bigNumber">
342
- <div class="number">${value}</div>
343
- ${label ? `<div class="label">${label}</div>` : ""}
344
- </section>
345
- `;
367
+ <section class="slide bigNumber">
368
+ <div class="number">${number}</div>
369
+ ${label ? `<div class="label">${label}</div>` : ""}
370
+ </section>
371
+ `;
346
372
  }
347
373
  });
348
374
  }
@@ -352,32 +378,33 @@ var TaleemBrowser = (() => {
352
378
  var BarChartSlide = {
353
379
  type: "barChart",
354
380
  fromJSON(raw) {
355
- const bars = raw.data?.filter((d) => d.name === "bar");
381
+ const bars = raw.data?.filter((d) => d.name === "bar").map((d) => ({
382
+ label: d.label,
383
+ value: d.value
384
+ }));
356
385
  if (!bars || bars.length === 0) {
357
386
  throw new Error("barChart: requires at least one bar");
358
387
  }
359
- bars.forEach((b, i) => {
360
- if (typeof b.content !== "object" || typeof b.content.label !== "string" || typeof b.content.value !== "number") {
361
- throw new Error(`barChart: invalid bar at index ${i}`);
362
- }
363
- });
364
388
  return Object.freeze({
365
389
  type: "barChart",
366
- render() {
390
+ bars,
391
+ render({ visibleCount = bars.length, activeIndex = null } = {}) {
367
392
  return `
368
- <section class="slide barChart">
369
- <ul class="bars">
370
- ${bars.map(
371
- (b) => `
372
- <li class="bar">
373
- <span class="bar-label">${b.content.label}</span>
374
- <span class="bar-value">${b.content.value}</span>
375
- </li>
376
- `
377
- ).join("")}
378
- </ul>
379
- </section>
380
- `;
393
+ <section class="slide barChart">
394
+ <ul class="bars">
395
+ ${bars.map((b, i) => {
396
+ if (i >= visibleCount) return "";
397
+ const cls = i === activeIndex ? "is-active" : activeIndex !== null && i < activeIndex ? "is-dim" : "";
398
+ return `
399
+ <li class="bar ${cls}">
400
+ <span class="bar-label">${b.label}</span>
401
+ <span class="bar-value">${b.value}</span>
402
+ </li>
403
+ `;
404
+ }).join("")}
405
+ </ul>
406
+ </section>
407
+ `;
381
408
  }
382
409
  });
383
410
  }
@@ -387,22 +414,35 @@ var TaleemBrowser = (() => {
387
414
  var DonutChartSlide = {
388
415
  type: "donutChart",
389
416
  fromJSON(raw) {
390
- const segments = raw.data?.filter((d) => d.name === "segment");
391
- if (!segments || segments.length === 0) {
417
+ const segments = [];
418
+ let current = null;
419
+ for (const d of raw.data || []) {
420
+ if (d.name === "percent") {
421
+ current = { percent: d.content };
422
+ segments.push(current);
423
+ } else if (current && d.name === "label") {
424
+ current.label = d.content;
425
+ } else if (current && d.name === "color") {
426
+ current.color = d.content;
427
+ }
428
+ }
429
+ if (!segments.length) {
392
430
  throw new Error("donutChart: requires at least one segment");
393
431
  }
394
432
  return Object.freeze({
395
433
  type: "donutChart",
396
- render() {
434
+ segments,
435
+ render({ visibleCount = segments.length } = {}) {
397
436
  return `
398
- <section class="slide donutChart">
399
- <ul>
400
- ${segments.map(
401
- (s) => `<li>${s.content.label}: ${s.content.value}</li>`
402
- ).join("")}
403
- </ul>
404
- </section>
405
- `;
437
+ <section class="slide donutChart">
438
+ <ul>
439
+ ${segments.map((s, i) => {
440
+ if (i >= visibleCount) return "";
441
+ return `<li>${s.label}: ${s.percent}%</li>`;
442
+ }).join("")}
443
+ </ul>
444
+ </section>
445
+ `;
406
446
  }
407
447
  });
408
448
  }
@@ -412,18 +452,22 @@ var TaleemBrowser = (() => {
412
452
  var QuoteSlide = {
413
453
  type: "quoteSlide",
414
454
  fromJSON(raw) {
415
- const text = raw.data?.find((d) => d.name === "quote")?.content;
455
+ const quote = raw.data?.find((d) => d.name === "quote")?.content;
416
456
  const author = raw.data?.find((d) => d.name === "author")?.content;
417
- if (!text) throw new Error("quoteSlide: quote required");
457
+ if (!quote) {
458
+ throw new Error("quoteSlide: quote required");
459
+ }
418
460
  return Object.freeze({
419
461
  type: "quoteSlide",
462
+ quote,
463
+ author,
420
464
  render() {
421
465
  return `
422
- <blockquote class="slide quoteSlide">
423
- <p>${text}</p>
424
- ${author ? `<footer>${author}</footer>` : ""}
425
- </blockquote>
426
- `;
466
+ <blockquote class="slide quoteSlide">
467
+ <p>${quote}</p>
468
+ ${author ? `<footer>${author}</footer>` : ""}
469
+ </blockquote>
470
+ `;
427
471
  }
428
472
  });
429
473
  }
@@ -441,16 +485,19 @@ var TaleemBrowser = (() => {
441
485
  }
442
486
  return Object.freeze({
443
487
  type: "quoteWithImage",
488
+ quote,
489
+ image,
490
+ author,
444
491
  render() {
445
492
  return `
446
- <section class="slide quoteWithImage">
447
- <img src="${image}" alt="" />
448
- <blockquote>
449
- <p>${quote}</p>
450
- ${author ? `<footer>${author}</footer>` : ""}
451
- </blockquote>
452
- </section>
453
- `;
493
+ <section class="slide quoteWithImage">
494
+ <img src="${image}" alt="" />
495
+ <blockquote>
496
+ <p>${quote}</p>
497
+ ${author ? `<footer>${author}</footer>` : ""}
498
+ </blockquote>
499
+ </section>
500
+ `;
454
501
  }
455
502
  });
456
503
  }
@@ -460,20 +507,27 @@ var TaleemBrowser = (() => {
460
507
  var CornerWordsSlide = {
461
508
  type: "cornerWordsSlide",
462
509
  fromJSON(raw) {
463
- const words = raw.data?.filter((d) => d.name === "word").map((d) => d.content);
464
- if (!words || words.length === 0) {
465
- throw new Error("cornerWordsSlide: requires at least one word");
510
+ const cards = raw.data?.filter((d) => d.name === "card").map((d) => ({ icon: d.icon, label: d.label }));
511
+ if (!cards || cards.length === 0) {
512
+ throw new Error("cornerWordsSlide: requires at least one card");
466
513
  }
467
514
  return Object.freeze({
468
515
  type: "cornerWordsSlide",
469
- render() {
516
+ cards,
517
+ render({ visibleCount = cards.length } = {}) {
470
518
  return `
471
- <section class="slide cornerWordsSlide">
472
- ${words.map(
473
- (w, i) => `<span class="corner-word corner-${i + 1}">${w}</span>`
474
- ).join("")}
475
- </section>
476
- `;
519
+ <section class="slide cornerWordsSlide">
520
+ ${cards.map((c, i) => {
521
+ if (i >= visibleCount) return "";
522
+ return `
523
+ <span class="corner-card corner-${i + 1}">
524
+ <span class="icon">${c.icon}</span>
525
+ <span class="label">${c.label}</span>
526
+ </span>
527
+ `;
528
+ }).join("")}
529
+ </section>
530
+ `;
477
531
  }
478
532
  });
479
533
  }
@@ -483,16 +537,19 @@ var TaleemBrowser = (() => {
483
537
  var ContactSlide = {
484
538
  type: "contactSlide",
485
539
  fromJSON(raw) {
486
- const items = raw.data?.map((d) => `<div>${d.content}</div>`);
487
- if (!items?.length) throw new Error("contactSlide: content required");
540
+ const items = raw.data?.map((d) => d.content);
541
+ if (!items || items.length === 0) {
542
+ throw new Error("contactSlide: content required");
543
+ }
488
544
  return Object.freeze({
489
545
  type: "contactSlide",
546
+ items,
490
547
  render() {
491
548
  return `
492
- <section class="slide contactSlide">
493
- ${items.join("")}
494
- </section>
495
- `;
549
+ <section class="slide contactSlide">
550
+ ${items.map((text) => `<div>${text}</div>`).join("")}
551
+ </section>
552
+ `;
496
553
  }
497
554
  });
498
555
  }
@@ -502,43 +559,33 @@ var TaleemBrowser = (() => {
502
559
  var EqSlide = {
503
560
  type: "eq",
504
561
  fromJSON(raw) {
505
- if (!Array.isArray(raw.data)) {
506
- throw new Error("eq: data must be array");
562
+ const lines = raw.data?.filter((d) => d.name === "line").map((d) => ({
563
+ type: d.type,
564
+ content: d.content
565
+ }));
566
+ if (!lines || lines.length === 0) {
567
+ throw new Error("eq: requires at least one line");
507
568
  }
508
569
  return Object.freeze({
509
570
  type: "eq",
510
- render() {
571
+ lines,
572
+ render({ visibleCount = lines.length, activeIndex = null } = {}) {
511
573
  return `
512
- <section class="slide eq">
513
- ${raw.data.map((d) => `<div>${d.content}</div>`).join("")}
514
- </section>
515
- `;
574
+ <section class="slide eq">
575
+ ${lines.map((l, i) => {
576
+ if (i >= visibleCount) return "";
577
+ const cls = i === activeIndex ? "is-active" : activeIndex !== null && i < activeIndex ? "is-dim" : "";
578
+ return `<div class="eq-line ${cls}">${l.content}</div>`;
579
+ }).join("")}
580
+ </section>
581
+ `;
516
582
  }
517
583
  });
518
584
  }
519
585
  };
520
586
 
521
- // node_modules/taleem-slides/src/slides/SvgPointerSlide.js
522
- var SvgPointerSlide = {
523
- type: "svgPointer",
524
- fromJSON(raw) {
525
- const svg = raw.data?.find((d) => d.name === "svg")?.content;
526
- if (!svg) throw new Error("svgPointer: svg required");
527
- return Object.freeze({
528
- type: "svgPointer",
529
- render() {
530
- return `
531
- <section class="slide svgPointer">
532
- ${svg}
533
- </section>
534
- `;
535
- }
536
- });
537
- }
538
- };
539
-
540
- // node_modules/taleem-slides/src/registry.js
541
- var registry = {
587
+ // node_modules/taleem-slides/src/SlideTemplates.js
588
+ var SlideTemplates = {
542
589
  titleSlide: TitleSlide,
543
590
  titleAndSubtitle: TitleAndSubtitleSlide,
544
591
  titleAndPara: TitleAndParaSlide,
@@ -559,114 +606,30 @@ var TaleemBrowser = (() => {
559
606
  quoteWithImage: QuoteWithImageSlide,
560
607
  cornerWordsSlide: CornerWordsSlide,
561
608
  contactSlide: ContactSlide,
562
- eq: EqSlide,
563
- svgPointer: SvgPointerSlide
564
- };
565
-
566
- // node_modules/taleem-slides/src/slideManager/SlideManager.js
567
- var SlideManager = class {
568
- #slides;
569
- constructor(slides) {
570
- if (!Array.isArray(slides)) {
571
- throw new Error("SlideManager: slides must be an array");
572
- }
573
- this.#slides = slides;
574
- }
575
- /**
576
- * Render a single slide by index.
577
- *
578
- * @param {number} index
579
- * @param {number} [showAt]
580
- * @returns {string} HTML
581
- */
582
- renderSlide(index, showAt) {
583
- const slide = this.#slides[index];
584
- if (!slide) {
585
- throw new Error(`SlideManager: invalid slide index ${index}`);
586
- }
587
- if (typeof slide.render !== "function") {
588
- throw new Error(
589
- `SlideManager: slide at index ${index} has no render() method`
590
- );
591
- }
592
- return slide.render(showAt);
593
- }
594
- /**
595
- * Render all slides as a static HTML dump.
596
- *
597
- * @returns {string} HTML
598
- */
599
- renderAll() {
600
- return this.#slides.map((slide, index) => {
601
- if (typeof slide.render !== "function") {
602
- throw new Error(
603
- `SlideManager: slide at index ${index} has no render() method`
604
- );
605
- }
606
- return slide.render();
607
- }).join("\n");
608
- }
609
+ eq: EqSlide
609
610
  };
610
611
 
611
- // node_modules/taleem-slides/src/interpreter/slideBuilder.js
612
- function slideBuilder(deckV1Json) {
613
- if (!deckV1Json || typeof deckV1Json !== "object") {
614
- throw new Error("slideBuilder: input must be an object");
615
- }
616
- if (deckV1Json.version !== "deck-v1") {
617
- throw new Error(
618
- `slideBuilder: unsupported deck version "${deckV1Json.version}"`
619
- );
612
+ // node_modules/taleem-slides/src/getSlideTemplate.js
613
+ function getSlideTemplate(type) {
614
+ const template = SlideTemplates[type];
615
+ if (!template) {
616
+ throw new Error(`Unknown slide template type "${type}"`);
620
617
  }
621
- if (!Array.isArray(deckV1Json.deck)) {
622
- throw new Error("slideBuilder: deck must be an array");
623
- }
624
- const slides = deckV1Json.deck.map((rawSlide, index) => {
625
- if (!rawSlide || typeof rawSlide !== "object") {
626
- throw new Error(`slideBuilder: slide ${index} is not an object`);
627
- }
628
- const { type } = rawSlide;
629
- if (!type || typeof type !== "string") {
630
- throw new Error(`slideBuilder: slide ${index} has no valid type`);
631
- }
632
- const builder = registry[type];
633
- if (!builder) {
634
- throw new Error(
635
- `slideBuilder: unsupported slide type "${type}" at index ${index}`
636
- );
637
- }
638
- try {
639
- return builder.fromJSON(rawSlide, index);
640
- } catch (err) {
641
- throw new Error(
642
- `slideBuilder: failed to build slide "${type}" at index ${index}
643
- ${err.message}`
644
- );
645
- }
646
- });
647
- slides.forEach(Object.freeze);
648
- Object.freeze(slides);
649
- return new SlideManager(slides);
618
+ return template;
650
619
  }
651
620
 
652
- // src/release.js
653
- var TALEEM_BROWSER_VERSION = "0.1.3";
654
- var TALEEM_CSS_URL = "https://github.com/bilza2023/taleem-browser/releases/download/v0.1.3/taleem.css";
655
-
656
- // src/index.js
621
+ // src/createBrowser.js
657
622
  function createTaleemBrowser({ mount, deck }) {
658
623
  if (!mount) {
659
624
  throw new Error("taleem-browser: mount is required");
660
625
  }
661
626
  if (!deck || !Array.isArray(deck.deck)) {
662
- throw new Error("taleem-browser: valid deck object required");
627
+ throw new Error("taleem-browser: valid deck-v1 required");
663
628
  }
664
629
  const root = typeof mount === "string" ? document.querySelector(mount) : mount;
665
630
  if (!root) {
666
- throw new Error("taleem-browser: mount element not found");
631
+ throw new Error("taleem-browser: mount not found");
667
632
  }
668
- let currentIndex = 0;
669
- const total = deck.deck.length;
670
633
  root.innerHTML = `
671
634
  <div class="taleem-browser-bg"></div>
672
635
  <div class="taleem-browser-slide"></div>
@@ -674,45 +637,27 @@ ${err.message}`
674
637
  const bgEl = root.querySelector(".taleem-browser-bg");
675
638
  const slideEl = root.querySelector(".taleem-browser-slide");
676
639
  applyBackground(bgEl, deck.background);
677
- const manager = slideBuilder(deck);
678
- function render() {
679
- slideEl.innerHTML = manager.renderSlide(currentIndex);
680
- }
681
- function next() {
682
- if (currentIndex < total - 1) {
683
- currentIndex++;
684
- render();
640
+ const slides = deck.deck.map((slideJSON, i) => {
641
+ if (!slideJSON.type) {
642
+ throw new Error(`taleem-browser: slide ${i} missing type`);
685
643
  }
686
- }
687
- function prev() {
688
- if (currentIndex > 0) {
689
- currentIndex--;
690
- render();
644
+ const Template = getSlideTemplate(slideJSON.type);
645
+ if (!Template) {
646
+ throw new Error(`taleem-browser: unknown slide type "${slideJSON.type}"`);
691
647
  }
692
- }
693
- function goTo(index) {
648
+ return Template.fromJSON(slideJSON);
649
+ });
650
+ const total = slides.length;
651
+ function render(index, renderState = {}) {
694
652
  if (index < 0 || index >= total) return;
695
- currentIndex = index;
696
- render();
653
+ const slide = slides[index];
654
+ slideEl.innerHTML = slide.render(renderState);
697
655
  }
698
- function getIndex() {
699
- return currentIndex;
700
- }
701
- function getTotal() {
702
- return total;
703
- }
704
- function destroy() {
705
- root.innerHTML = "";
706
- }
707
- render();
708
656
  return {
709
- next,
710
- prev,
711
- goTo,
712
- getIndex,
713
- getTotal,
714
657
  render,
715
- destroy
658
+ getTotal() {
659
+ return total;
660
+ }
716
661
  };
717
662
  }
718
663
  function applyBackground(el, bg = {}) {