@prabhask5/stellar-engine 1.1.7 → 1.1.9

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 (191) hide show
  1. package/README.md +12 -18
  2. package/dist/actions/remoteChange.d.ts +143 -18
  3. package/dist/actions/remoteChange.d.ts.map +1 -1
  4. package/dist/actions/remoteChange.js +182 -58
  5. package/dist/actions/remoteChange.js.map +1 -1
  6. package/dist/actions/truncateTooltip.d.ts +26 -12
  7. package/dist/actions/truncateTooltip.d.ts.map +1 -1
  8. package/dist/actions/truncateTooltip.js +89 -34
  9. package/dist/actions/truncateTooltip.js.map +1 -1
  10. package/dist/auth/crypto.d.ts +35 -8
  11. package/dist/auth/crypto.d.ts.map +1 -1
  12. package/dist/auth/crypto.js +38 -10
  13. package/dist/auth/crypto.js.map +1 -1
  14. package/dist/auth/deviceVerification.d.ts +236 -20
  15. package/dist/auth/deviceVerification.d.ts.map +1 -1
  16. package/dist/auth/deviceVerification.js +293 -40
  17. package/dist/auth/deviceVerification.js.map +1 -1
  18. package/dist/auth/displayUtils.d.ts +98 -0
  19. package/dist/auth/displayUtils.d.ts.map +1 -0
  20. package/dist/auth/displayUtils.js +133 -0
  21. package/dist/auth/displayUtils.js.map +1 -0
  22. package/dist/auth/loginGuard.d.ts +103 -16
  23. package/dist/auth/loginGuard.d.ts.map +1 -1
  24. package/dist/auth/loginGuard.js +163 -76
  25. package/dist/auth/loginGuard.js.map +1 -1
  26. package/dist/auth/offlineCredentials.d.ts +88 -24
  27. package/dist/auth/offlineCredentials.d.ts.map +1 -1
  28. package/dist/auth/offlineCredentials.js +114 -73
  29. package/dist/auth/offlineCredentials.js.map +1 -1
  30. package/dist/auth/offlineSession.d.ts +83 -9
  31. package/dist/auth/offlineSession.d.ts.map +1 -1
  32. package/dist/auth/offlineSession.js +104 -13
  33. package/dist/auth/offlineSession.js.map +1 -1
  34. package/dist/auth/resolveAuthState.d.ts +67 -9
  35. package/dist/auth/resolveAuthState.d.ts.map +1 -1
  36. package/dist/auth/resolveAuthState.js +125 -71
  37. package/dist/auth/resolveAuthState.js.map +1 -1
  38. package/dist/auth/singleUser.d.ts +390 -37
  39. package/dist/auth/singleUser.d.ts.map +1 -1
  40. package/dist/auth/singleUser.js +504 -103
  41. package/dist/auth/singleUser.js.map +1 -1
  42. package/dist/bin/install-pwa.d.ts +18 -2
  43. package/dist/bin/install-pwa.d.ts.map +1 -1
  44. package/dist/bin/install-pwa.js +2624 -77
  45. package/dist/bin/install-pwa.js.map +1 -1
  46. package/dist/config.d.ts +131 -15
  47. package/dist/config.d.ts.map +1 -1
  48. package/dist/config.js +87 -9
  49. package/dist/config.js.map +1 -1
  50. package/dist/conflicts.d.ts +246 -23
  51. package/dist/conflicts.d.ts.map +1 -1
  52. package/dist/conflicts.js +495 -46
  53. package/dist/conflicts.js.map +1 -1
  54. package/dist/data.d.ts +338 -18
  55. package/dist/data.d.ts.map +1 -1
  56. package/dist/data.js +385 -34
  57. package/dist/data.js.map +1 -1
  58. package/dist/database.d.ts +72 -14
  59. package/dist/database.d.ts.map +1 -1
  60. package/dist/database.js +120 -29
  61. package/dist/database.js.map +1 -1
  62. package/dist/debug.d.ts +77 -1
  63. package/dist/debug.d.ts.map +1 -1
  64. package/dist/debug.js +88 -1
  65. package/dist/debug.js.map +1 -1
  66. package/dist/deviceId.d.ts +38 -7
  67. package/dist/deviceId.d.ts.map +1 -1
  68. package/dist/deviceId.js +68 -10
  69. package/dist/deviceId.js.map +1 -1
  70. package/dist/engine.d.ts +175 -3
  71. package/dist/engine.d.ts.map +1 -1
  72. package/dist/engine.js +756 -109
  73. package/dist/engine.js.map +1 -1
  74. package/dist/entries/actions.d.ts +13 -0
  75. package/dist/entries/actions.d.ts.map +1 -1
  76. package/dist/entries/actions.js +26 -1
  77. package/dist/entries/actions.js.map +1 -1
  78. package/dist/entries/auth.d.ts +15 -4
  79. package/dist/entries/auth.d.ts.map +1 -1
  80. package/dist/entries/auth.js +47 -4
  81. package/dist/entries/auth.js.map +1 -1
  82. package/dist/entries/config.d.ts +12 -0
  83. package/dist/entries/config.d.ts.map +1 -1
  84. package/dist/entries/config.js +18 -1
  85. package/dist/entries/config.js.map +1 -1
  86. package/dist/entries/kit.d.ts +11 -0
  87. package/dist/entries/kit.d.ts.map +1 -1
  88. package/dist/entries/kit.js +52 -2
  89. package/dist/entries/kit.js.map +1 -1
  90. package/dist/entries/stores.d.ts +11 -0
  91. package/dist/entries/stores.d.ts.map +1 -1
  92. package/dist/entries/stores.js +43 -2
  93. package/dist/entries/stores.js.map +1 -1
  94. package/dist/entries/types.d.ts +10 -1
  95. package/dist/entries/types.d.ts.map +1 -1
  96. package/dist/entries/types.js +10 -0
  97. package/dist/entries/types.js.map +1 -1
  98. package/dist/entries/utils.d.ts +6 -0
  99. package/dist/entries/utils.d.ts.map +1 -1
  100. package/dist/entries/utils.js +22 -1
  101. package/dist/entries/utils.js.map +1 -1
  102. package/dist/entries/vite.d.ts +17 -0
  103. package/dist/entries/vite.d.ts.map +1 -1
  104. package/dist/entries/vite.js +24 -1
  105. package/dist/entries/vite.js.map +1 -1
  106. package/dist/index.d.ts +32 -4
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +166 -23
  109. package/dist/index.js.map +1 -1
  110. package/dist/kit/auth.d.ts +60 -5
  111. package/dist/kit/auth.d.ts.map +1 -1
  112. package/dist/kit/auth.js +45 -4
  113. package/dist/kit/auth.js.map +1 -1
  114. package/dist/kit/confirm.d.ts +93 -12
  115. package/dist/kit/confirm.d.ts.map +1 -1
  116. package/dist/kit/confirm.js +103 -16
  117. package/dist/kit/confirm.js.map +1 -1
  118. package/dist/kit/loads.d.ts +148 -23
  119. package/dist/kit/loads.d.ts.map +1 -1
  120. package/dist/kit/loads.js +136 -28
  121. package/dist/kit/loads.js.map +1 -1
  122. package/dist/kit/server.d.ts +142 -10
  123. package/dist/kit/server.d.ts.map +1 -1
  124. package/dist/kit/server.js +158 -15
  125. package/dist/kit/server.js.map +1 -1
  126. package/dist/kit/sw.d.ts +152 -23
  127. package/dist/kit/sw.d.ts.map +1 -1
  128. package/dist/kit/sw.js +182 -26
  129. package/dist/kit/sw.js.map +1 -1
  130. package/dist/queue.d.ts +274 -0
  131. package/dist/queue.d.ts.map +1 -1
  132. package/dist/queue.js +556 -38
  133. package/dist/queue.js.map +1 -1
  134. package/dist/realtime.d.ts +241 -27
  135. package/dist/realtime.d.ts.map +1 -1
  136. package/dist/realtime.js +633 -109
  137. package/dist/realtime.js.map +1 -1
  138. package/dist/runtime/runtimeConfig.d.ts +91 -8
  139. package/dist/runtime/runtimeConfig.d.ts.map +1 -1
  140. package/dist/runtime/runtimeConfig.js +146 -19
  141. package/dist/runtime/runtimeConfig.js.map +1 -1
  142. package/dist/stores/authState.d.ts +150 -11
  143. package/dist/stores/authState.d.ts.map +1 -1
  144. package/dist/stores/authState.js +169 -17
  145. package/dist/stores/authState.js.map +1 -1
  146. package/dist/stores/network.d.ts +39 -0
  147. package/dist/stores/network.d.ts.map +1 -1
  148. package/dist/stores/network.js +169 -16
  149. package/dist/stores/network.js.map +1 -1
  150. package/dist/stores/remoteChanges.d.ts +327 -52
  151. package/dist/stores/remoteChanges.d.ts.map +1 -1
  152. package/dist/stores/remoteChanges.js +337 -75
  153. package/dist/stores/remoteChanges.js.map +1 -1
  154. package/dist/stores/sync.d.ts +130 -0
  155. package/dist/stores/sync.d.ts.map +1 -1
  156. package/dist/stores/sync.js +167 -7
  157. package/dist/stores/sync.js.map +1 -1
  158. package/dist/supabase/auth.d.ts +186 -46
  159. package/dist/supabase/auth.d.ts.map +1 -1
  160. package/dist/supabase/auth.js +238 -190
  161. package/dist/supabase/auth.js.map +1 -1
  162. package/dist/supabase/client.d.ts +79 -6
  163. package/dist/supabase/client.d.ts.map +1 -1
  164. package/dist/supabase/client.js +158 -15
  165. package/dist/supabase/client.js.map +1 -1
  166. package/dist/supabase/validate.d.ts +101 -7
  167. package/dist/supabase/validate.d.ts.map +1 -1
  168. package/dist/supabase/validate.js +117 -8
  169. package/dist/supabase/validate.js.map +1 -1
  170. package/dist/sw/build/vite-plugin.d.ts +55 -10
  171. package/dist/sw/build/vite-plugin.d.ts.map +1 -1
  172. package/dist/sw/build/vite-plugin.js +77 -18
  173. package/dist/sw/build/vite-plugin.js.map +1 -1
  174. package/dist/sw/sw.js +99 -44
  175. package/dist/types.d.ts +150 -26
  176. package/dist/types.d.ts.map +1 -1
  177. package/dist/types.js +12 -10
  178. package/dist/types.js.map +1 -1
  179. package/dist/utils.d.ts +55 -13
  180. package/dist/utils.d.ts.map +1 -1
  181. package/dist/utils.js +83 -22
  182. package/dist/utils.js.map +1 -1
  183. package/package.json +1 -1
  184. package/dist/auth/admin.d.ts +0 -12
  185. package/dist/auth/admin.d.ts.map +0 -1
  186. package/dist/auth/admin.js +0 -26
  187. package/dist/auth/admin.js.map +0 -1
  188. package/dist/auth/offlineLogin.d.ts +0 -34
  189. package/dist/auth/offlineLogin.d.ts.map +0 -1
  190. package/dist/auth/offlineLogin.js +0 -75
  191. package/dist/auth/offlineLogin.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"authState.d.ts","sourceRoot":"","sources":["../../src/stores/authState.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAqB,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,UAAU,SAAS;IACjB,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AA4ID,eAAO,MAAM,SAAS;;IA9HlB;;OAEG;6BACsB,OAAO,GAAG,IAAI;IAWvC;;OAEG;4BACqB,kBAAkB,GAAG,IAAI;IAWjD;;OAEG;8BACuB,MAAM,GAAG,IAAI;IAWvC;;OAEG;0BACmB,OAAO,GAAG,IAAI;IAIpC;;OAEG;0BACmB,IAAI;IAI1B;;OAEG;2BACoB,OAAO,GAAG,IAAI,GAAG,IAAI;IAkB5C;;;OAGG;+BACwB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IA8BzD;;OAEG;aACM,IAAI;CAY8B,CAAC;AAGhD,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,OAAO,CAG7C,CAAC;AAGF,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC;IACrC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,IAAI,CAeN,CAAC"}
