@templatical/core 0.49.0 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -178,7 +178,6 @@ function buildUrl(template, params) {
178
178
  }
179
179
  const BASE = "/api/v1/projects/{project}/tenants/{tenant}";
180
180
  const TEMPLATE = `${BASE}/templates/{template}`;
181
- const AI = `${TEMPLATE}/ai`;
182
181
  const MEDIA = `${BASE}/media`;
183
182
  const FOLDERS = `${MEDIA}/folders`;
184
183
  const MODULES = `${BASE}/saved-modules`;
@@ -202,13 +201,6 @@ const API_ROUTES = {
202
201
  "comments.update": `${TEMPLATE}/comments/{comment}`,
203
202
  "comments.destroy": `${TEMPLATE}/comments/{comment}`,
204
203
  "comments.resolve": `${TEMPLATE}/comments/{comment}/resolve`,
205
- "ai.generate": `${AI}/generate`,
206
- "ai.conversationMessages": `${AI}/conversation-messages`,
207
- "ai.suggestions": `${AI}/suggestions`,
208
- "ai.rewriteText": `${AI}/rewrite-text`,
209
- "ai.score": `${AI}/score`,
210
- "ai.fixFinding": `${AI}/fix-finding`,
211
- "ai.generateFromDesign": `${AI}/generate-from-design`,
212
204
  "media.upload": `${MEDIA}/upload`,
213
205
  "media.browse": `${MEDIA}/browse`,
214
206
  "media.delete": `${MEDIA}/delete`,
@@ -693,624 +685,6 @@ var WebSocketClient = class {
693
685
  }
694
686
  };
695
687
  //#endregion
