waitroom 0.0.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.
Files changed (128) hide show
  1. package/README.md +62 -0
  2. package/dist/chunk-3RJ542WD.js +130 -0
  3. package/dist/chunk-3RJ542WD.js.map +1 -0
  4. package/dist/chunk-4DE2IREA.cjs +9 -0
  5. package/dist/chunk-4DE2IREA.cjs.map +1 -0
  6. package/dist/chunk-5AUPIR2C.cjs +90 -0
  7. package/dist/chunk-5AUPIR2C.cjs.map +1 -0
  8. package/dist/chunk-ARXVTVP4.js +55 -0
  9. package/dist/chunk-ARXVTVP4.js.map +1 -0
  10. package/dist/chunk-C5XPYOJI.js +137 -0
  11. package/dist/chunk-C5XPYOJI.js.map +1 -0
  12. package/dist/chunk-DEQZY4AM.js +58 -0
  13. package/dist/chunk-DEQZY4AM.js.map +1 -0
  14. package/dist/chunk-FH3QBC6T.cjs +139 -0
  15. package/dist/chunk-FH3QBC6T.cjs.map +1 -0
  16. package/dist/chunk-GEBKOXLQ.cjs +255 -0
  17. package/dist/chunk-GEBKOXLQ.cjs.map +1 -0
  18. package/dist/chunk-JG5ZMB2Y.cjs +142 -0
  19. package/dist/chunk-JG5ZMB2Y.cjs.map +1 -0
  20. package/dist/chunk-MAWVAR3Q.cjs +135 -0
  21. package/dist/chunk-MAWVAR3Q.cjs.map +1 -0
  22. package/dist/chunk-MMNQMDV3.js +39 -0
  23. package/dist/chunk-MMNQMDV3.js.map +1 -0
  24. package/dist/chunk-O6CAFCTV.js +140 -0
  25. package/dist/chunk-O6CAFCTV.js.map +1 -0
  26. package/dist/chunk-P6NO27XB.cjs +74 -0
  27. package/dist/chunk-P6NO27XB.cjs.map +1 -0
  28. package/dist/chunk-PKRYY3X6.cjs +60 -0
  29. package/dist/chunk-PKRYY3X6.cjs.map +1 -0
  30. package/dist/chunk-PUR7CO53.js +72 -0
  31. package/dist/chunk-PUR7CO53.js.map +1 -0
  32. package/dist/chunk-R5V2UBE7.js +88 -0
  33. package/dist/chunk-R5V2UBE7.js.map +1 -0
  34. package/dist/chunk-SSP4S4NY.cjs +57 -0
  35. package/dist/chunk-SSP4S4NY.cjs.map +1 -0
  36. package/dist/chunk-SUJCEDVR.js +251 -0
  37. package/dist/chunk-SUJCEDVR.js.map +1 -0
  38. package/dist/chunk-V4RO47V6.cjs +41 -0
  39. package/dist/chunk-V4RO47V6.cjs.map +1 -0
  40. package/dist/chunk-V5DABI44.cjs +172 -0
  41. package/dist/chunk-V5DABI44.cjs.map +1 -0
  42. package/dist/chunk-V6TY7KAL.js +7 -0
  43. package/dist/chunk-V6TY7KAL.js.map +1 -0
  44. package/dist/chunk-VKSLYTRF.js +170 -0
  45. package/dist/chunk-VKSLYTRF.js.map +1 -0
  46. package/dist/core/index.cjs +30 -0
  47. package/dist/core/index.cjs.map +1 -0
  48. package/dist/core/index.d.cts +23 -0
  49. package/dist/core/index.d.ts +23 -0
  50. package/dist/core/index.js +5 -0
  51. package/dist/core/index.js.map +1 -0
  52. package/dist/doodle/basic-canvas.cjs +13 -0
  53. package/dist/doodle/basic-canvas.cjs.map +1 -0
  54. package/dist/doodle/basic-canvas.d.cts +5 -0
  55. package/dist/doodle/basic-canvas.d.ts +5 -0
  56. package/dist/doodle/basic-canvas.js +4 -0
  57. package/dist/doodle/basic-canvas.js.map +1 -0
  58. package/dist/doodle/index.cjs +13 -0
  59. package/dist/doodle/index.cjs.map +1 -0
  60. package/dist/doodle/index.d.cts +2 -0
  61. package/dist/doodle/index.d.ts +2 -0
  62. package/dist/doodle/index.js +4 -0
  63. package/dist/doodle/index.js.map +1 -0
  64. package/dist/engine--hGQ4LNR.d.ts +16 -0
  65. package/dist/engine-DdHCpfbk.d.cts +16 -0
  66. package/dist/facts/dev-tips.cjs +13 -0
  67. package/dist/facts/dev-tips.cjs.map +1 -0
  68. package/dist/facts/dev-tips.d.cts +5 -0
  69. package/dist/facts/dev-tips.d.ts +5 -0
  70. package/dist/facts/dev-tips.js +4 -0
  71. package/dist/facts/dev-tips.js.map +1 -0
  72. package/dist/facts/index.cjs +23 -0
  73. package/dist/facts/index.cjs.map +1 -0
  74. package/dist/facts/index.d.cts +4 -0
  75. package/dist/facts/index.d.ts +4 -0
  76. package/dist/facts/index.js +6 -0
  77. package/dist/facts/index.js.map +1 -0
  78. package/dist/facts/programming-trivia.cjs +13 -0
  79. package/dist/facts/programming-trivia.cjs.map +1 -0
  80. package/dist/facts/programming-trivia.d.cts +5 -0
  81. package/dist/facts/programming-trivia.d.ts +5 -0
  82. package/dist/facts/programming-trivia.js +4 -0
  83. package/dist/facts/programming-trivia.js.map +1 -0
  84. package/dist/facts/tech-stats.cjs +13 -0
  85. package/dist/facts/tech-stats.cjs.map +1 -0
  86. package/dist/facts/tech-stats.d.cts +5 -0
  87. package/dist/facts/tech-stats.d.ts +5 -0
  88. package/dist/facts/tech-stats.js +4 -0
  89. package/dist/facts/tech-stats.js.map +1 -0
  90. package/dist/games/click-counter.cjs +13 -0
  91. package/dist/games/click-counter.cjs.map +1 -0
  92. package/dist/games/click-counter.d.cts +5 -0
  93. package/dist/games/click-counter.d.ts +5 -0
  94. package/dist/games/click-counter.js +4 -0
  95. package/dist/games/click-counter.js.map +1 -0
  96. package/dist/games/index.cjs +23 -0
  97. package/dist/games/index.cjs.map +1 -0
  98. package/dist/games/index.d.cts +4 -0
  99. package/dist/games/index.d.ts +4 -0
  100. package/dist/games/index.js +6 -0
  101. package/dist/games/index.js.map +1 -0
  102. package/dist/games/memory.cjs +13 -0
  103. package/dist/games/memory.cjs.map +1 -0
  104. package/dist/games/memory.d.cts +5 -0
  105. package/dist/games/memory.d.ts +5 -0
  106. package/dist/games/memory.js +4 -0
  107. package/dist/games/memory.js.map +1 -0
  108. package/dist/games/snake.cjs +13 -0
  109. package/dist/games/snake.cjs.map +1 -0
  110. package/dist/games/snake.d.cts +5 -0
  111. package/dist/games/snake.d.ts +5 -0
  112. package/dist/games/snake.js +4 -0
  113. package/dist/games/snake.js.map +1 -0
  114. package/dist/index.cjs +43 -0
  115. package/dist/index.cjs.map +1 -0
  116. package/dist/index.d.cts +5 -0
  117. package/dist/index.d.ts +5 -0
  118. package/dist/index.js +6 -0
  119. package/dist/index.js.map +1 -0
  120. package/dist/react/index.cjs +22 -0
  121. package/dist/react/index.cjs.map +1 -0
  122. package/dist/react/index.d.cts +24 -0
  123. package/dist/react/index.d.ts +24 -0
  124. package/dist/react/index.js +5 -0
  125. package/dist/react/index.js.map +1 -0
  126. package/dist/types-vBwPFyxq.d.cts +101 -0
  127. package/dist/types-vBwPFyxq.d.ts +101 -0
  128. package/package.json +64 -0