1
+ {"version":3,"file":"authState.d.ts","sourceRoot":"","sources":["../../src/stores/authState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAqB,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAMrD;;;GAGG;AACH,UAAU,SAAS;IACjB,iDAAiD;IACjD,IAAI,EAAE,QAAQ,CAAC;IAEf,wEAAwE;IACxE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAExB,0EAA0E;IAC1E,cAAc,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAE1C,wEAAwE;IACxE,SAAS,EAAE,OAAO,CAAC;IAEnB;;;;OAIG;IACH,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AA8OD,gFAAgF;AAChF,eAAO,MAAM,SAAS;;IA3MlB;;;;;;;;;;;;;OAaG;6BACsB,OAAO,GAAG,IAAI;IAWvC;;;;;;;;;;;;;OAaG;4BACqB,kBAAkB,GAAG,IAAI;IAWjD;;;;;;;;;;;;;;;;;OAiBG;8BACuB,MAAM,GAAG,IAAI;IAWvC;;;;;;;OAOG;0BACmB,OAAO,GAAG,IAAI;IAIpC;;;;;OAKG;0BACmB,IAAI;IAI1B;;;;;;;;;;;OAWG;2BACoB,OAAO,GAAG,IAAI,GAAG,IAAI;IAkB5C;;;;;;;;;;;;;;OAcG;+BACwB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAiCzD;;;;;;OAMG;aACM,IAAI;CAiB8B,CAAC;AAMhD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,OAAO,CAG7C,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC;IACrC,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,IAAI,CAeN,CAAC"}
@@ -1,8 +1,49 @@
1
1
  /**
2
- * Auth State Store
3
- * Tracks the current authentication mode (supabase/offline/none)
2
+ * @fileoverview Authentication State Store
3
+ *
4
+ * Manages the current authentication mode and session data for the application.
5
+ * Supports three distinct authentication modes:
6
+ * - **supabase**: Online authentication via Supabase with a full session object
7
+ * - **offline**: Local/cached authentication using stored credentials
8
+ * - **none**: Unauthenticated state (login screen)
9
+ *
10
+ * **Svelte Store Pattern:**
11
+ * Uses a custom writable store created via the factory function `createAuthStateStore()`.
12
+ * The store exposes the standard `subscribe` method for reactivity, plus imperative
13
+ * mutation methods (e.g., `setSupabaseAuth`, `setOfflineAuth`) that internally call
14
+ * `update()` to ensure immutable state transitions.
15
+ *
16
+ * **Reactive Architecture:**
17
+ * Two derived stores (`isAuthenticated`, `userDisplayInfo`) project slices of the
18
+ * auth state for UI consumption, keeping components decoupled from the raw state shape.
19
+ * Components subscribe to these derived stores rather than inspecting the full auth
20
+ * state, which simplifies rendering logic and reduces unnecessary re-renders.
21
+ *
22
+ * @see {@link ../types} for AuthMode and OfflineCredentials type definitions
23
+ * @see {@link @supabase/supabase-js} for the Session type
4
24
  */
5
25
  import { writable, derived } from 'svelte/store';
26
+ // =============================================================================
27
+ // Store Factory
28
+ // =============================================================================
29
+ /**
30
+ * Creates the singleton authentication state store.
31
+ *
32
+ * The store starts in a loading state (`mode: 'none', isLoading: true`) and
33
+ * transitions to a concrete mode once the auth subsystem determines whether
34
+ * a Supabase session, offline credentials, or neither are available.
35
+ *
36
+ * @returns A Svelte-compatible store with auth-specific mutation methods
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * // In the auth initialization flow:
41
+ * authState.setSupabaseAuth(session);
42
+ *
43
+ * // On logout or session expiry:
44
+ * authState.setNoAuth('Your session has expired.');
45
+ * ```
46
+ */
6
47
  function createAuthStateStore() {
7
48
  const { subscribe, set, update } = writable({
8
49
  mode: 'none',
@@ -14,33 +55,70 @@ function createAuthStateStore() {
14
55
  return {
15
56
  subscribe,
16
57
  /**
17
- * Set auth mode to Supabase with session
58
+ * Transition to Supabase-authenticated mode.
59
+ *
60
+ * Clears any offline profile and kicked message, sets loading to false,
61
+ * and stores the provided Supabase session.
62
+ *
63
+ * @param session - The active Supabase session object from sign-in or token refresh
64
+ *
65
+ * @example
66
+ * ```ts
67
+ * const { data } = await supabase.auth.signInWithPassword({ email, password });
68
+ * if (data.session) authState.setSupabaseAuth(data.session);
69
+ * ```
18
70
  */
19
71
  setSupabaseAuth(session) {
20
72
  update((state) => ({
21
73
  ...state,
22
74
  mode: 'supabase',
23
75
  session,
24
- offlineProfile: null,
76
+ offlineProfile: null /* Clear offline data to avoid stale cross-mode references */,
25
77
  isLoading: false,
26
78
  authKickedMessage: null
27
79
  }));
28
80
  },
29
81
  /**
30
- * Set auth mode to offline with cached profile
82
+ * Transition to offline-authenticated mode.
83
+ *
84
+ * Used when the app detects valid cached credentials but no network
85
+ * connectivity for Supabase verification.
86
+ *
87
+ * @param profile - The locally-cached offline credentials
88
+ *
89
+ * @example
90
+ * ```ts
91
+ * const cached = await loadCachedCredentials();
92
+ * if (cached) authState.setOfflineAuth(cached);
93
+ * ```
31
94
  */
32
95
  setOfflineAuth(profile) {
33
96
  update((state) => ({
34
97
  ...state,
35
98
  mode: 'offline',
36
- session: null,
99
+ session: null /* Clear Supabase session since we're operating offline */,
37
100
  offlineProfile: profile,
38
101
  isLoading: false,
39
102
  authKickedMessage: null
40
103
  }));
41
104
  },
42
105
  /**
43
- * Set auth mode to none (no session)
106
+ * Transition to unauthenticated mode.
107
+ *
108
+ * Clears all session and profile data. Optionally stores a human-readable
109
+ * message explaining why the user was signed out, which the login UI can
110
+ * display as a banner or toast.
111
+ *
112
+ * @param kickedMessage - Optional explanation for the forced sign-out
113
+ *
114
+ * @example
115
+ * ```ts
116
+ * // Voluntary logout
117
+ * authState.setNoAuth();
118
+ *
119
+ * // Forced sign-out with reason
120
+ * authState.setNoAuth('Your session has expired.');
121
+ * ```
44
122
  */
45
123
  setNoAuth(kickedMessage) {
46
124
  update((state) => ({
@@ -53,25 +131,42 @@ function createAuthStateStore() {
53
131
  }));
54
132
  },
55
133
  /**
56
- * Set loading state
134
+ * Update only the loading flag without altering the auth mode or session.
135
+ *
136
+ * Useful during initialization when the auth subsystem needs to signal
137
+ * that it is still resolving the session state.
138
+ *
139
+ * @param isLoading - Whether the auth subsystem is currently loading
57
140
  */
58
141
  setLoading(isLoading) {
59
142
  update((state) => ({ ...state, isLoading }));
60
143
  },
61
144
  /**
62
- * Clear the auth kicked message
145
+ * Dismiss the kicked message without changing auth mode.
146
+ *
147
+ * Typically called after the login UI has displayed the kicked banner
148
+ * and the user has acknowledged it.
63
149
  */
64
150
  clearKickedMessage() {
65
151
  update((state) => ({ ...state, authKickedMessage: null }));
66
152
  },
67
153
  /**
68
- * Update the Supabase session (for token refresh)
154
+ * Update the Supabase session in-place (e.g., after a token refresh).
155
+ *
156
+ * If the new session is `null`, the session field is cleared but the mode
157
+ * is **not** changed here. The caller (typically the auth listener) is
158
+ * responsible for deciding whether to fall back to offline or no-auth mode.
159
+ *
160
+ * @param session - The refreshed Supabase session, or null if invalidated
161
+ *
162
+ * @see setNoAuth for transitioning to unauthenticated mode
163
+ * @see setOfflineAuth for falling back to offline mode
69
164
  */
70
165
  updateSession(session) {
71
166
  update((state) => {
72
167
  if (!session) {
73
- // Session was cleared - if online, set no auth
74
- // If offline and was in supabase mode, we'll check offline session elsewhere
168
+ /* Session was cleared - if online, set no auth
169
+ * If offline and was in supabase mode, we'll check offline session elsewhere */
75
170
  return {
76
171
  ...state,
77
172
  session: null
@@ -85,12 +180,24 @@ function createAuthStateStore() {
85
180
  });
86
181
  },
87
182
  /**
88
- * Update user profile info in the session
89
- * Used when profile is updated to immediately reflect changes in UI
183
+ * Merge updated profile fields into the current user metadata.
184
+ *
185
+ * Handles both Supabase and offline modes so UI components that display
186
+ * user profile info (avatar, display name, etc.) update immediately
187
+ * without waiting for a round-trip.
188
+ *
189
+ * @param profile - Key-value pairs to merge into the existing profile metadata
190
+ *
191
+ * @example
192
+ * ```ts
193
+ * // After saving profile changes to the server:
194
+ * authState.updateUserProfile({ display_name: 'New Name', avatar_url: newUrl });
195
+ * ```
90
196
  */
91
197
  updateUserProfile(profile) {
92
198
  update((state) => {
93
199
  if (state.mode === 'supabase' && state.session) {
200
+ /* Deep-merge into Supabase's user_metadata so existing fields are preserved */
94
201
  return {
95
202
  ...state,
96
203
  session: {
@@ -106,6 +213,8 @@ function createAuthStateStore() {
106
213
  };
107
214
  }
108
215
  if (state.mode === 'offline' && state.offlineProfile) {
216
+ /* For offline mode, replace the profile object wholesale since
217
+ * offline credentials use a simpler profile structure */
109
218
  return {
110
219
  ...state,
111
220
  offlineProfile: {
@@ -118,7 +227,11 @@ function createAuthStateStore() {
118
227
  });
119
228
  },
120
229
  /**
121
- * Reset to initial state
230
+ * Reset the store to its initial loading state.
231
+ *
232
+ * Called during app teardown or when reinitializing the auth subsystem.
233
+ * The `isLoading: true` default ensures the UI shows a loading indicator
234
+ * until the auth flow completes again.
122
235
  */
123
236
  reset() {
124
237
  set({
@@ -131,10 +244,49 @@ function createAuthStateStore() {
131
244
  }
132
245
  };
133
246
  }
247
+ // =============================================================================
248
+ // Singleton Store Instance
249
+ // =============================================================================
250
+ /** The singleton authentication state store used throughout the application. */
134
251
  export const authState = createAuthStateStore();
135
- // Derived store for checking if user is authenticated (any mode)
252
+ // =============================================================================
253
+ // Derived Stores
254
+ // =============================================================================
255
+ /**
256
+ * Derived store that resolves to `true` when the user is authenticated
257
+ * in any mode (Supabase or offline) and the auth subsystem has finished loading.
258
+ *
259
+ * Use this for route guards and conditional rendering of authenticated content.
260
+ *
261
+ * @example
262
+ * ```svelte
263
+ * {#if $isAuthenticated}
264
+ * <Dashboard />
265
+ * {:else}
266
+ * <LoginScreen />
267
+ * {/if}
268
+ * ```
269
+ *
270
+ * @see authState for the underlying state
271
+ */
136
272
  export const isAuthenticated = derived(authState, ($authState) => $authState.mode !== 'none' && !$authState.isLoading);
137
- // Derived store for getting user display info
273
+ /**
274
+ * Derived store that projects the user's display-friendly profile info
275
+ * (email and metadata) regardless of the current auth mode.
276
+ *
277
+ * Returns `null` when unauthenticated, allowing components to use a simple
278
+ * null check rather than inspecting the auth mode directly.
279
+ *
280
+ * @example
281
+ * ```svelte
282
+ * {#if $userDisplayInfo}
283
+ * <Avatar profile={$userDisplayInfo.profile} />
284
+ * <span>{$userDisplayInfo.email}</span>
285
+ * {/if}
286
+ * ```
287
+ *
288
+ * @see authState for the underlying state
289
+ */
138
290
  export const userDisplayInfo = derived(authState, ($authState) => {
139
291
  if ($authState.mode === 'supabase' && $authState.session) {
140
292
  const user = $authState.session.user;
@@ -1 +1 @@
1
- {"version":3,"file":"authState.js","sourceRoot":"","sources":["../../src/stores/authState.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"authState.js","sourceRoot":"","sources":["../../src/stores/authState.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,44 @@
1
+ /**
2
+ * @fileoverview Network Connectivity Store
3
+ *
4
+ * Provides a reactive boolean store (`isOnline`) that tracks whether the browser
5
+ * currently has network connectivity. Components subscribe to this store to
6
+ * conditionally enable/disable features that require a network connection
7
+ * (e.g., sync, realtime subscriptions, remote API calls).
8
+ *
9
+ * **Svelte Store Pattern:**
10
+ * Uses a custom writable store that exposes the standard `subscribe` method
11
+ * (making it a valid Svelte `Readable<boolean>`) plus imperative methods for
12
+ * initialization and callback registration. The store value is a simple boolean:
13
+ * `true` = online, `false` = offline.
14
+ *
15
+ * **Reactive Architecture:**
16
+ * The store listens to three browser events for comprehensive coverage:
17
+ * 1. `online` / `offline` - Standard connectivity events (works on desktop browsers)
18
+ * 2. `visibilitychange` - Catches iOS PWA edge cases where online/offline events
19
+ * do not fire reliably when the app returns from background
20
+ *
21
+ * Registered callbacks (via `onReconnect` / `onDisconnect`) are executed sequentially
22
+ * to ensure ordering guarantees (e.g., auth validation must complete before sync).
23
+ *
24
+ * @see {@link ./sync} for the sync store that depends on network state
25
+ * @see {@link ./authState} for auth state that may need revalidation on reconnect
26
+ */
1
27
  import { type Readable } from 'svelte/store';
28
+ /**
29
+ * Callback function registered for network state transitions.
30
+ * May be synchronous or asynchronous; async callbacks are properly awaited
31
+ * before the next callback in the sequence executes.
32
+ */
2
33
  type NetworkCallback = () => void | Promise<void>;
34
+ /**
35
+ * Singleton network connectivity store.
36
+ *
37
+ * Readable as a boolean (`true` = online, `false` = offline) and provides
38
+ * methods for initialization and callback registration.
39
+ *
40
+ * @see {@link createNetworkStore} for implementation details
41
+ */
3
42
  export declare const isOnline: Readable<boolean> & {
4
43
  init: () => void;
5
44
  onReconnect: (callback: NetworkCallback) => () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../src/stores/network.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAKvD,KAAK,eAAe,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAoHlD,eAAO,MAAM,QAAQ;UAjHb,MAAM,IAAI;iBACH,CAAC,QAAQ,EAAE,eAAe,KAAK,MAAM,IAAI;kBACxC,CAAC,QAAQ,EAAE,eAAe,KAAK,MAAM,IAAI;CA+Gb,CAAC"}
1
+ {"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../src/stores/network.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAQvD;;;;GAIG;AACH,KAAK,eAAe,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAqPlD;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ;UA7Nb,MAAM,IAAI;iBACH,CAAC,QAAQ,EAAE,eAAe,KAAK,MAAM,IAAI;kBACxC,CAAC,QAAQ,EAAE,eAAe,KAAK,MAAM,IAAI;CA2Nb,CAAC"}
@@ -1,22 +1,104 @@
1
+ /**
2
+ * @fileoverview Network Connectivity Store
3
+ *
4
+ * Provides a reactive boolean store (`isOnline`) that tracks whether the browser
5
+ * currently has network connectivity. Components subscribe to this store to
6
+ * conditionally enable/disable features that require a network connection
7
+ * (e.g., sync, realtime subscriptions, remote API calls).
8
+ *
9
+ * **Svelte Store Pattern:**
10
+ * Uses a custom writable store that exposes the standard `subscribe` method
11
+ * (making it a valid Svelte `Readable<boolean>`) plus imperative methods for
12
+ * initialization and callback registration. The store value is a simple boolean:
13
+ * `true` = online, `false` = offline.
14
+ *
15
+ * **Reactive Architecture:**
16
+ * The store listens to three browser events for comprehensive coverage:
17
+ * 1. `online` / `offline` - Standard connectivity events (works on desktop browsers)
18
+ * 2. `visibilitychange` - Catches iOS PWA edge cases where online/offline events
19
+ * do not fire reliably when the app returns from background
20
+ *
21
+ * Registered callbacks (via `onReconnect` / `onDisconnect`) are executed sequentially
22
+ * to ensure ordering guarantees (e.g., auth validation must complete before sync).
23
+ *
24
+ * @see {@link ./sync} for the sync store that depends on network state
25
+ * @see {@link ./authState} for auth state that may need revalidation on reconnect
26
+ */
1
27
  import { writable } from 'svelte/store';
2
28
  const browser = typeof window !== 'undefined';
3
29
  import { debugError } from '../debug';
30
+ // =============================================================================
31
+ // Store Factory
32
+ // =============================================================================
33
+ /**
34
+ * Creates the singleton network connectivity store.
35
+ *
36
+ * The store must be explicitly initialized via `init()` to attach browser event
37
+ * listeners. This is intentional: it allows server-side rendering (SSR) contexts
38
+ * to import the store without triggering browser API calls.
39
+ *
40
+ * @returns A Svelte-readable boolean store extended with `init`, `onReconnect`,
41
+ * and `onDisconnect` methods
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * // During app initialization:
46
+ * isOnline.init();
47
+ *
48
+ * // Register a reconnect handler (returns an unsubscribe function):
49
+ * const unsub = isOnline.onReconnect(async () => {
50
+ * await revalidateAuth();
51
+ * await triggerSync();
52
+ * });
53
+ *
54
+ * // In a Svelte component:
55
+ * $: if ($isOnline) { enableRealtimeFeatures(); }
56
+ * ```
57
+ */
4
58
  function createNetworkStore() {
5
59
  const { subscribe, set } = writable(true);
60
+ /** Set of callbacks to invoke when connectivity is restored */
6
61
  const reconnectCallbacks = new Set();
62
+ /** Set of callbacks to invoke when connectivity is lost */
7
63
  const disconnectCallbacks = new Set();
64
+ /** Tracks whether we were offline so reconnect callbacks only fire on actual transitions */
8
65
  let wasOffline = false;
9
- let currentValue = true; // Track current value to prevent redundant updates
10
- let initialized = false; // Prevent double-initialization
11
- let reconnectPending = false; // Prevent duplicate reconnect callbacks (iOS PWA fires both online + visibilitychange)
66
+ /** Tracks current value to prevent redundant store updates and re-renders */
67
+ let currentValue = true;
68
+ /** Guards against double-initialization (e.g., HMR in development) */
69
+ let initialized = false;
70
+ /**
71
+ * Guards against duplicate reconnect callback invocations.
72
+ * iOS PWAs can fire both `online` and `visibilitychange` events simultaneously
73
+ * when returning from background, which would otherwise trigger reconnect
74
+ * callbacks twice.
75
+ */
76
+ let reconnectPending = false;
77
+ // ---------------------------------------------------------------------------
78
+ // Internal Helpers
79
+ // ---------------------------------------------------------------------------
80
+ /**
81
+ * Conditionally updates the store value only when it actually changes.
82
+ * Prevents unnecessary Svelte re-renders for redundant state transitions.
83
+ *
84
+ * @param value - The new online/offline boolean state
85
+ */
12
86
  function setIfChanged(value) {
13
87
  if (value !== currentValue) {
14
88
  currentValue = value;
15
89
  set(value);
16
90
  }
17
91
  }
18
- // Run callbacks sequentially, properly awaiting async ones
19
- // This ensures auth validation completes before sync is triggered
92
+ /**
93
+ * Executes a set of callbacks one-by-one, awaiting each before proceeding.
94
+ *
95
+ * Sequential execution is critical here: for example, the auth revalidation
96
+ * callback must complete before the sync callback fires, since sync depends
97
+ * on a valid session token.
98
+ *
99
+ * @param callbacks - The set of callbacks to execute in registration order
100
+ * @param label - A human-readable label for error logging (e.g., 'Reconnect', 'Disconnect')
101
+ */
20
102
  async function runCallbacksSequentially(callbacks, label) {
21
103
  for (const callback of callbacks) {
22
104
  try {
@@ -27,47 +109,68 @@ function createNetworkStore() {
27
109
  }
28
110
  }
29
111
  }
112
+ // ---------------------------------------------------------------------------
113
+ // Public API
114
+ // ---------------------------------------------------------------------------
115
+ /**
116
+ * Attach browser event listeners for connectivity tracking.
117
+ *
118
+ * Must be called once during app startup (client-side only). Subsequent
119
+ * calls are no-ops to ensure idempotency.
120
+ *
121
+ * @see {@link createNetworkStore} for the full lifecycle description
122
+ */
30
123
  function init() {
31
124
  if (!browser)
32
125
  return;
33
126
  if (initialized)
34
- return; // Idempotent
127
+ return; /* Idempotent - safe to call multiple times */
35
128
  initialized = true;
36
- // Set initial state
129
+ /* Set initial state from the browser's navigator.onLine property */
37
130
  const initiallyOnline = navigator.onLine;
38
131
  currentValue = initiallyOnline;
39
132
  set(initiallyOnline);
40
133
  wasOffline = !initiallyOnline;
41
- // Listen for going offline
134
+ // -------------------------------------------------------------------------
135
+ // Event: Going Offline
136
+ // -------------------------------------------------------------------------
42
137
  window.addEventListener('offline', () => {
43
138
  const wasOnline = currentValue;
44
139
  wasOffline = true;
45
140
  setIfChanged(false);
46
- // If we were online, trigger disconnect callbacks
141
+ /* Only fire disconnect callbacks on an actual online->offline transition */
47
142
  if (wasOnline) {
48
143
  runCallbacksSequentially(disconnectCallbacks, 'Disconnect');
49
144
  }
50
145
  });
51
- // Listen for coming back online
146
+ // -------------------------------------------------------------------------
147
+ // Event: Coming Back Online
148
+ // -------------------------------------------------------------------------
52
149
  window.addEventListener('online', () => {
53
150
  setIfChanged(true);
54
- // If we were offline, trigger reconnect callbacks (guard against duplicate firing)
151
+ /* Guard against duplicate firing (iOS PWA fires both online + visibilitychange) */
55
152
  if (wasOffline && !reconnectPending) {
56
153
  wasOffline = false;
57
154
  reconnectPending = true;
58
- // Small delay to ensure network is stable
155
+ /* Small delay (500ms) to ensure the network connection has stabilized
156
+ * before triggering potentially expensive operations like sync */
59
157
  setTimeout(() => {
60
158
  reconnectPending = false;
61
159
  runCallbacksSequentially(reconnectCallbacks, 'Reconnect');
62
160
  }, 500);
63
161
  }
64
162
  });
65
- // Also listen for visibility changes (iOS specific - PWA may not fire online/offline)
163
+ // -------------------------------------------------------------------------
164
+ // Event: Visibility Change (iOS PWA Workaround)
165
+ // -------------------------------------------------------------------------
166
+ /* iOS PWAs often do not fire online/offline events when the app is
167
+ * backgrounded and resumed. The visibilitychange event catches these
168
+ * cases and ensures the store reflects the actual connectivity state. */
66
169
  document.addEventListener('visibilitychange', () => {
67
170
  if (document.visibilityState === 'visible') {
68
171
  const nowOnline = navigator.onLine;
69
- setIfChanged(nowOnline); // Only update if actually changed
70
- // If we're coming back online after being hidden (guard against duplicate firing)
172
+ setIfChanged(nowOnline); /* Only triggers a store update if value actually changed */
173
+ /* If we're coming back online after being hidden (guard against duplicate firing) */
71
174
  if (nowOnline && wasOffline && !reconnectPending) {
72
175
  wasOffline = false;
73
176
  reconnectPending = true;
@@ -78,15 +181,54 @@ function createNetworkStore() {
78
181
  }
79
182
  }
80
183
  else {
81
- // When going to background, assume we might lose connection
184
+ /* When going to background, conservatively mark as potentially offline
185
+ * so that reconnect callbacks fire if needed when the tab becomes visible again */
82
186
  wasOffline = !navigator.onLine;
83
187
  }
84
188
  });
85
189
  }
190
+ /**
191
+ * Register a callback to be invoked when network connectivity is restored.
192
+ *
193
+ * Callbacks are executed sequentially in registration order and properly
194
+ * awaited if async. Use this for operations that must happen on reconnect
195
+ * (auth revalidation, sync trigger, realtime re-subscription).
196
+ *
197
+ * @param callback - The function to call on reconnect (may be sync or async)
198
+ * @returns An unsubscribe function that removes the callback from the set
199
+ *
200
+ * @example
201
+ * ```ts
202
+ * const unsub = isOnline.onReconnect(async () => {
203
+ * await authState.revalidate();
204
+ * await syncEngine.pushPendingChanges();
205
+ * });
206
+ * // Later, to stop listening:
207
+ * unsub();
208
+ * ```
209
+ */
86
210
  function onReconnect(callback) {
87
211
  reconnectCallbacks.add(callback);
88
212
  return () => reconnectCallbacks.delete(callback);
89
213
  }
214
+ /**
215
+ * Register a callback to be invoked when network connectivity is lost.
216
+ *
217
+ * Callbacks are executed sequentially in registration order and properly
218
+ * awaited if async. Use this for graceful degradation (pausing sync,
219
+ * switching to offline mode, showing offline indicators).
220
+ *
221
+ * @param callback - The function to call on disconnect (may be sync or async)
222
+ * @returns An unsubscribe function that removes the callback from the set
223
+ *
224
+ * @example
225
+ * ```ts
226
+ * const unsub = isOnline.onDisconnect(() => {
227
+ * realtimeChannel.unsubscribe();
228
+ * showOfflineBanner();
229
+ * });
230
+ * ```
231
+ */
90
232
  function onDisconnect(callback) {
91
233
  disconnectCallbacks.add(callback);
92
234
  return () => disconnectCallbacks.delete(callback);
@@ -98,5 +240,16 @@ function createNetworkStore() {
98
240
  onDisconnect
99
241
  };
100
242
  }
243
+ // =============================================================================
244
+ // Singleton Store Instance
245
+ // =============================================================================
246
+ /**
247
+ * Singleton network connectivity store.
248
+ *
249
+ * Readable as a boolean (`true` = online, `false` = offline) and provides
250
+ * methods for initialization and callback registration.
251
+ *
252
+ * @see {@link createNetworkStore} for implementation details
253
+ */
101
254
  export const isOnline = createNetworkStore();
102
255
  //# sourceMappingURL=network.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"network.js","sourceRoot":"","sources":["../../src/stores/network.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAiB,MAAM,cAAc,CAAC;AACvD,MAAM,OAAO,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAKtC,SAAS,kBAAkB;IAKzB,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,QAAQ,CAAU,IAAI,CAAC,CAAC;IACnD,MAAM,kBAAkB,GAAyB,IAAI,GAAG,EAAE,CAAC;IAC3D,MAAM,mBAAmB,GAAyB,IAAI,GAAG,EAAE,CAAC;IAC5D,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,IAAI,YAAY,GAAG,IAAI,CAAC,CAAC,mDAAmD;IAC5E,IAAI,WAAW,GAAG,KAAK,CAAC,CAAC,gCAAgC;IACzD,IAAI,gBAAgB,GAAG,KAAK,CAAC,CAAC,uFAAuF;IAErH,SAAS,YAAY,CAAC,KAAc;QAClC,IAAI,KAAK,KAAK,YAAY,EAAE,CAAC;YAC3B,YAAY,GAAG,KAAK,CAAC;YACrB,GAAG,CAAC,KAAK,CAAC,CAAC;QACb,CAAC;IACH,CAAC;IAED,2DAA2D;IAC3D,kEAAkE;IAClE,KAAK,UAAU,wBAAwB,CACrC,SAA+B,EAC/B,KAAa;QAEb,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC;gBACH,MAAM,QAAQ,EAAE,CAAC;YACnB,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,UAAU,CAAC,aAAa,KAAK,kBAAkB,EAAE,CAAC,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;IACH,CAAC;IAED,SAAS,IAAI;QACX,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,IAAI,WAAW;YAAE,OAAO,CAAC,aAAa;QACtC,WAAW,GAAG,IAAI,CAAC;QAEnB,oBAAoB;QACpB,MAAM,eAAe,GAAG,SAAS,CAAC,MAAM,CAAC;QACzC,YAAY,GAAG,eAAe,CAAC;QAC/B,GAAG,CAAC,eAAe,CAAC,CAAC;QACrB,UAAU,GAAG,CAAC,eAAe,CAAC;QAE9B,2BAA2B;QAC3B,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,GAAG,EAAE;YACtC,MAAM,SAAS,GAAG,YAAY,CAAC;YAC/B,UAAU,GAAG,IAAI,CAAC;YAClB,YAAY,CAAC,KAAK,CAAC,CAAC;YAEpB,kDAAkD;YAClD,IAAI,SAAS,EAAE,CAAC;gBACd,wBAAwB,CAAC,mBAAmB,EAAE,YAAY,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,gCAAgC;QAChC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,EAAE;YACrC,YAAY,CAAC,IAAI,CAAC,CAAC;YAEnB,mFAAmF;YACnF,IAAI,UAAU,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACpC,UAAU,GAAG,KAAK,CAAC;gBACnB,gBAAgB,GAAG,IAAI,CAAC;gBACxB,0CAA0C;gBAC1C,UAAU,CAAC,GAAG,EAAE;oBACd,gBAAgB,GAAG,KAAK,CAAC;oBACzB,wBAAwB,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAC;gBAC5D,CAAC,EAAE,GAAG,CAAC,CAAC;YACV,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,sFAAsF;QACtF,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,GAAG,EAAE;YACjD,IAAI,QAAQ,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;gBAC3C,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC;gBACnC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,kCAAkC;gBAE3D,kFAAkF;gBAClF,IAAI,SAAS,IAAI,UAAU,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACjD,UAAU,GAAG,KAAK,CAAC;oBACnB,gBAAgB,GAAG,IAAI,CAAC;oBACxB,UAAU,CAAC,GAAG,EAAE;wBACd,gBAAgB,GAAG,KAAK,CAAC;wBACzB,wBAAwB,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAC;oBAC5D,CAAC,EAAE,GAAG,CAAC,CAAC;gBACV,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,4DAA4D;gBAC5D,UAAU,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC;YACjC,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,SAAS,WAAW,CAAC,QAAyB;QAC5C,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjC,OAAO,GAAG,EAAE,CAAC,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACnD,CAAC;IAED,SAAS,YAAY,CAAC,QAAyB;QAC7C,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAClC,OAAO,GAAG,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACpD,CAAC;IAED,OAAO;QACL,SAAS;QACT,IAAI;QACJ,WAAW;QACX,YAAY;KACb,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAC"}
1
+ {"version":3,"file":"network.js","sourceRoot":"","sources":["../../src/stores/network.ts"],"names":[],"mappings":"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"}