696
- //#region src/cloud/ai-chat.ts
697
- let messageIdCounter = 0;
698
- function generateMessageId() {
699
- return `msg_${Date.now()}_${++messageIdCounter}`;
700
- }
701
- function useAiChat(options) {
702
- const { authManager, getTemplateId, onApply, onError } = options;
703
- const messages = ref([]);
704
- const isGenerating = ref(false);
705
- const isLoadingHistory = ref(false);
706
- const error = ref(null);
707
- const failedPrompt = ref(null);
708
- const conversationId = ref(null);
709
- const lastApplyMessageId = ref(null);
710
- const lastPreviousContent = ref(null);
711
- const lastAppliedContent = ref(null);
712
- const isLastChangeReverted = ref(false);
713
- const suggestions = ref([]);
714
- const isLoadingSuggestions = ref(false);
715
- function updateMessage(msgId, updates) {
716
- const idx = messages.value.findIndex((m) => m.id === msgId);
717
- if (idx === -1) return;
718
- const updated = {
719
- ...messages.value[idx],
720
- ...updates
721
- };
722
- messages.value = [
723
- ...messages.value.slice(0, idx),
724
- updated,
725
- ...messages.value.slice(idx + 1)
726
- ];
727
- }
728
- async function loadConversation() {
729
- const templateId = getTemplateId();
730
- if (!templateId) return;
731
- isLoadingHistory.value = true;
732
- try {
733
- const url = buildUrl(API_ROUTES["ai.conversationMessages"], {
734
- project: authManager.projectId,
735
- tenant: authManager.tenantSlug,
736
- template: templateId
737
- });
738
- const response = await authManager.authenticatedFetch(url, {
739
- method: "GET",
740
- headers: { Accept: "application/json" }
741
- });
742
- if (!response.ok) return;
743
- const data = await response.json();
744
- if (data.conversationId) conversationId.value = data.conversationId;
745
- if (Array.isArray(data.data) && data.data.length > 0) messages.value = data.data.map((msg) => ({
746
- id: msg.id,
747
- role: msg.role,
748
- content: msg.content,
749
- timestamp: new Date(msg.createdAt).getTime()
750
- }));
751
- } catch {} finally {
752
- isLoadingHistory.value = false;
753
- }
754
- }
755
- async function loadSuggestions(currentContent, mergeTags) {
756
- const templateId = getTemplateId();
757
- if (!templateId) return;
758
- isLoadingSuggestions.value = true;
759
- try {
760
- const url = buildUrl(API_ROUTES["ai.suggestions"], {
761
- project: authManager.projectId,
762
- tenant: authManager.tenantSlug,
763
- template: templateId
764
- });
765
- const response = await authManager.authenticatedFetch(url, {
766
- method: "POST",
767
- headers: {
768
- "Content-Type": "application/json",
769
- Accept: "text/event-stream"
770
- },
771
- body: JSON.stringify({
772
- currentContent,
773
- mergeTags: mergeTags.map((p) => ({
774
- label: p.label,
775
- value: p.value
776
- }))
777
- })
778
- });
779
- if (!response.ok) return;
780
- const reader = response.body?.getReader();
781
- if (!reader) return;
782
- const decoder = new TextDecoder();
783
- let buffer = "";
784
- while (true) {
785
- const { done, value } = await reader.read();
786
- if (done) break;
787
- buffer += decoder.decode(value, { stream: true });
788
- const lines = buffer.split("\n");
789
- buffer = lines.pop() ?? "";
790
- for (const line of lines) {
791
- if (!line.startsWith("data: ")) continue;
792
- let event;
793
- try {
794
- event = JSON.parse(line.slice(6));
795
- } catch {
796
- continue;
797
- }
798
- if (event.type === "done" && Array.isArray(event.suggestions)) suggestions.value = event.suggestions.slice(0, 3);
799
- }
800
- }
801
- } catch {} finally {
802
- isLoadingSuggestions.value = false;
803
- }
804
- }
805
- async function sendPrompt(prompt, currentContent, mergeTags) {
806
- const templateId = getTemplateId();
807
- if (!templateId) throw new Error("Template must be saved before using AI generation");
808
- isGenerating.value = true;
809
- error.value = null;
810
- failedPrompt.value = null;
811
- suggestions.value = [];
812
- const userMsgId = generateMessageId();
813
- messages.value = [...messages.value, {
814
- id: userMsgId,
815
- role: "user",
816
- content: prompt,
817
- timestamp: Date.now()
818
- }];
819
- const assistantMsgId = generateMessageId();
820
- messages.value = [...messages.value, {
821
- id: assistantMsgId,
822
- role: "assistant",
823
- content: "",
824
- timestamp: Date.now()
825
- }];
826
- try {
827
- const url = buildUrl(API_ROUTES["ai.generate"], {
828
- project: authManager.projectId,
829
- tenant: authManager.tenantSlug,
830
- template: templateId
831
- });
832
- const response = await authManager.authenticatedFetch(url, {
833
- method: "POST",
834
- headers: {
835
- "Content-Type": "application/json",
836
- Accept: "text/event-stream"
837
- },
838
- body: JSON.stringify({
839
- prompt,
840
- currentContent,
841
- mergeTags: mergeTags.map((p) => ({
842
- label: p.label,
843
- value: p.value
844
- })),
845
- conversationId: conversationId.value
846
- })
847
- });
848
- if (!response.ok) {
849
- const errorData = await response.json().catch(() => null);
850
- if (response.status === 403) throw new Error("aiGenerationNotAvailable");
851
- throw new Error(errorData?.message || "Failed to generate template");
852
- }
853
- const reader = response.body?.getReader();
854
- if (!reader) throw new Error("Failed to read stream");
855
- const decoder = new TextDecoder();
856
- let buffer = "";
857
- let result = null;
858
- try {
859
- while (true) {
860
- const { done, value } = await reader.read();
861
- if (done) break;
862
- buffer += decoder.decode(value, { stream: true });
863
- const lines = buffer.split("\n");
864
- buffer = lines.pop() ?? "";
865
- for (const line of lines) {
866
- if (!line.startsWith("data: ")) continue;
867
- const jsonStr = line.slice(6);
868
- let event;
869
- try {
870
- event = JSON.parse(jsonStr);
871
- } catch {
872
- continue;
873
- }
874
- if (event.type === "text") updateMessage(assistantMsgId, { content: (messages.value.find((m) => m.id === assistantMsgId)?.content ?? "") + event.text });
875
- else if (event.type === "error") throw new Error(event.message || "Failed to generate template");
876
- else if (event.type === "done") {
877
- if (event.conversationId) conversationId.value = event.conversationId;
878
- updateMessage(assistantMsgId, { content: event.text });
879
- result = event.content ?? null;
880
- if (result) {
881
- lastPreviousContent.value = currentContent;
882
- lastAppliedContent.value = result;
883
- lastApplyMessageId.value = assistantMsgId;
884
- isLastChangeReverted.value = false;
885
- onApply?.(result);
886
- } else error.value = "ai_apply_failed";
887
- }
888
- }
889
- }
890
- } finally {
891
- reader.cancel().catch(() => {});
892
- }
893
- return result;
894
- } catch (err) {
895
- const wrappedError = err instanceof Error ? err : new Error("Failed to generate template", { cause: err });
896
- error.value = wrappedError.message;
897
- failedPrompt.value = prompt;
898
- onError?.(wrappedError);
899
- messages.value = messages.value.filter((m) => m.id !== userMsgId && m.id !== assistantMsgId);
900
- return null;
901
- } finally {
902
- isGenerating.value = false;
903
- }
904
- }
905
- function toggleLastRevert() {
906
- if (isLastChangeReverted.value) {
907
- if (lastAppliedContent.value) onApply?.(lastAppliedContent.value);
908
- isLastChangeReverted.value = false;
909
- } else {
910
- if (lastPreviousContent.value) onApply?.(lastPreviousContent.value);
911
- isLastChangeReverted.value = true;
912
- }
913
- }
914
- function clearChat() {
915
- messages.value = [];
916
- conversationId.value = null;
917
- error.value = null;
918
- lastApplyMessageId.value = null;
919
- lastPreviousContent.value = null;
920
- lastAppliedContent.value = null;
921
- isLastChangeReverted.value = false;
922
- }
923
- return {
924
- messages,
925
- isGenerating,
926
- isLoadingHistory,
927
- isLastChangeReverted,
928
- lastApplyMessageId,
929
- error,
930
- failedPrompt,
931
- suggestions,
932
- isLoadingSuggestions,
933
- sendPrompt,
934
- toggleLastRevert,
935
- loadConversation,
936
- loadSuggestions,
937
- clearChat
938
- };
939
- }
940
- //#endregion
941
- //#region src/cloud/ai-rewrite.ts
942
- function useAiRewrite(options) {
943
- const { authManager, getTemplateId } = options;
944
- const isRewriting = ref(false);
945
- const streamingText = ref("");
946
- const previousContent = ref(null);
947
- const rewrittenContent = ref(null);
948
- const isReverted = ref(false);
949
- const error = ref(null);
950
- async function rewrite(content, instruction, mergeTags) {
951
- const templateId = getTemplateId();
952
- if (!templateId) return null;
953
- isRewriting.value = true;
954
- streamingText.value = "";
955
- error.value = null;
956
- try {
957
- const url = buildUrl(API_ROUTES["ai.rewriteText"], {
958
- project: authManager.projectId,
959
- tenant: authManager.tenantSlug,
960
- template: templateId
961
- });
962
- const response = await authManager.authenticatedFetch(url, {
963
- method: "POST",
964
- headers: {
965
- "Content-Type": "application/json",
966
- Accept: "text/event-stream"
967
- },
968
- body: JSON.stringify({
969
- content,
970
- instruction,
971
- mergeTags: mergeTags.map((p) => ({
972
- label: p.label,
973
- value: p.value
974
- }))
975
- })
976
- });
977
- if (!response.ok) {
978
- if (response.status === 403) throw new Error("aiGenerationNotAvailable");
979
- const errorData = await response.json().catch(() => null);
980
- throw new Error(errorData?.message || "Failed to rewrite text");
981
- }
982
- const reader = response.body?.getReader();
983
- if (!reader) throw new Error("Failed to read stream");
984
- const decoder = new TextDecoder();
985
- let buffer = "";
986
- let result = null;
987
- while (true) {
988
- const { done, value } = await reader.read();
989
- if (done) break;
990
- buffer += decoder.decode(value, { stream: true });
991
- const lines = buffer.split("\n");
992
- buffer = lines.pop() ?? "";
993
- for (const line of lines) {
994
- if (!line.startsWith("data: ")) continue;
995
- let event;
996
- try {
997
- event = JSON.parse(line.slice(6));
998
- } catch {
999
- continue;
1000
- }
1001
- if (event.type === "text") streamingText.value += event.text;
1002
- else if (event.type === "error") throw new Error(event.message || "Failed to rewrite text");
1003
- else if (event.type === "done") {
1004
- result = event.content ?? null;
1005
- if (result) {
1006
- previousContent.value = content;
1007
- rewrittenContent.value = result;
1008
- isReverted.value = false;
1009
- }
1010
- }
1011
- }
1012
- }
1013
- return result;
1014
- } catch (err) {
1015
- error.value = err instanceof Error ? err.message : "Failed to rewrite text";
1016
- return null;
1017
- } finally {
1018
- isRewriting.value = false;
1019
- }
1020
- }
1021
- function undo() {
1022
- if (!previousContent.value) return null;
1023
- isReverted.value = true;
1024
- return previousContent.value;
1025
- }
1026
- function redo() {
1027
- if (!rewrittenContent.value) return null;
1028
- isReverted.value = false;
1029
- return rewrittenContent.value;
1030
- }
1031
- function reset() {
1032
- isRewriting.value = false;
1033
- streamingText.value = "";
1034
- previousContent.value = null;
1035
- rewrittenContent.value = null;
1036
- isReverted.value = false;
1037
- error.value = null;
1038
- }
1039
- return {
1040
- isRewriting,
1041
- streamingText,
1042
- previousContent,
1043
- rewrittenContent,
1044
- isReverted,
1045
- error,
1046
- rewrite,
1047
- undo,
1048
- redo,
1049
- reset
1050
- };
1051
- }
1052
- //#endregion
1053
- //#region src/cloud/ai-config.ts
1054
- function useAiConfig(config) {
1055
- function isFeatureEnabled(feature) {
1056
- if (config === false) return false;
1057
- return config?.[feature] !== false;
1058
- }
1059
- return {
1060
- isFeatureEnabled,
1061
- hasAnyMenuFeature: computed(() => isFeatureEnabled("chat") || isFeatureEnabled("scoring") || isFeatureEnabled("designToTemplate"))
1062
- };
1063
- }
1064
- //#endregion
1065
- //#region src/cloud/template-scoring.ts
1066
- function useTemplateScoring(options) {
1067
- const { authManager, getTemplateId } = options;
1068
- const isScoring = ref(false);
1069
- const scoringResult = ref(null);
1070
- const error = ref(null);
1071
- const fixingFindingId = ref(null);
1072
- const fixStreamingText = ref("");
1073
- const fixError = ref(null);
1074
- async function score(content, mergeTags) {
1075
- const templateId = getTemplateId();
1076
- if (!templateId) return null;
1077
- isScoring.value = true;
1078
- error.value = null;
1079
- scoringResult.value = null;
1080
- try {
1081
- const url = buildUrl(API_ROUTES["ai.score"], {
1082
- project: authManager.projectId,
1083
- tenant: authManager.tenantSlug,
1084
- template: templateId
1085
- });
1086
- const response = await authManager.authenticatedFetch(url, {
1087
- method: "POST",
1088
- headers: {
1089
- "Content-Type": "application/json",
1090
- Accept: "text/event-stream"
1091
- },
1092
- body: JSON.stringify({
1093
- currentContent: content,
1094
- mergeTags: mergeTags.map((p) => ({
1095
- label: p.label,
1096
- value: p.value
1097
- }))
1098
- })
1099
- });
1100
- if (!response.ok) {
1101
- if (response.status === 403) throw new Error("aiGenerationNotAvailable");
1102
- const errorData = await response.json().catch(() => null);
1103
- throw new Error(errorData?.message || "Failed to score template");
1104
- }
1105
- const reader = response.body?.getReader();
1106
- if (!reader) throw new Error("Failed to read stream");
1107
- const decoder = new TextDecoder();
1108
- let buffer = "";
1109
- let result = null;
1110
- while (true) {
1111
- const { done, value } = await reader.read();
1112
- if (done) break;
1113
- buffer += decoder.decode(value, { stream: true });
1114
- const lines = buffer.split("\n");
1115
- buffer = lines.pop() ?? "";
1116
- for (const line of lines) {
1117
- if (!line.startsWith("data: ")) continue;
1118
- let event;
1119
- try {
1120
- event = JSON.parse(line.slice(6));
1121
- } catch {
1122
- continue;
1123
- }
1124
- if (event.type === "error") throw new Error(event.message || "Failed to score template");
1125
- if (event.type === "done") result = event.result ?? null;
1126
- }
1127
- }
1128
- if (result) for (const [category, categoryData] of Object.entries(result.categories)) for (const finding of categoryData.findings) finding.category = category;
1129
- scoringResult.value = result;
1130
- return result;
1131
- } catch (err) {
1132
- error.value = err instanceof Error ? err.message : "Failed to score template";
1133
- return null;
1134
- } finally {
1135
- isScoring.value = false;
1136
- }
1137
- }
1138
- async function fixFinding(blockContent, finding, mergeTags) {
1139
- const templateId = getTemplateId();
1140
- if (!templateId) return null;
1141
- fixingFindingId.value = finding.id;
1142
- fixStreamingText.value = "";
1143
- fixError.value = null;
1144
- try {
1145
- const url = buildUrl(API_ROUTES["ai.fixFinding"], {
1146
- project: authManager.projectId,
1147
- tenant: authManager.tenantSlug,
1148
- template: templateId
1149
- });
1150
- const response = await authManager.authenticatedFetch(url, {
1151
- method: "POST",
1152
- headers: {
1153
- "Content-Type": "application/json",
1154
- Accept: "text/event-stream"
1155
- },
1156
- body: JSON.stringify({
1157
- content: blockContent,
1158
- finding: {
1159
- id: finding.id,
1160
- message: finding.message,
1161
- suggestion: finding.suggestion,
1162
- category: finding.category
1163
- },
1164
- mergeTags: mergeTags.map((p) => ({
1165
- label: p.label,
1166
- value: p.value
1167
- }))
1168
- })
1169
- });
1170
- if (!response.ok) {
1171
- if (response.status === 403) throw new Error("aiGenerationNotAvailable");
1172
- const errorData = await response.json().catch(() => null);
1173
- throw new Error(errorData?.message || "Failed to fix finding");
1174
- }
1175
- const reader = response.body?.getReader();
1176
- if (!reader) throw new Error("Failed to read stream");
1177
- const decoder = new TextDecoder();
1178
- let buffer = "";
1179
- let result = null;
1180
- while (true) {
1181
- const { done, value } = await reader.read();
1182
- if (done) break;
1183
- buffer += decoder.decode(value, { stream: true });
1184
- const lines = buffer.split("\n");
1185
- buffer = lines.pop() ?? "";
1186
- for (const line of lines) {
1187
- if (!line.startsWith("data: ")) continue;
1188
- let event;
1189
- try {
1190
- event = JSON.parse(line.slice(6));
1191
- } catch {
1192
- continue;
1193
- }
1194
- if (event.type === "text") fixStreamingText.value += event.text;
1195
- else if (event.type === "error") throw new Error(event.message || "Failed to fix finding");
1196
- else if (event.type === "done") result = event.content ?? null;
1197
- }
1198
- }
1199
- return result;
1200
- } catch (err) {
1201
- fixError.value = err instanceof Error ? err.message : "Failed to fix finding";
1202
- return null;
1203
- } finally {
1204
- fixingFindingId.value = null;
1205
- }
1206
- }
1207
- function removeFinding(category, findingId) {
1208
- if (!scoringResult.value) return;
1209
- const cat = scoringResult.value.categories[category];
1210
- if (!cat) return;
1211
- cat.findings = cat.findings.filter((f) => f.id !== findingId);
1212
- }
1213
- function reset() {
1214
- isScoring.value = false;
1215
- scoringResult.value = null;
1216
- error.value = null;
1217
- fixingFindingId.value = null;
1218
- fixStreamingText.value = "";
1219
- fixError.value = null;
1220
- }
1221
- return {
1222
- isScoring,
1223
- scoringResult,
1224
- error,
1225
- fixingFindingId,
1226
- fixStreamingText,
1227
- fixError,
1228
- score,
1229
- fixFinding,
1230
- removeFinding,
1231
- reset
1232
- };
1233
- }
1234
- //#endregion
1235
- //#region src/cloud/design-reference.ts
1236
- function useDesignReference(options) {
1237
- const { authManager, getTemplateId, onApply, onError } = options;
1238
- const isGenerating = ref(false);
1239
- const error = ref(null);
1240
- async function generate(input) {
1241
- const templateId = getTemplateId();
1242
- if (!templateId) throw new Error("Template must be saved before using design reference");
1243
- isGenerating.value = true;
1244
- error.value = null;
1245
- try {
1246
- const formData = new FormData();
1247
- if (input.prompt) formData.append("prompt", input.prompt);
1248
- if (input.imageUpload) formData.append("image_upload", input.imageUpload);
1249
- if (input.pdfUpload) formData.append("pdf_upload", input.pdfUpload);
1250
- const url = buildUrl(API_ROUTES["ai.generateFromDesign"], {
1251
- project: authManager.projectId,
1252
- tenant: authManager.tenantSlug,
1253
- template: templateId
1254
- });
1255
- const response = await authManager.authenticatedFetch(url, {
1256
- method: "POST",
1257
- headers: { Accept: "text/event-stream" },
1258
- body: formData
1259
- });
1260
- if (!response.ok) {
1261
- const errorData = await response.json().catch(() => null);
1262
- if (response.status === 403) throw new Error("aiGenerationNotAvailable");
1263
- throw new Error(errorData?.message || "Failed to generate template from design");
1264
- }
1265
- const reader = response.body?.getReader();
1266
- if (!reader) throw new Error("Failed to read stream");
1267
- const decoder = new TextDecoder();
1268
- let buffer = "";
1269
- let result = null;
1270
- while (true) {
1271
- const { done, value } = await reader.read();
1272
- if (done) break;
1273
- buffer += decoder.decode(value, { stream: true });
1274
- const lines = buffer.split("\n");
1275
- buffer = lines.pop() ?? "";
1276
- for (const line of lines) {
1277
- if (!line.startsWith("data: ")) continue;
1278
- const jsonStr = line.slice(6);
1279
- let event;
1280
- try {
1281
- event = JSON.parse(jsonStr);
1282
- } catch {
1283
- continue;
1284
- }
1285
- if (event.type === "error") throw new Error(event.message || "Failed to generate template from design");
1286
- if (event.type === "done") {
1287
- result = event.content ?? null;
1288
- if (result) onApply?.(result);
1289
- }
1290
- }
1291
- }
1292
- return result;
1293
- } catch (err) {
1294
- const wrappedError = err instanceof Error ? err : new Error("Failed to generate template from design", { cause: err });
1295
- error.value = wrappedError.message;
1296
- onError?.(wrappedError);
1297
- return null;
1298
- } finally {
1299
- isGenerating.value = false;
1300
- }
1301
- }
1302
- function reset() {
1303
- isGenerating.value = false;
1304
- error.value = null;
1305
- }
1306
- return {
1307
- isGenerating,
1308
- error,
1309
- generate,
1310
- reset
1311
- };
1312
- }
1313
- //#endregion
1314
688
  //#region src/cloud/comments-provider.ts