package/README.md ADDED
@@ -0,0 +1,62 @@
1
+ # waitroom
2
+
3
+ Transform dead loading time into engaging micro-interactions.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install waitroom
9
+ # or
10
+ yarn add waitroom
11
+ # or
12
+ pnpm add waitroom
13
+ ```
14
+
15
+ ## Quick Start (React)
16
+
17
+ ```tsx
18
+ import { useState } from 'react';
19
+ import { LoadingInteraction } from 'waitroom';
20
+ import { SnakeGame } from 'waitroom/games/snake';
21
+ import { DevTipsFacts } from 'waitroom/facts/dev-tips';
22
+
23
+ function App() {
24
+ const [isLoading, setIsLoading] = useState(false);
25
+
26
+ return (
27
+ <LoadingInteraction
28
+ isLoading={isLoading}
29
+ availableModes={['game', 'facts']}
30
+ game={SnakeGame}
31
+ facts={DevTipsFacts}
32
+ >
33
+ <YourContent />
34
+ </LoadingInteraction>
35
+ );
36
+ }
37
+ ```
38
+
39
+ ## Examples
40
+
41
+ ### React Demo
42
+ A comprehensive React example is available in `examples/react-demo`.
43
+
44
+ To run it:
45
+ 1. `npm run build` (in root)
46
+ 2. `cd examples/react-demo`
47
+ 3. `npm install`
48
+ 4. `npm run dev`
49
+
50
+ This demo showcases:
51
+ - All interaction modes (Game, Facts, Doodle)
52
+ - Mode switching
53
+ - Custom themes
54
+ - Full-screen expansion capability
55
+
56
+ ## Architecture
57
+ The package is designed for tree-shaking:
58
+ - `waitroom/core`: Framework-agnostic engine
59
+ - `waitroom/games/*`: Individual games
60
+ - `waitroom/facts/*`: Individual fact collections
61
+ - `waitroom/doodle/*`: Doodle plugins
62
+ - `waitroom/react`: React components only
@@ -0,0 +1,130 @@
1
+ import { __publicField } from './chunk-V6TY7KAL.js';
2
+
3
+ // src/core/state.ts
4
+ var STORAGE_KEY_PREFIX = "waitroom_";
5
+ var _StateManager = class _StateManager {
6
+ constructor() {
7
+ }
8
+ static getInstance() {
9
+ if (!_StateManager.instance) {
10
+ _StateManager.instance = new _StateManager();
11
+ }
12
+ return _StateManager.instance;
13
+ }
14
+ // --- Game State ---
15
+ getGameState(gameId) {
16
+ try {
17
+ const data = localStorage.getItem(`${STORAGE_KEY_PREFIX}game_${gameId}`);
18
+ if (data) {
19
+ return JSON.parse(data);
20
+ }
21
+ } catch (e) {
22
+ console.warn("Failed to load game state", e);
23
+ }
24
+ return null;
25
+ }
26
+ saveGameState(gameId, state) {
27
+ try {
28
+ localStorage.setItem(
29
+ `${STORAGE_KEY_PREFIX}game_${gameId}`,
30
+ JSON.stringify(state)
31
+ );
32
+ } catch (e) {
33
+ console.warn("Failed to save game state", e);
34
+ }
35
+ }
36
+ // --- Mode Preference ---
37
+ getPreferredMode() {
38
+ try {
39
+ return localStorage.getItem(
40
+ `${STORAGE_KEY_PREFIX}mode`
41
+ );
42
+ } catch (e) {
43
+ return null;
44
+ }
45
+ }
46
+ savePreferredMode(mode) {
47
+ try {
48
+ localStorage.setItem(`${STORAGE_KEY_PREFIX}mode`, mode);
49
+ } catch (e) {
50
+ console.warn("Failed to save preferred mode", e);
51
+ }
52
+ }
53
+ };
54
+ __publicField(_StateManager, "instance");
55
+ var StateManager = _StateManager;
56
+ var stateManager = StateManager.getInstance();
57
+
58
+ // src/core/engine.ts
59
+ var LoadingEngine = class {
60
+ constructor(container, config) {
61
+ __publicField(this, "config");
62
+ __publicField(this, "container");
63
+ __publicField(this, "currentInstance", null);
64
+ __publicField(this, "activeMode", "none");
65
+ this.container = container;
66
+ this.config = config;
67
+ }
68
+ init() {
69
+ let startMode = this.config.mode || "none";
70
+ if (this.config.persistModePreference) {
71
+ const saved = stateManager.getPreferredMode();
72
+ if (saved && this.config.availableModes?.includes(saved)) {
73
+ startMode = saved;
74
+ }
75
+ }
76
+ this.setMode(startMode);
77
+ }
78
+ setMode(mode) {
79
+ if (this.activeMode === mode) return;
80
+ if (this.currentInstance) {
81
+ this.currentInstance.destroy();
82
+ this.currentInstance = null;
83
+ }
84
+ this.activeMode = mode;
85
+ this.container.style.opacity = "0";
86
+ this.container.style.transition = `opacity ${this.config.transitionDuration || 300}ms ease-in-out`;
87
+ setTimeout(() => {
88
+ this.render();
89
+ this.container.style.opacity = "1";
90
+ }, (this.config.transitionDuration || 300) / 2);
91
+ if (this.config.persistModePreference && mode !== "none") {
92
+ stateManager.savePreferredMode(mode);
93
+ }
94
+ if (this.config.onModeChange) {
95
+ this.config.onModeChange(mode);
96
+ }
97
+ }
98
+ render() {
99
+ this.container.innerHTML = "";
100
+ if (this.activeMode === "none") {
101
+ return;
102
+ }
103
+ if (this.activeMode === "game" && this.config.game) {
104
+ const gamePlugin = this.config.game;
105
+ const savedState = stateManager.getGameState(gamePlugin.id) || {};
106
+ this.currentInstance = gamePlugin.renderMini(this.container, savedState);
107
+ } else if (this.activeMode === "facts" && this.config.facts) {
108
+ const factsPlugin = this.config.facts;
109
+ this.currentInstance = factsPlugin.renderMini(this.container);
110
+ } else if (this.activeMode === "doodle" && this.config.doodle) {
111
+ const doodlePlugin = this.config.doodle;
112
+ this.currentInstance = doodlePlugin.renderMini(this.container);
113
+ }
114
+ }
115
+ destroy() {
116
+ if (this.currentInstance) {
117
+ this.currentInstance.destroy();
118
+ }
119
+ this.container.innerHTML = "";
120
+ }
121
+ };
122
+ function createLoadingInteraction(container, config) {
123
+ const engine = new LoadingEngine(container, config);
124
+ engine.init();
125
+ return engine;
126
+ }
127
+
128
+ export { LoadingEngine, StateManager, createLoadingInteraction, stateManager };
129
+ //# sourceMappingURL=chunk-3RJ542WD.js.map
130
+ //# sourceMappingURL=chunk-3RJ542WD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/state.ts","../src/core/engine.ts"],"names":[],"mappings":";;;AAEA,IAAM,kBAAA,GAAqB,WAAA;AAEpB,IAAM,aAAA,GAAN,MAAM,aAAA,CAAa;AAAA,EAGhB,WAAA,GAAc;AAAA,EAAC;AAAA,EAEvB,OAAO,WAAA,GAA4B;AACjC,IAAA,IAAI,CAAC,cAAa,QAAA,EAAU;AAC1B,MAAA,aAAA,CAAa,QAAA,GAAW,IAAI,aAAA,EAAa;AAAA,IAC3C;AACA,IAAA,OAAO,aAAA,CAAa,QAAA;AAAA,EACtB;AAAA;AAAA,EAIA,aAAa,MAAA,EAA2C;AACtD,IAAA,IAAI;AACF,MAAA,MAAM,OAAO,YAAA,CAAa,OAAA,CAAQ,GAAG,kBAAkB,CAAA,KAAA,EAAQ,MAAM,CAAA,CAAE,CAAA;AACvE,MAAA,IAAI,IAAA,EAAM;AACR,QAAA,OAAO,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,MACxB;AAAA,IACF,SAAS,CAAA,EAAG;AACV,MAAA,OAAA,CAAQ,IAAA,CAAK,6BAA6B,CAAC,CAAA;AAAA,IAC7C;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,aAAA,CAAc,QAAgB,KAAA,EAAiC;AAC7D,IAAA,IAAI;AAEF,MAAA,YAAA,CAAa,OAAA;AAAA,QACX,CAAA,EAAG,kBAAkB,CAAA,KAAA,EAAQ,MAAM,CAAA,CAAA;AAAA,QACnC,IAAA,CAAK,UAAU,KAAK;AAAA,OACtB;AAAA,IACF,SAAS,CAAA,EAAG;AACV,MAAA,OAAA,CAAQ,IAAA,CAAK,6BAA6B,CAAC,CAAA;AAAA,IAC7C;AAAA,EACF;AAAA;AAAA,EAIA,gBAAA,GAA2C;AACzC,IAAA,IAAI;AACF,MAAA,OAAO,YAAA,CAAa,OAAA;AAAA,QAClB,GAAG,kBAAkB,CAAA,IAAA;AAAA,OACvB;AAAA,IACF,SAAS,CAAA,EAAG;AACV,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,kBAAkB,IAAA,EAA6B;AAC7C,IAAA,IAAI;AACF,MAAA,YAAA,CAAa,OAAA,CAAQ,CAAA,EAAG,kBAAkB,CAAA,IAAA,CAAA,EAAQ,IAAI,CAAA;AAAA,IACxD,SAAS,CAAA,EAAG;AACV,MAAA,OAAA,CAAQ,IAAA,CAAK,iCAAiC,CAAC,CAAA;AAAA,IACjD;AAAA,EACF;AACF,CAAA;AAxDE,aAAA,CADW,aAAA,EACI,UAAA,CAAA;AADV,IAAM,YAAA,GAAN;AA2DA,IAAM,YAAA,GAAe,aAAa,WAAA;;;AC5DlC,IAAM,gBAAN,MAAoB;AAAA,EAMzB,WAAA,CAAY,WAAwB,MAAA,EAA2B;AAL/D,IAAA,aAAA,CAAA,IAAA,EAAQ,QAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAQ,WAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAQ,iBAAA,EAAuB,IAAA,CAAA;AAC/B,IAAA,aAAA,CAAA,IAAA,EAAQ,YAAA,EAA8B,MAAA,CAAA;AAGpC,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AAAA,EAEA,IAAA,GAAO;AAEL,IAAA,IAAI,SAAA,GAAY,IAAA,CAAK,MAAA,CAAO,IAAA,IAAQ,MAAA;AAEpC,IAAA,IAAI,IAAA,CAAK,OAAO,qBAAA,EAAuB;AACrC,MAAA,MAAM,KAAA,GAAQ,aAAa,gBAAA,EAAiB;AAC5C,MAAA,IAAI,SAAS,IAAA,CAAK,MAAA,CAAO,cAAA,EAAgB,QAAA,CAAS,KAAK,CAAA,EAAG;AACxD,QAAA,SAAA,GAAY,KAAA;AAAA,MACd;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,QAAQ,SAAS,CAAA;AAAA,EACxB;AAAA,EAEA,QAAQ,IAAA,EAAuB;AAC7B,IAAA,IAAI,IAAA,CAAK,eAAe,IAAA,EAAM;AAG9B,IAAA,IAAI,KAAK,eAAA,EAAiB;AACxB,MAAA,IAAA,CAAK,gBAAgB,OAAA,EAAQ;AAC7B,MAAA,IAAA,CAAK,eAAA,GAAkB,IAAA;AAAA,IACzB;AAEA,IAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAGlB,IAAA,IAAA,CAAK,SAAA,CAAU,MAAM,OAAA,GAAU,GAAA;AAC/B,IAAA,IAAA,CAAK,UAAU,KAAA,CAAM,UAAA,GAAa,WAChC,IAAA,CAAK,MAAA,CAAO,sBAAsB,GACpC,CAAA,cAAA,CAAA;AAEA,IAAA,UAAA,CAAW,MAAM;AACf,MAAA,IAAA,CAAK,MAAA,EAAO;AACZ,MAAA,IAAA,CAAK,SAAA,CAAU,MAAM,OAAA,GAAU,GAAA;AAAA,IACjC,CAAA,EAAA,CAAI,IAAA,CAAK,MAAA,CAAO,kBAAA,IAAsB,OAAO,CAAC,CAAA;AAG9C,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,qBAAA,IAAyB,IAAA,KAAS,MAAA,EAAQ;AACxD,MAAA,YAAA,CAAa,kBAAkB,IAAI,CAAA;AAAA,IACrC;AAEA,IAAA,IAAI,IAAA,CAAK,OAAO,YAAA,EAAc;AAC5B,MAAA,IAAA,CAAK,MAAA,CAAO,aAAa,IAAI,CAAA;AAAA,IAC/B;AAAA,EACF;AAAA,EAEQ,MAAA,GAAS;AACf,IAAA,IAAA,CAAK,UAAU,SAAA,GAAY,EAAA;AAE3B,IAAA,IAAI,IAAA,CAAK,eAAe,MAAA,EAAQ;AAC9B,MAAA;AAAA,IACF;AAMA,IAAA,IAAI,IAAA,CAAK,UAAA,KAAe,MAAA,IAAU,IAAA,CAAK,OAAO,IAAA,EAAM;AAClD,MAAA,MAAM,UAAA,GAAa,KAAK,MAAA,CAAO,IAAA;AAE/B,MAAA,MAAM,aAAa,YAAA,CAAa,YAAA,CAAa,UAAA,CAAW,EAAE,KAAK,EAAC;AAChE,MAAA,IAAA,CAAK,eAAA,GAAkB,UAAA,CAAW,UAAA,CAAW,IAAA,CAAK,WAAW,UAAU,CAAA;AAAA,IACzE,WAAW,IAAA,CAAK,UAAA,KAAe,OAAA,IAAW,IAAA,CAAK,OAAO,KAAA,EAAO;AAC3D,MAAA,MAAM,WAAA,GAAc,KAAK,MAAA,CAAO,KAAA;AAChC,MAAA,IAAA,CAAK,eAAA,GAAkB,WAAA,CAAY,UAAA,CAAW,IAAA,CAAK,SAAS,CAAA;AAAA,IAC9D,WAAW,IAAA,CAAK,UAAA,KAAe,QAAA,IAAY,IAAA,CAAK,OAAO,MAAA,EAAQ;AAC7D,MAAA,MAAM,YAAA,GAAe,KAAK,MAAA,CAAO,MAAA;AACjC,MAAA,IAAA,CAAK,eAAA,GAAkB,YAAA,CAAa,UAAA,CAAW,IAAA,CAAK,SAAS,CAAA;AAAA,IAC/D;AAAA,EACF;AAAA,EAEA,OAAA,GAAU;AACR,IAAA,IAAI,KAAK,eAAA,EAAiB;AACxB,MAAA,IAAA,CAAK,gBAAgB,OAAA,EAAQ;AAAA,IAC/B;AACA,IAAA,IAAA,CAAK,UAAU,SAAA,GAAY,EAAA;AAAA,EAC7B;AACF;AAEO,SAAS,wBAAA,CACd,WACA,MAAA,EACA;AACA,EAAA,MAAM,MAAA,GAAS,IAAI,aAAA,CAAc,SAAA,EAAW,MAAM,CAAA;AAClD,EAAA,MAAA,CAAO,IAAA,EAAK;AACZ,EAAA,OAAO,MAAA;AACT","file":"chunk-3RJ542WD.js","sourcesContent":["import { GameState, InteractionMode } from \"./types\";\n\nconst STORAGE_KEY_PREFIX = \"waitroom_\";\n\nexport class StateManager {\n private static instance: StateManager;\n\n private constructor() {}\n\n static getInstance(): StateManager {\n if (!StateManager.instance) {\n StateManager.instance = new StateManager();\n }\n return StateManager.instance;\n }\n\n // --- Game State ---\n\n getGameState(gameId: string): Partial<GameState> | null {\n try {\n const data = localStorage.getItem(`${STORAGE_KEY_PREFIX}game_${gameId}`);\n if (data) {\n return JSON.parse(data);\n }\n } catch (e) {\n console.warn(\"Failed to load game state\", e);\n }\n return null;\n }\n\n saveGameState(gameId: string, state: Partial<GameState>): void {\n try {\n // Simple debounce could be added here if needed, but for now direct write\n localStorage.setItem(\n `${STORAGE_KEY_PREFIX}game_${gameId}`,\n JSON.stringify(state)\n );\n } catch (e) {\n console.warn(\"Failed to save game state\", e);\n }\n }\n\n // --- Mode Preference ---\n\n getPreferredMode(): InteractionMode | null {\n try {\n return localStorage.getItem(\n `${STORAGE_KEY_PREFIX}mode`\n ) as InteractionMode;\n } catch (e) {\n return null;\n }\n }\n\n savePreferredMode(mode: InteractionMode): void {\n try {\n localStorage.setItem(`${STORAGE_KEY_PREFIX}mode`, mode);\n } catch (e) {\n console.warn(\"Failed to save preferred mode\", e);\n }\n }\n}\n\nexport const stateManager = StateManager.getInstance();\n","import { InteractionConfig, InteractionMode } from \"./types\";\nimport { stateManager } from \"./state\";\n\nexport class LoadingEngine {\n private config: InteractionConfig;\n private container: HTMLElement;\n private currentInstance: any = null;\n private activeMode: InteractionMode = \"none\";\n\n constructor(container: HTMLElement, config: InteractionConfig) {\n this.container = container;\n this.config = config;\n }\n\n init() {\n // Determine start mode\n let startMode = this.config.mode || \"none\";\n\n if (this.config.persistModePreference) {\n const saved = stateManager.getPreferredMode();\n if (saved && this.config.availableModes?.includes(saved)) {\n startMode = saved;\n }\n }\n\n this.setMode(startMode);\n }\n\n setMode(mode: InteractionMode) {\n if (this.activeMode === mode) return;\n\n // Cleanup previous\n if (this.currentInstance) {\n this.currentInstance.destroy();\n this.currentInstance = null;\n }\n\n this.activeMode = mode;\n\n // Simple fade transition\n this.container.style.opacity = \"0\";\n this.container.style.transition = `opacity ${\n this.config.transitionDuration || 300\n }ms ease-in-out`;\n\n setTimeout(() => {\n this.render();\n this.container.style.opacity = \"1\";\n }, (this.config.transitionDuration || 300) / 2);\n\n // Persist preference\n if (this.config.persistModePreference && mode !== \"none\") {\n stateManager.savePreferredMode(mode);\n }\n\n if (this.config.onModeChange) {\n this.config.onModeChange(mode);\n }\n }\n\n private render() {\n this.container.innerHTML = \"\"; // Clear container\n\n if (this.activeMode === \"none\") {\n return;\n }\n\n // Normally we would have a plugin registry or pass plugins in config.\n // For this lightweight version we rely on config having the specific plugin instances.\n\n // Render based on mode\n if (this.activeMode === \"game\" && this.config.game) {\n const gamePlugin = this.config.game;\n // Load state\n const savedState = stateManager.getGameState(gamePlugin.id) || {};\n this.currentInstance = gamePlugin.renderMini(this.container, savedState);\n } else if (this.activeMode === \"facts\" && this.config.facts) {\n const factsPlugin = this.config.facts;\n this.currentInstance = factsPlugin.renderMini(this.container);\n } else if (this.activeMode === \"doodle\" && this.config.doodle) {\n const doodlePlugin = this.config.doodle;\n this.currentInstance = doodlePlugin.renderMini(this.container);\n }\n }\n\n destroy() {\n if (this.currentInstance) {\n this.currentInstance.destroy();\n }\n this.container.innerHTML = \"\";\n }\n}\n\nexport function createLoadingInteraction(\n container: HTMLElement,\n config: InteractionConfig\n) {\n const engine = new LoadingEngine(container, config);\n engine.init();\n return engine;\n}\n"]}
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+
3
+ var __defProp = Object.defineProperty;
4
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
5
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6
+
7
+ exports.__publicField = __publicField;
8
+ //# sourceMappingURL=chunk-4DE2IREA.cjs.map
9
+ //# sourceMappingURL=chunk-4DE2IREA.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-4DE2IREA.cjs"}
@@ -0,0 +1,90 @@
1
+ 'use strict';
2
+
3
+ var chunk4DE2IREA_cjs = require('./chunk-4DE2IREA.cjs');
4
+
5
+ // src/facts/dev-tips.ts
6
+ var TIPS = [
7
+ {
8
+ id: "1",
9
+ text: "Ctrl+Shift+P opens command palette in VS Code",
10
+ category: "vscode"
11
+ },
12
+ { id: "2", text: "Use git reflog to find lost commits", category: "git" },
13
+ {
14
+ id: "3",
15
+ text: "Console.table() displays data in a table format",
16
+ category: "js"
17
+ },
18
+ { id: "4", text: "Alt+Click to use multiple cursors", category: "vscode" }
19
+ ];
20
+ var SimpleFactsRenderer = class {
21
+ constructor(container, facts, config) {
22
+ chunk4DE2IREA_cjs.__publicField(this, "container");
23
+ chunk4DE2IREA_cjs.__publicField(this, "facts");
24
+ chunk4DE2IREA_cjs.__publicField(this, "currentIndex", 0);
25
+ chunk4DE2IREA_cjs.__publicField(this, "timer");
26
+ chunk4DE2IREA_cjs.__publicField(this, "config");
27
+ this.container = container;
28
+ this.facts = facts;
29
+ this.config = config || {};
30
+ this.container.style.display = "flex";
31
+ this.container.style.flexDirection = "column";
32
+ this.container.style.alignItems = "center";
33
+ this.container.style.justifyContent = "center";
34
+ this.container.style.padding = "20px";
35
+ this.container.style.textAlign = "center";
36
+ this.showCurrent();
37
+ this.startRotation();
38
+ }
39
+ showCurrent() {
40
+ const fact = this.facts[this.currentIndex];
41
+ this.container.innerHTML = `
42
+ <div style="font-weight: bold; margin-bottom: 8px;">Tip #${this.currentIndex + 1}</div>
43
+ <div style="font-size: 1.1em;">${fact.text}</div>
44
+ ${fact.category ? `<div style="font-size: 0.8em; color: #888; margin-top: 5px;">${fact.category}</div>` : ""}
45
+ `;
46
+ const timerBar = document.createElement("div");
47
+ timerBar.style.width = "0%";
48
+ timerBar.style.height = "2px";
49
+ timerBar.style.background = "#22c55e";
50
+ timerBar.style.marginTop = "10px";
51
+ timerBar.style.transition = `width ${this.config.rotationInterval || 4e3}ms linear`;
52
+ void this.container.offsetWidth;
53
+ this.container.appendChild(timerBar);
54
+ requestAnimationFrame(() => {
55
+ timerBar.style.width = "100%";
56
+ });
57
+ }
58
+ startRotation() {
59
+ if (this.timer) clearInterval(this.timer);
60
+ const interval = this.config.rotationInterval || 4e3;
61
+ this.timer = setInterval(() => this.next(), interval);
62
+ }
63
+ next() {
64
+ this.currentIndex = (this.currentIndex + 1) % this.facts.length;
65
+ this.showCurrent();
66
+ }
67
+ previous() {
68
+ this.currentIndex = (this.currentIndex - 1 + this.facts.length) % this.facts.length;
69
+ this.showCurrent();
70
+ }
71
+ favorite(id) {
72
+ console.log("Fav:", id);
73
+ }
74
+ destroy() {
75
+ if (this.timer) clearInterval(this.timer);
76
+ this.container.innerHTML = "";
77
+ }
78
+ };
79
+ var DevTipsFacts = {
80
+ id: "dev-tips",
81
+ name: "Developer Tips",
82
+ category: "coding",
83
+ facts: TIPS,
84
+ renderMini: (c, cfg) => new SimpleFactsRenderer(c, TIPS, cfg),
85
+ renderFull: (c, cfg) => new SimpleFactsRenderer(c, TIPS, cfg)
86
+ };
87
+
88
+ exports.DevTipsFacts = DevTipsFacts;
89
+ //# sourceMappingURL=chunk-5AUPIR2C.cjs.map
90
+ //# sourceMappingURL=chunk-5AUPIR2C.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/facts/dev-tips.ts"],"names":["__publicField"],"mappings":"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","file":"chunk-5AUPIR2C.cjs","sourcesContent":["import { FactsPlugin, FactsInstance, Fact, FactsConfig } from \"../core/types\";\n\nconst TIPS: Fact[] = [\n {\n id: \"1\",\n text: \"Ctrl+Shift+P opens command palette in VS Code\",\n category: \"vscode\",\n },\n { id: \"2\", text: \"Use git reflog to find lost commits\", category: \"git\" },\n {\n id: \"3\",\n text: \"Console.table() displays data in a table format\",\n category: \"js\",\n },\n { id: \"4\", text: \"Alt+Click to use multiple cursors\", category: \"vscode\" },\n];\n\nclass SimpleFactsRenderer implements FactsInstance {\n private container: HTMLElement;\n private facts: Fact[];\n private currentIndex = 0;\n private timer: any;\n private config: FactsConfig;\n\n constructor(container: HTMLElement, facts: Fact[], config?: FactsConfig) {\n this.container = container;\n this.facts = facts;\n this.config = config || {};\n\n this.container.style.display = \"flex\";\n this.container.style.flexDirection = \"column\";\n this.container.style.alignItems = \"center\";\n this.container.style.justifyContent = \"center\";\n this.container.style.padding = \"20px\";\n this.container.style.textAlign = \"center\";\n\n this.showCurrent();\n this.startRotation();\n }\n\n private showCurrent() {\n const fact = this.facts[this.currentIndex];\n this.container.innerHTML = `\n <div style=\"font-weight: bold; margin-bottom: 8px;\">Tip #${\n this.currentIndex + 1\n }</div>\n <div style=\"font-size: 1.1em;\">${fact.text}</div>\n ${\n fact.category\n ? `<div style=\"font-size: 0.8em; color: #888; margin-top: 5px;\">${fact.category}</div>`\n : \"\"\n }\n `;\n\n // Add timer bar\n const timerBar = document.createElement(\"div\");\n timerBar.style.width = \"0%\";\n timerBar.style.height = \"2px\";\n timerBar.style.background = \"#22c55e\"; // Green progress\n timerBar.style.marginTop = \"10px\";\n timerBar.style.transition = `width ${\n this.config.rotationInterval || 4000\n }ms linear`;\n\n // Reset animation\n // Force reflow\n void this.container.offsetWidth;\n\n this.container.appendChild(timerBar);\n\n // Trigger animation\n requestAnimationFrame(() => {\n timerBar.style.width = \"100%\";\n });\n }\n\n private startRotation() {\n if (this.timer) clearInterval(this.timer);\n const interval = this.config.rotationInterval || 4000;\n this.timer = setInterval(() => this.next(), interval);\n }\n\n next() {\n this.currentIndex = (this.currentIndex + 1) % this.facts.length;\n this.showCurrent();\n }\n\n previous() {\n this.currentIndex =\n (this.currentIndex - 1 + this.facts.length) % this.facts.length;\n this.showCurrent();\n }\n\n favorite(id: string) {\n console.log(\"Fav:\", id);\n }\n\n destroy() {\n if (this.timer) clearInterval(this.timer);\n this.container.innerHTML = \"\";\n }\n}\n\nexport const DevTipsFacts: FactsPlugin = {\n id: \"dev-tips\",\n name: \"Developer Tips\",\n category: \"coding\",\n facts: TIPS,\n renderMini: (c, cfg) => new SimpleFactsRenderer(c, TIPS, cfg),\n renderFull: (c, cfg) => new SimpleFactsRenderer(c, TIPS, cfg),\n};\n"]}
@@ -0,0 +1,55 @@
1
+ import { __publicField } from './chunk-V6TY7KAL.js';
2
+
3
+ // src/core/portal.ts
4
+ var PortalSystem = class {
5
+ constructor() {
6
+ __publicField(this, "overlay", null);
7
+ }
8
+ open(contentRenderer, onClose) {
9
+ if (this.overlay) return;
10
+ this.overlay = document.createElement("div");
11
+ this.overlay.style.position = "fixed";
12
+ this.overlay.style.top = "0";
13
+ this.overlay.style.left = "0";
14
+ this.overlay.style.width = "100vw";
15
+ this.overlay.style.height = "100vh";
16
+ this.overlay.style.backgroundColor = "rgba(0,0,0,0.85)";
17
+ this.overlay.style.zIndex = "9999";
18
+ this.overlay.style.display = "flex";
19
+ this.overlay.style.justifyContent = "center";
20
+ this.overlay.style.alignItems = "center";
21
+ this.overlay.style.color = "white";
22
+ const contentContainer = document.createElement("div");
23
+ contentContainer.style.width = "80%";
24
+ contentContainer.style.height = "80%";
25
+ contentContainer.style.position = "relative";
26
+ const closeBtn = document.createElement("button");
27
+ closeBtn.innerText = "\xD7";
28
+ closeBtn.style.position = "absolute";
29
+ closeBtn.style.top = "-40px";
30
+ closeBtn.style.right = "0";
31
+ closeBtn.style.fontSize = "30px";
32
+ closeBtn.style.background = "transparent";
33
+ closeBtn.style.border = "none";
34
+ closeBtn.style.color = "white";
35
+ closeBtn.style.cursor = "pointer";
36
+ closeBtn.onclick = () => {
37
+ this.close();
38
+ onClose();
39
+ };
40
+ this.overlay.appendChild(closeBtn);
41
+ this.overlay.appendChild(contentContainer);
42
+ document.body.appendChild(this.overlay);
43
+ contentRenderer(contentContainer);
44
+ }
45
+ close() {
46
+ if (this.overlay) {
47
+ document.body.removeChild(this.overlay);
48
+ this.overlay = null;
49
+ }
50
+ }
51
+ };
52
+
53
+ export { PortalSystem };
54
+ //# sourceMappingURL=chunk-ARXVTVP4.js.map
55
+ //# sourceMappingURL=chunk-ARXVTVP4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/portal.ts"],"names":[],"mappings":";;;AAIO,IAAM,eAAN,MAAmB;AAAA,EAGxB,WAAA,GAAc;AAFd,IAAA,aAAA,CAAA,IAAA,EAAQ,SAAA,EAA8B,IAAA,CAAA;AAAA,EAEvB;AAAA,EAEf,IAAA,CAAK,iBAAmD,OAAA,EAAqB;AAC3E,IAAA,IAAI,KAAK,OAAA,EAAS;AAElB,IAAA,IAAA,CAAK,OAAA,GAAU,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA;AAC3C,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,QAAA,GAAW,OAAA;AAC9B,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,GAAA,GAAM,GAAA;AACzB,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,IAAA,GAAO,GAAA;AAC1B,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,KAAA,GAAQ,OAAA;AAC3B,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,MAAA,GAAS,OAAA;AAC5B,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,eAAA,GAAkB,kBAAA;AACrC,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,MAAA,GAAS,MAAA;AAC5B,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,OAAA,GAAU,MAAA;AAC7B,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,cAAA,GAAiB,QAAA;AACpC,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,UAAA,GAAa,QAAA;AAChC,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,KAAA,GAAQ,OAAA;AAE3B,IAAA,MAAM,gBAAA,GAAmB,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA;AACrD,IAAA,gBAAA,CAAiB,MAAM,KAAA,GAAQ,KAAA;AAC/B,IAAA,gBAAA,CAAiB,MAAM,MAAA,GAAS,KAAA;AAChC,IAAA,gBAAA,CAAiB,MAAM,QAAA,GAAW,UAAA;AAGlC,IAAA,MAAM,QAAA,GAAW,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAChD,IAAA,QAAA,CAAS,SAAA,GAAY,MAAA;AACrB,IAAA,QAAA,CAAS,MAAM,QAAA,GAAW,UAAA;AAC1B,IAAA,QAAA,CAAS,MAAM,GAAA,GAAM,OAAA;AACrB,IAAA,QAAA,CAAS,MAAM,KAAA,GAAQ,GAAA;AACvB,IAAA,QAAA,CAAS,MAAM,QAAA,GAAW,MAAA;AAC1B,IAAA,QAAA,CAAS,MAAM,UAAA,GAAa,aAAA;AAC5B,IAAA,QAAA,CAAS,MAAM,MAAA,GAAS,MAAA;AACxB,IAAA,QAAA,CAAS,MAAM,KAAA,GAAQ,OAAA;AACvB,IAAA,QAAA,CAAS,MAAM,MAAA,GAAS,SAAA;AAExB,IAAA,QAAA,CAAS,UAAU,MAAM;AACvB,MAAA,IAAA,CAAK,KAAA,EAAM;AACX,MAAA,OAAA,EAAQ;AAAA,IACV,CAAA;AAEA,IAAA,IAAA,CAAK,OAAA,CAAQ,YAAY,QAAQ,CAAA;AACjC,IAAA,IAAA,CAAK,OAAA,CAAQ,YAAY,gBAAgB,CAAA;AACzC,IAAA,QAAA,CAAS,IAAA,CAAK,WAAA,CAAY,IAAA,CAAK,OAAO,CAAA;AAGtC,IAAA,eAAA,CAAgB,gBAAgB,CAAA;AAAA,EAClC;AAAA,EAEA,KAAA,GAAQ;AACN,IAAA,IAAI,KAAK,OAAA,EAAS;AAChB,MAAA,QAAA,CAAS,IAAA,CAAK,WAAA,CAAY,IAAA,CAAK,OAAO,CAAA;AACtC,MAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AAAA,IACjB;AAAA,EACF;AACF","file":"chunk-ARXVTVP4.js","sourcesContent":["// Minimal Portal helper logic\n// In a framework-agnostic way, this would manage creating a fixed overlay\n// and transferring the state/rendering to it.\n\nexport class PortalSystem {\n private overlay: HTMLElement | null = null;\n\n constructor() {}\n\n open(contentRenderer: (container: HTMLElement) => void, onClose: () => void) {\n if (this.overlay) return;\n\n this.overlay = document.createElement(\"div\");\n this.overlay.style.position = \"fixed\";\n this.overlay.style.top = \"0\";\n this.overlay.style.left = \"0\";\n this.overlay.style.width = \"100vw\";\n this.overlay.style.height = \"100vh\";\n this.overlay.style.backgroundColor = \"rgba(0,0,0,0.85)\";\n this.overlay.style.zIndex = \"9999\";\n this.overlay.style.display = \"flex\";\n this.overlay.style.justifyContent = \"center\";\n this.overlay.style.alignItems = \"center\";\n this.overlay.style.color = \"white\";\n\n const contentContainer = document.createElement(\"div\");\n contentContainer.style.width = \"80%\";\n contentContainer.style.height = \"80%\";\n contentContainer.style.position = \"relative\";\n\n // Close button\n const closeBtn = document.createElement(\"button\");\n closeBtn.innerText = \"×\";\n closeBtn.style.position = \"absolute\";\n closeBtn.style.top = \"-40px\";\n closeBtn.style.right = \"0\";\n closeBtn.style.fontSize = \"30px\";\n closeBtn.style.background = \"transparent\";\n closeBtn.style.border = \"none\";\n closeBtn.style.color = \"white\";\n closeBtn.style.cursor = \"pointer\";\n\n closeBtn.onclick = () => {\n this.close();\n onClose();\n };\n\n this.overlay.appendChild(closeBtn);\n this.overlay.appendChild(contentContainer);\n document.body.appendChild(this.overlay);\n\n // Render content\n contentRenderer(contentContainer);\n }\n\n close() {\n if (this.overlay) {\n document.body.removeChild(this.overlay);\n this.overlay = null;\n }\n }\n}\n"]}
@@ -0,0 +1,137 @@
1
+ import { __publicField } from './chunk-V6TY7KAL.js';
2
+
3
+ // src/games/memory.ts
4
+ var MemoryInstance = class {
5
+ // 6 pairs for 3x4 grid
6
+ constructor(container, state) {
7
+ __publicField(this, "container");
8
+ __publicField(this, "state");
9
+ __publicField(this, "cards", []);
10
+ __publicField(this, "flippedCards", []);
11
+ __publicField(this, "grid");
12
+ __publicField(this, "messageDisplay");
13
+ __publicField(this, "isLocked", false);
14
+ __publicField(this, "emojis", ["\u{1F436}", "\u{1F431}", "\u{1F42D}", "\u{1F439}", "\u{1F430}", "\u{1F98A}"]);
15
+ this.container = container;
16
+ this.state = state;
17
+ this.container.style.display = "flex";
18
+ this.container.style.flexDirection = "column";
19
+ this.container.style.alignItems = "center";
20
+ this.container.style.justifyContent = "center";
21
+ this.container.style.fontFamily = "sans-serif";
22
+ const title = document.createElement("h3");
23
+ title.innerText = "Memory Match";
24
+ title.style.margin = "0 0 5px 0";
25
+ this.container.appendChild(title);
26
+ const helper = document.createElement("div");
27
+ helper.innerText = "Find matching pairs";
28
+ helper.style.fontSize = "0.8em";
29
+ helper.style.color = "#888";
30
+ helper.style.marginBottom = "10px";
31
+ this.container.appendChild(helper);
32
+ this.messageDisplay = document.createElement("div");
33
+ this.messageDisplay.style.height = "20px";
34
+ this.messageDisplay.style.fontSize = "14px";
35
+ this.messageDisplay.style.fontWeight = "bold";
36
+ this.messageDisplay.style.marginBottom = "5px";
37
+ this.container.appendChild(this.messageDisplay);
38
+ this.grid = document.createElement("div");
39
+ this.grid.style.display = "grid";
40
+ this.grid.style.gridTemplateColumns = "repeat(4, 1fr)";
41
+ this.grid.style.gap = "8px";
42
+ this.container.appendChild(this.grid);
43
+ this.initGame();
44
+ }
45
+ initGame() {
46
+ const deck = [...this.emojis, ...this.emojis].sort(() => Math.random() - 0.5).map((emoji, index) => ({
47
+ id: index,
48
+ value: emoji,
49
+ isFlipped: false,
50
+ isMatched: false
51
+ }));
52
+ this.cards = deck;
53
+ this.renderGrid();
54
+ }
55
+ renderGrid() {
56
+ this.grid.innerHTML = "";
57
+ this.cards.forEach((card) => {
58
+ const cardEl = document.createElement("div");
59
+ cardEl.style.width = "50px";
60
+ cardEl.style.height = "50px";
61
+ cardEl.style.background = card.isFlipped || card.isMatched ? "#fff" : "#22c55e";
62
+ cardEl.style.border = "1px solid #ccc";
63
+ cardEl.style.borderRadius = "8px";
64
+ cardEl.style.display = "flex";
65
+ cardEl.style.alignItems = "center";
66
+ cardEl.style.justifyContent = "center";
67
+ cardEl.style.fontSize = "24px";
68
+ cardEl.style.cursor = "pointer";
69
+ cardEl.style.transition = "transform 0.2s, background 0.2s";
70
+ if (card.isFlipped || card.isMatched) {
71
+ cardEl.innerText = card.value;
72
+ cardEl.style.transform = "rotateY(0deg)";
73
+ } else {
74
+ cardEl.innerText = "";
75
+ cardEl.style.transform = "rotateY(180deg)";
76
+ }
77
+ cardEl.onclick = () => this.handleCardClick(card);
78
+ this.grid.appendChild(cardEl);
79
+ });
80
+ }
81
+ handleCardClick(card) {
82
+ if (this.isLocked || card.isFlipped || card.isMatched) return;
83
+ card.isFlipped = true;
84
+ this.flippedCards.push(card);
85
+ this.renderGrid();
86
+ if (this.flippedCards.length === 2) {
87
+ this.isLocked = true;
88
+ this.checkMatch();
89
+ }
90
+ }
91
+ checkMatch() {
92
+ const [card1, card2] = this.flippedCards;
93
+ if (card1.value === card2.value) {
94
+ card1.isMatched = true;
95
+ card2.isMatched = true;
96
+ this.flippedCards = [];
97
+ this.isLocked = false;
98
+ this.renderGrid();
99
+ this.checkWin();
100
+ } else {
101
+ setTimeout(() => {
102
+ card1.isFlipped = false;
103
+ card2.isFlipped = false;
104
+ this.flippedCards = [];
105
+ this.isLocked = false;
106
+ this.renderGrid();
107
+ }, 1e3);
108
+ }
109
+ }
110
+ checkWin() {
111
+ if (this.cards.every((c) => c.isMatched)) {
112
+ this.messageDisplay.innerText = "You Won! \u{1F389}";
113
+ this.messageDisplay.style.color = "green";
114
+ setTimeout(() => this.initGame(), 3e3);
115
+ }
116
+ }
117
+ getState() {
118
+ return this.state;
119
+ }
120
+ setState(s) {
121
+ this.state = { ...this.state, ...s };
122
+ }
123
+ destroy() {
124
+ this.container.innerHTML = "";
125
+ }
126
+ };
127
+ var MemoryGame = {
128
+ id: "memory",
129
+ name: "Memory Match",
130
+ description: "Find matching pairs",
131
+ renderMini: (c, s) => new MemoryInstance(c, s),
132
+ renderFull: (c, s) => new MemoryInstance(c, s)
133
+ };
134
+
135
+ export { MemoryGame };
136
+ //# sourceMappingURL=chunk-C5XPYOJI.js.map
137
+ //# sourceMappingURL=chunk-C5XPYOJI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/games/memory.ts"],"names":[],"mappings":"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","file":"chunk-C5XPYOJI.js","sourcesContent":["import { GamePlugin, GameInstance, GameState } from \"../core/types\";\n\n// Memory Game Logic\ninterface Card {\n id: number;\n value: string;\n isFlipped: boolean;\n isMatched: boolean;\n}\n\nclass MemoryInstance implements GameInstance {\n private container: HTMLElement;\n private state: Partial<GameState>;\n private cards: Card[] = [];\n private flippedCards: Card[] = [];\n private grid: HTMLElement;\n private messageDisplay: HTMLElement;\n private isLocked = false;\n\n private emojis = [\"🐶\", \"🐱\", \"🐭\", \"🐹\", \"🐰\", \"🦊\"]; // 6 pairs for 3x4 grid\n\n constructor(container: HTMLElement, state: Partial<GameState>) {\n this.container = container;\n this.state = state;\n\n this.container.style.display = \"flex\";\n this.container.style.flexDirection = \"column\";\n this.container.style.alignItems = \"center\";\n this.container.style.justifyContent = \"center\";\n this.container.style.fontFamily = \"sans-serif\";\n\n // Title and Helper\n const title = document.createElement(\"h3\");\n title.innerText = \"Memory Match\";\n title.style.margin = \"0 0 5px 0\";\n this.container.appendChild(title);\n\n const helper = document.createElement(\"div\");\n helper.innerText = \"Find matching pairs\";\n helper.style.fontSize = \"0.8em\";\n helper.style.color = \"#888\";\n helper.style.marginBottom = \"10px\";\n this.container.appendChild(helper);\n\n this.messageDisplay = document.createElement(\"div\");\n this.messageDisplay.style.height = \"20px\";\n this.messageDisplay.style.fontSize = \"14px\";\n this.messageDisplay.style.fontWeight = \"bold\";\n this.messageDisplay.style.marginBottom = \"5px\";\n this.container.appendChild(this.messageDisplay);\n\n this.grid = document.createElement(\"div\");\n this.grid.style.display = \"grid\";\n this.grid.style.gridTemplateColumns = \"repeat(4, 1fr)\";\n this.grid.style.gap = \"8px\";\n this.container.appendChild(this.grid);\n\n this.initGame();\n }\n\n private initGame() {\n // Create pairs\n const deck = [...this.emojis, ...this.emojis]\n .sort(() => Math.random() - 0.5)\n .map((emoji, index) => ({\n id: index,\n value: emoji,\n isFlipped: false,\n isMatched: false,\n }));\n\n this.cards = deck;\n this.renderGrid();\n }\n\n private renderGrid() {\n this.grid.innerHTML = \"\";\n this.cards.forEach((card) => {\n const cardEl = document.createElement(\"div\");\n cardEl.style.width = \"50px\";\n cardEl.style.height = \"50px\";\n cardEl.style.background =\n card.isFlipped || card.isMatched ? \"#fff\" : \"#22c55e\";\n cardEl.style.border = \"1px solid #ccc\";\n cardEl.style.borderRadius = \"8px\";\n cardEl.style.display = \"flex\";\n cardEl.style.alignItems = \"center\";\n cardEl.style.justifyContent = \"center\";\n cardEl.style.fontSize = \"24px\";\n cardEl.style.cursor = \"pointer\";\n cardEl.style.transition = \"transform 0.2s, background 0.2s\";\n\n if (card.isFlipped || card.isMatched) {\n cardEl.innerText = card.value;\n cardEl.style.transform = \"rotateY(0deg)\";\n } else {\n cardEl.innerText = \"\";\n cardEl.style.transform = \"rotateY(180deg)\";\n }\n\n cardEl.onclick = () => this.handleCardClick(card);\n this.grid.appendChild(cardEl);\n });\n }\n\n private handleCardClick(card: Card) {\n if (this.isLocked || card.isFlipped || card.isMatched) return;\n\n // Flip card\n card.isFlipped = true;\n this.flippedCards.push(card);\n this.renderGrid();\n\n // Check match\n if (this.flippedCards.length === 2) {\n this.isLocked = true;\n this.checkMatch();\n }\n }\n\n private checkMatch() {\n const [card1, card2] = this.flippedCards;\n\n if (card1.value === card2.value) {\n // Match!\n card1.isMatched = true;\n card2.isMatched = true;\n this.flippedCards = [];\n this.isLocked = false;\n this.renderGrid();\n this.checkWin();\n } else {\n // No match\n setTimeout(() => {\n card1.isFlipped = false;\n card2.isFlipped = false;\n this.flippedCards = [];\n this.isLocked = false;\n this.renderGrid();\n }, 1000);\n }\n }\n\n private checkWin() {\n if (this.cards.every((c) => c.isMatched)) {\n this.messageDisplay.innerText = \"You Won! 🎉\";\n this.messageDisplay.style.color = \"green\";\n setTimeout(() => this.initGame(), 3000); // Restart\n }\n }\n\n getState() {\n return this.state as GameState;\n }\n setState(s: Partial<GameState>) {\n this.state = { ...this.state, ...s };\n }\n destroy() {\n this.container.innerHTML = \"\";\n }\n}\n\nexport const MemoryGame: GamePlugin = {\n id: \"memory\",\n name: \"Memory Match\",\n description: \"Find matching pairs\",\n renderMini: (c, s) => new MemoryInstance(c, s),\n renderFull: (c, s) => new MemoryInstance(c, s),\n};\n"]}
@@ -0,0 +1,58 @@
1
+ import { __publicField } from './chunk-V6TY7KAL.js';
2
+
3
+ // src/facts/programming-trivia.ts
4
+ var TRIVIA = [
5
+ {
6
+ id: "1",
7
+ text: "The first computer bug was an actual moth found in a relay",
8
+ category: "history"
9
+ },
10
+ {
11
+ id: "2",
12
+ text: "JavaScript was created in 10 days by Brendan Eich",
13
+ category: "history"
14
+ },
15
+ {
16
+ id: "3",
17
+ text: "Python is named after Monty Python, not the snake",
18
+ category: "history"
19
+ }
20
+ ];
21
+ var TriviaRenderer = class {
22
+ constructor(container, facts) {
23
+ __publicField(this, "container");
24
+ __publicField(this, "facts");
25
+ __publicField(this, "currentIndex", 0);
26
+ this.container = container;
27
+ this.facts = facts;
28
+ this.show();
29
+ }
30
+ show() {
31
+ this.container.innerText = this.facts[this.currentIndex].text;
32
+ this.container.style.textAlign = "center";
33
+ this.container.style.padding = "10px";
34
+ }
35
+ next() {
36
+ this.currentIndex = (this.currentIndex + 1) % this.facts.length;
37
+ this.show();
38
+ }
39
+ previous() {
40
+ }
41
+ favorite() {
42
+ }
43
+ destroy() {
44
+ this.container.innerHTML = "";
45
+ }
46
+ };
47
+ var ProgrammingTrivia = {
48
+ id: "prog-trivia",
49
+ name: "Programming Trivia",
50
+ category: "trivia",
51
+ facts: TRIVIA,
52
+ renderMini: (c) => new TriviaRenderer(c, TRIVIA),
53
+ renderFull: (c) => new TriviaRenderer(c, TRIVIA)
54
+ };
55
+
56
+ export { ProgrammingTrivia };
57
+ //# sourceMappingURL=chunk-DEQZY4AM.js.map
58
+ //# sourceMappingURL=chunk-DEQZY4AM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/facts/programming-trivia.ts"],"names":[],"mappings":";;;AAEA,IAAM,MAAA,GAAiB;AAAA,EACrB;AAAA,IACE,EAAA,EAAI,GAAA;AAAA,IACJ,IAAA,EAAM,4DAAA;AAAA,IACN,QAAA,EAAU;AAAA,GACZ;AAAA,EACA;AAAA,IACE,EAAA,EAAI,GAAA;AAAA,IACJ,IAAA,EAAM,mDAAA;AAAA,IACN,QAAA,EAAU;AAAA,GACZ;AAAA,EACA;AAAA,IACE,EAAA,EAAI,GAAA;AAAA,IACJ,IAAA,EAAM,mDAAA;AAAA,IACN,QAAA,EAAU;AAAA;AAEd,CAAA;AAEA,IAAM,iBAAN,MAA8C;AAAA,EAK5C,WAAA,CAAY,WAAwB,KAAA,EAAe;AAJnD,IAAA,aAAA,CAAA,IAAA,EAAQ,WAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAQ,OAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAQ,cAAA,EAAe,CAAA,CAAA;AAGrB,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,IAAA,IAAA,CAAK,IAAA,EAAK;AAAA,EACZ;AAAA,EAEA,IAAA,GAAO;AACL,IAAA,IAAA,CAAK,UAAU,SAAA,GAAY,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,YAAY,CAAA,CAAE,IAAA;AACzD,IAAA,IAAA,CAAK,SAAA,CAAU,MAAM,SAAA,GAAY,QAAA;AACjC,IAAA,IAAA,CAAK,SAAA,CAAU,MAAM,OAAA,GAAU,MAAA;AAAA,EACjC;AAAA,EAEA,IAAA,GAAO;AACL,IAAA,IAAA,CAAK,YAAA,GAAA,CAAgB,IAAA,CAAK,YAAA,GAAe,CAAA,IAAK,KAAK,KAAA,CAAM,MAAA;AACzD,IAAA,IAAA,CAAK,IAAA,EAAK;AAAA,EACZ;AAAA,EAEA,QAAA,GAAW;AAAA,EAAC;AAAA,EACZ,QAAA,GAAW;AAAA,EAAC;AAAA,EACZ,OAAA,GAAU;AACR,IAAA,IAAA,CAAK,UAAU,SAAA,GAAY,EAAA;AAAA,EAC7B;AACF,CAAA;AAEO,IAAM,iBAAA,GAAiC;AAAA,EAC5C,EAAA,EAAI,aAAA;AAAA,EACJ,IAAA,EAAM,oBAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,KAAA,EAAO,MAAA;AAAA,EACP,YAAY,CAAC,CAAA,KAAM,IAAI,cAAA,CAAe,GAAG,MAAM,CAAA;AAAA,EAC/C,YAAY,CAAC,CAAA,KAAM,IAAI,cAAA,CAAe,GAAG,MAAM;AACjD","file":"chunk-DEQZY4AM.js","sourcesContent":["import { FactsPlugin, FactsInstance, Fact } from \"../core/types\";\n\nconst TRIVIA: Fact[] = [\n {\n id: \"1\",\n text: \"The first computer bug was an actual moth found in a relay\",\n category: \"history\",\n },\n {\n id: \"2\",\n text: \"JavaScript was created in 10 days by Brendan Eich\",\n category: \"history\",\n },\n {\n id: \"3\",\n text: \"Python is named after Monty Python, not the snake\",\n category: \"history\",\n },\n];\n\nclass TriviaRenderer implements FactsInstance {\n private container: HTMLElement;\n private facts: Fact[];\n private currentIndex = 0;\n\n constructor(container: HTMLElement, facts: Fact[]) {\n this.container = container;\n this.facts = facts;\n this.show();\n }\n\n show() {\n this.container.innerText = this.facts[this.currentIndex].text;\n this.container.style.textAlign = \"center\";\n this.container.style.padding = \"10px\";\n }\n\n next() {\n this.currentIndex = (this.currentIndex + 1) % this.facts.length;\n this.show();\n }\n\n previous() {}\n favorite() {}\n destroy() {\n this.container.innerHTML = \"\";\n }\n}\n\nexport const ProgrammingTrivia: FactsPlugin = {\n id: \"prog-trivia\",\n name: \"Programming Trivia\",\n category: \"trivia\",\n facts: TRIVIA,\n renderMini: (c) => new TriviaRenderer(c, TRIVIA),\n renderFull: (c) => new TriviaRenderer(c, TRIVIA),\n};\n"]}