1315
689
  /** The Pusher event Cloud's backend fans comment writes out on. */
1316
690
  const BROADCAST_EVENT = "comment-broadcast";
@@ -2090,6 +1464,6 @@ async function performHealthCheck(options = {}) {
2090
1464
  };
2091
1465
  }
2092
1466
  //#endregion
2093
- export { API_ROUTES, ApiClient, AuthManager, MediaApiClient, WebSocketClient, buildUrl, createCloudCommentsProvider, createCloudMediaProvider, createCloudRenderProvider, createCloudSavedBlocksProvider, createCloudTemplatesProvider, createCloudTestEmailProvider, createCloudVersionHistoryProvider, createSdkAuthManager, isFatalAuthError, performHealthCheck, resolveExportFonts, resolveWebSocketConfig, useAiChat, useAiConfig, useAiRewrite, useDesignReference, useExport, usePlanConfig, useTemplateScoring, useTestEmail, useWebSocket };
1467
+ export { API_ROUTES, ApiClient, AuthManager, MediaApiClient, WebSocketClient, buildUrl, createCloudCommentsProvider, createCloudMediaProvider, createCloudRenderProvider, createCloudSavedBlocksProvider, createCloudTemplatesProvider, createCloudTestEmailProvider, createCloudVersionHistoryProvider, createSdkAuthManager, isFatalAuthError, performHealthCheck, resolveExportFonts, resolveWebSocketConfig, useExport, usePlanConfig, useTestEmail, useWebSocket };
2094
1468
 
2095
1469
  //# sourceMappingURL=index.js.map