@8wave/ai-elements 0.74.0 → 0.77.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{PkStreamingMarkdown-orhL2kzD.js → PkStreamingMarkdown-COZApJzT.js} +22 -22
- package/dist/_chunks/PkStreamingMarkdown-COZApJzT.js.map +1 -0
- package/dist/_chunks/{PkToolShowArtifact-c_vCWUpQ.js → PkToolShowArtifact-BZQixk9z.js} +7 -7
- package/dist/_chunks/{PkToolShowArtifact-c_vCWUpQ.js.map → PkToolShowArtifact-BZQixk9z.js.map} +1 -1
- package/dist/_chunks/{PkToolShowCalendarEvent-D2VHu1V3.js → PkToolShowCalendarEvent-BEqn5iEb.js} +12 -12
- package/dist/_chunks/{PkToolShowCalendarEvent-D2VHu1V3.js.map → PkToolShowCalendarEvent-BEqn5iEb.js.map} +1 -1
- package/dist/_chunks/{PkToolShowComparison-C2ZUH0w4.js → PkToolShowComparison-p34r0Hhd.js} +7 -7
- package/dist/_chunks/{PkToolShowComparison-C2ZUH0w4.js.map → PkToolShowComparison-p34r0Hhd.js.map} +1 -1
- package/dist/_chunks/PkToolShowContactForm-thS7c8iL.js +1658 -0
- package/dist/_chunks/PkToolShowContactForm-thS7c8iL.js.map +1 -0
- package/dist/_chunks/{PkToolShowEmail-BuyCHUU5.js → PkToolShowEmail-Be8FvWjw.js} +11 -11
- package/dist/_chunks/{PkToolShowEmail-BuyCHUU5.js.map → PkToolShowEmail-Be8FvWjw.js.map} +1 -1
- package/dist/_chunks/{PkToolShowImageGallery-ByldZ0nj.js → PkToolShowImageGallery-DmJztS-Z.js} +5 -5
- package/dist/_chunks/{PkToolShowImageGallery-ByldZ0nj.js.map → PkToolShowImageGallery-DmJztS-Z.js.map} +1 -1
- package/dist/_chunks/{PkToolShowLocation-BCFnC5c7.js → PkToolShowLocation-DOoLCHzS.js} +9 -9
- package/dist/_chunks/{PkToolShowLocation-BCFnC5c7.js.map → PkToolShowLocation-DOoLCHzS.js.map} +1 -1
- package/dist/_chunks/{PkToolShowMessage-6Bsfi3BC.js → PkToolShowMessage-DgeULbdQ.js} +10 -10
- package/dist/_chunks/{PkToolShowMessage-6Bsfi3BC.js.map → PkToolShowMessage-DgeULbdQ.js.map} +1 -1
- package/dist/_chunks/{PkToolShowMultipleChoice-BLNTD2lK.js → PkToolShowMultipleChoice-CpGyn_bZ.js} +3 -3
- package/dist/_chunks/{PkToolShowMultipleChoice-BLNTD2lK.js.map → PkToolShowMultipleChoice-CpGyn_bZ.js.map} +1 -1
- package/dist/_chunks/{PkToolShowProductList-B4S5_m-f.js → PkToolShowProductList-DEo7XogW.js} +4 -4
- package/dist/_chunks/{PkToolShowProductList-B4S5_m-f.js.map → PkToolShowProductList-DEo7XogW.js.map} +1 -1
- package/dist/_chunks/{PkToolShowQrCode-BVZlzYDq.js → PkToolShowQrCode-UE4uSyvJ.js} +7 -7
- package/dist/_chunks/{PkToolShowQrCode-BVZlzYDq.js.map → PkToolShowQrCode-UE4uSyvJ.js.map} +1 -1
- package/dist/_chunks/{PkToolShowSources-BQo5DRwt.js → PkToolShowSources-BMXftK6O.js} +10 -9
- package/dist/_chunks/PkToolShowSources-BMXftK6O.js.map +1 -0
- package/dist/_chunks/{PkToolShowSuggestedReply-BxDI6yp_.js → PkToolShowSuggestedReply-CPAnHI0c.js} +3 -3
- package/dist/_chunks/{PkToolShowSuggestedReply-BxDI6yp_.js.map → PkToolShowSuggestedReply-CPAnHI0c.js.map} +1 -1
- package/dist/_chunks/{PkToolShowWeather-DR6egBIP.js → PkToolShowWeather-DcSUbzx0.js} +4 -4
- package/dist/_chunks/{PkToolShowWeather-DR6egBIP.js.map → PkToolShowWeather-DcSUbzx0.js.map} +1 -1
- package/dist/_chunks/{PkToolShowWebPages-D8RngE-F.js → PkToolShowWebPages-aH_GarEV.js} +5 -5
- package/dist/_chunks/{PkToolShowWebPages-D8RngE-F.js.map → PkToolShowWebPages-aH_GarEV.js.map} +1 -1
- package/dist/_chunks/{PkUrl-CI17WkYu.js → PkUrl-BHD0_pal.js} +2 -2
- package/dist/_chunks/{PkUrl-CI17WkYu.js.map → PkUrl-BHD0_pal.js.map} +1 -1
- package/dist/_chunks/{VvCheckbox.es-kmMsWlkU.js → VvCheckbox.es-ohF87NOe.js} +3 -3
- package/dist/_chunks/{VvCheckbox.es-kmMsWlkU.js.map → VvCheckbox.es-ohF87NOe.js.map} +1 -1
- package/dist/_chunks/{VvCheckboxGroup.es-BRRmuO9h.js → VvCheckboxGroup.es-DZCbyLN0.js} +109 -109
- package/dist/_chunks/{VvCheckboxGroup.es-BRRmuO9h.js.map → VvCheckboxGroup.es-DZCbyLN0.js.map} +1 -1
- package/dist/_chunks/{VvCombobox.es-pTM53Z4B.js → VvCombobox.es-YLPD7MpO.js} +256 -256
- package/dist/_chunks/{VvCombobox.es-pTM53Z4B.js.map → VvCombobox.es-YLPD7MpO.js.map} +1 -1
- package/dist/_chunks/{VvInputText.es-DO39OSWk.js → VvInputText.es-DAnAXfBO.js} +190 -190
- package/dist/_chunks/{VvInputText.es-DO39OSWk.js.map → VvInputText.es-DAnAXfBO.js.map} +1 -1
- package/dist/_chunks/{VvRadio.es-BpQAJbon.js → VvRadio.es-Do9oyNtV.js} +3 -3
- package/dist/_chunks/{VvRadio.es-BpQAJbon.js.map → VvRadio.es-Do9oyNtV.js.map} +1 -1
- package/dist/_chunks/{VvRadioGroup.es-BSBrmx9w.js → VvRadioGroup.es-BHcqcJFC.js} +11 -11
- package/dist/_chunks/{VvRadioGroup.es-BSBrmx9w.js.map → VvRadioGroup.es-BHcqcJFC.js.map} +1 -1
- package/dist/_chunks/{VvSelect.es-DALpUK5j.js → VvSelect.es-CP_y02fy.js} +8 -8
- package/dist/_chunks/{VvSelect.es-DALpUK5j.js.map → VvSelect.es-CP_y02fy.js.map} +1 -1
- package/dist/_chunks/{VvTextarea.es-C9dwYLOG.js → VvTextarea.es-DetA_2DM.js} +250 -250
- package/dist/_chunks/{VvTextarea.es-C9dwYLOG.js.map → VvTextarea.es-DetA_2DM.js.map} +1 -1
- package/dist/_chunks/{dist-DtF6poRc.js → dist-yqV26MWM.js} +132 -120
- package/dist/_chunks/dist-yqV26MWM.js.map +1 -0
- package/dist/_chunks/{esm-0nyRYwmP.js → esm-DLxNpT06.js} +7 -7
- package/dist/_chunks/{esm-0nyRYwmP.js.map → esm-DLxNpT06.js.map} +1 -1
- package/dist/_chunks/{floating-ui.vue-B5ZV-j8C.js → floating-ui.vue-tVPpNXUc.js} +3 -3
- package/dist/_chunks/{floating-ui.vue-B5ZV-j8C.js.map → floating-ui.vue-tVPpNXUc.js.map} +1 -1
- package/dist/_chunks/{iconify-C1EOwL90.js → iconify-y0w2FIJH.js} +3 -3
- package/dist/_chunks/{iconify-C1EOwL90.js.map → iconify-y0w2FIJH.js.map} +1 -1
- package/dist/_chunks/{index.es-BGFmj59S.js → index.es-7fUi-rc0.js} +452 -452
- package/dist/_chunks/{index.es-BGFmj59S.js.map → index.es-7fUi-rc0.js.map} +1 -1
- package/dist/_chunks/{schemas-Bp3a8tYV.js → schemas-aPiXCaCc.js} +1309 -945
- package/dist/_chunks/schemas-aPiXCaCc.js.map +1 -0
- package/dist/_chunks/{src-C_wl-KYN.js → src-BfoQF6Z3.js} +2 -2
- package/dist/_chunks/{src-C_wl-KYN.js.map → src-BfoQF6Z3.js.map} +1 -1
- package/dist/_chunks/{useLightbox-CH1KeVqr.js → useLightbox-DL_oVBep.js} +3 -3
- package/dist/_chunks/{useLightbox-CH1KeVqr.js.map → useLightbox-DL_oVBep.js.map} +1 -1
- package/dist/_chunks/{vue-i18n-KvYvoek4.js → vue-i18n-DAH6nDTN.js} +3 -3
- package/dist/_chunks/{vue-i18n-KvYvoek4.js.map → vue-i18n-DAH6nDTN.js.map} +1 -1
- package/dist/_chunks/{vue.runtime.esm-bundler-BmggS4HU.js → vue.runtime.esm-bundler-Dq29dQrz.js} +16 -10
- package/dist/_chunks/vue.runtime.esm-bundler-Dq29dQrz.js.map +1 -0
- package/dist/ai-elements.es.js +4637 -3428
- package/dist/ai-elements.es.js.map +1 -1
- package/dist-vue/PkChatbot.js +1 -1
- package/dist-vue/PkChatbotFeedbackForm.js +1 -1
- package/dist-vue/PkChatbotInput.js +1 -1
- package/dist-vue/PkChatbotMessages.js +1 -1
- package/dist-vue/PkChatbotViewChat.js +1 -1
- package/dist-vue/PkChatbotViewConversations.js +1 -1
- package/dist-vue/PkChatbotViewProfile.js +1 -1
- package/dist-vue/_chunks/{Media-Bic_vfSX.js → Media-kK7BnZGr.js} +4 -4
- package/dist-vue/_chunks/Media-kK7BnZGr.js.map +1 -0
- package/dist-vue/_chunks/{PkChatbot-woRkjgP5.js → PkChatbot-B9RSkQmJ.js} +7 -7
- package/dist-vue/_chunks/{PkChatbot-woRkjgP5.js.map → PkChatbot-B9RSkQmJ.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotFeedbackForm-D-lx1URv.js → PkChatbotFeedbackForm-lj9CHdhn.js} +3 -3
- package/dist-vue/_chunks/{PkChatbotFeedbackForm-D-lx1URv.js.map → PkChatbotFeedbackForm-lj9CHdhn.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotInput-LHE0HZ9z.js → PkChatbotInput-C5QSmt21.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotInput-LHE0HZ9z.js.map → PkChatbotInput-C5QSmt21.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotMessages-BxTeEm3j.js → PkChatbotMessages-DOeUT6YL.js} +7 -7
- package/dist-vue/_chunks/PkChatbotMessages-DOeUT6YL.js.map +1 -0
- package/dist-vue/_chunks/{PkChatbotViewChat-BoEfZeco.js → PkChatbotViewChat-C2FuDayB.js} +6 -6
- package/dist-vue/_chunks/{PkChatbotViewChat-BoEfZeco.js.map → PkChatbotViewChat-C2FuDayB.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotViewConversations-DvVc1arX.js → PkChatbotViewConversations-2xc0o-fO.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotViewConversations-DvVc1arX.js.map → PkChatbotViewConversations-2xc0o-fO.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotViewProfile-Dev_6pki.js → PkChatbotViewProfile-CoT1JnMk.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotViewProfile-Dev_6pki.js.map → PkChatbotViewProfile-CoT1JnMk.js.map} +1 -1
- package/dist-vue/_chunks/{PkStreamingMarkdown-B4gnJ4hk.js → PkStreamingMarkdown-BAhC3uGK.js} +20 -20
- package/dist-vue/_chunks/PkStreamingMarkdown-BAhC3uGK.js.map +1 -0
- package/dist-vue/_chunks/{PkToolShowArtifact-EvbUZSOf.js → PkToolShowArtifact-RzrDPcEQ.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowArtifact-EvbUZSOf.js.map → PkToolShowArtifact-RzrDPcEQ.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowContactForm-CsDOqSJK.js → PkToolShowContactForm-5H4jfq1F.js} +4 -4
- package/dist-vue/_chunks/{PkToolShowContactForm-CsDOqSJK.js.map → PkToolShowContactForm-5H4jfq1F.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowSources-ZtXFkIHt.js → PkToolShowSources-Dv0uuvqS.js} +5 -4
- package/dist-vue/_chunks/PkToolShowSources-Dv0uuvqS.js.map +1 -0
- package/dist-vue/_chunks/{ZodError-Ca0wCsGp.js → ZodError-C_est8SY.js} +2 -2
- package/dist-vue/_chunks/{ZodError-Ca0wCsGp.js.map → ZodError-C_est8SY.js.map} +1 -1
- package/dist-vue/_chunks/{createChatbotApiClient-YJegM3ni.js → createChatbotApiClient-CvDRMmDa.js} +3 -3
- package/dist-vue/_chunks/createChatbotApiClient-CvDRMmDa.js.map +1 -0
- package/dist-vue/_chunks/{index.es-CrPSzhoZ.js → index.es-Dk_HaA08.js} +4 -4
- package/dist-vue/_chunks/{index.es-CrPSzhoZ.js.map → index.es-Dk_HaA08.js.map} +1 -1
- package/dist-vue/_chunks/{schemas-sa2dDEGb.js → schemas-Clx4oKCB.js} +1309 -945
- package/dist-vue/_chunks/schemas-Clx4oKCB.js.map +1 -0
- package/dist-vue/_chunks/{useChatbotStore-DGL81KJa.js → useChatbotStore-DMDbzuub.js} +1061 -1000
- package/dist-vue/_chunks/useChatbotStore-DMDbzuub.js.map +1 -0
- package/dist-vue/api.js +1 -1
- package/dist-vue/apps/web-component/src/composables/useChatbotAgent.d.ts +6 -6
- package/dist-vue/apps/web-component/src/composables/useChatbotAuth.d.ts +8 -8
- package/dist-vue/apps/web-component/src/lib.d.ts +29 -0
- package/dist-vue/apps/web-component/src/main.d.ts +0 -0
- package/dist-vue/apps/web-component/src/modules/applicationInsights.d.ts +38 -0
- package/dist-vue/composables.js +2 -2
- package/dist-vue/index.js +2852 -2876
- package/dist-vue/index.js.map +1 -1
- package/dist-vue/packages/auth/src/add-member-to-organization.d.ts +5 -0
- package/dist-vue/packages/auth/src/anonymous-reauth-plugin.d.ts +11 -0
- package/dist-vue/packages/auth/src/external-auth-plugin.d.ts +2 -0
- package/dist-vue/packages/auth/src/index.d.ts +3477 -8
- package/dist-vue/packages/auth/src/media-helpers.d.ts +13 -0
- package/dist-vue/packages/auth/src/organization-auto-join.d.ts +1 -0
- package/dist-vue/packages/components/src/PkEditorMarkdown.d.ts +1 -1
- package/dist-vue/packages/components/src/PkEditorRepeater.d.ts +2 -2
- package/dist-vue/packages/components/src/PkEditorWyswyg.d.ts +1 -1
- package/dist-vue/packages/components/src/PkFieldset.d.ts +3 -3
- package/dist-vue/packages/components/src/composables/index.d.ts +3 -0
- package/dist-vue/packages/components/src/composables/useChatbotError.d.ts +11 -11
- package/dist-vue/packages/composable/src/constants.d.ts +5 -0
- package/dist-vue/packages/composable/src/useDialog.d.ts +3 -3
- package/dist-vue/packages/composable/src/useSettingsStore.d.ts +4 -5
- package/dist-vue/packages/models/src/schema/Agent.d.ts +27 -27
- package/dist-vue/packages/models/src/schema/AgentEndpoint.d.ts +1 -1
- package/dist-vue/packages/models/src/schema/Document.d.ts +2 -0
- package/dist-vue/packages/models/src/schema/ReasoningChat.d.ts +5 -5
- package/dist-vue/packages/models/src/schema/SubAgent.d.ts +10 -10
- package/dist-vue/packages/models/src/schema/constants.d.ts +3 -1
- package/package.json +4 -4
- package/dist/_chunks/PkStreamingMarkdown-orhL2kzD.js.map +0 -1
- package/dist/_chunks/PkToolShowContactForm-6C4uWDtf.js +0 -1103
- package/dist/_chunks/PkToolShowContactForm-6C4uWDtf.js.map +0 -1
- package/dist/_chunks/PkToolShowSources-BQo5DRwt.js.map +0 -1
- package/dist/_chunks/dist-DtF6poRc.js.map +0 -1
- package/dist/_chunks/schemas-Bp3a8tYV.js.map +0 -1
- package/dist/_chunks/vue.runtime.esm-bundler-BmggS4HU.js.map +0 -1
- package/dist-vue/_chunks/Media-Bic_vfSX.js.map +0 -1
- package/dist-vue/_chunks/PkChatbotMessages-BxTeEm3j.js.map +0 -1
- package/dist-vue/_chunks/PkStreamingMarkdown-B4gnJ4hk.js.map +0 -1
- package/dist-vue/_chunks/PkToolShowSources-ZtXFkIHt.js.map +0 -1
- package/dist-vue/_chunks/createChatbotApiClient-YJegM3ni.js.map +0 -1
- package/dist-vue/_chunks/schemas-sa2dDEGb.js.map +0 -1
- package/dist-vue/_chunks/useChatbotStore-DGL81KJa.js.map +0 -1
- package/dist-vue/packages/composable/src/chatbot/useChatbotStore.d.ts +0 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "./vue.runtime.esm-bundler-
|
|
1
|
+
import "./vue.runtime.esm-bundler-Dq29dQrz.js";
|
|
2
2
|
//#region ../../packages/utils/src/cdn-css.ts
|
|
3
3
|
var e = /* @__PURE__ */ new WeakMap();
|
|
4
4
|
function t(t, n) {
|
|
@@ -152,4 +152,4 @@ function T(e) {
|
|
|
152
152
|
//#endregion
|
|
153
153
|
export { v as a, _ as c, f as d, d as f, t as g, n as h, b as i, p as l, i as m, w as n, h as o, r as p, T as r, g as s, S as t, m as u };
|
|
154
154
|
|
|
155
|
-
//# sourceMappingURL=src-
|
|
155
|
+
//# sourceMappingURL=src-BfoQF6Z3.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"src-C_wl-KYN.js","names":[],"sources":["../../../../packages/utils/src/cdn-css.ts","../../../../packages/utils/src/device-context.ts","../../../../packages/utils/src/logger.ts","../../../../packages/utils/src/markdown.ts","../../../../packages/utils/src/message.ts","../../../../packages/utils/src/text.ts","../../../../packages/utils/src/url-validation.ts"],"sourcesContent":["const loaded = new WeakMap<Node, Set<string>>()\n\n/**\n * Injects a CDN stylesheet `<link>` once per URL per root.\n * When a `ShadowRoot` is passed, the link is appended there so that\n * custom-element (Shadow DOM) encapsulation is respected.\n * Falls back to `document.head` for regular DOM usage.\n */\nexport function loadCdnCss(href: string, root?: ShadowRoot) {\n const target: Node = root ?? document.head\n let set = loaded.get(target)\n if (!set) {\n set = new Set()\n loaded.set(target, set)\n }\n if (set.has(href)) {\n return\n }\n const link = document.createElement('link')\n link.rel = 'stylesheet'\n link.href = href\n target.appendChild(link)\n set.add(href)\n}\n\n/** Returns the `ShadowRoot` ancestor of `el`, or `undefined` in regular DOM. */\nexport function getShadowRoot(el?: Element | null): ShadowRoot | undefined {\n const root = el?.getRootNode?.()\n return root instanceof ShadowRoot ? root : undefined\n}\n","interface NetworkInformation {\n type?: string\n effectiveType?: string\n downlink?: number\n rtt?: number\n saveData?: boolean\n}\n\ninterface NavigatorUAData {\n platform?: string\n}\n\n/**\n * Collects client-side device context information useful for chatbot interactions.\n * No additional permissions are required — all values are available by default in the browser.\n */\nexport function collectDeviceContext() {\n const connection = (\n navigator as Navigator & { connection?: NetworkInformation }\n ).connection\n\n const uaData = (\n navigator as Navigator & { userAgentData?: NavigatorUAData }\n ).userAgentData\n\n return {\n dateTime: new Date().toISOString(),\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n language: navigator.language,\n languages: [...navigator.languages],\n url: window.location.href,\n pathname: window.location.pathname,\n pageTitle: document.title,\n referrer: document.referrer || undefined,\n screenWidth: screen.width,\n screenHeight: screen.height,\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n devicePixelRatio: window.devicePixelRatio,\n maxTouchPoints: navigator.maxTouchPoints,\n hardwareConcurrency: navigator.hardwareConcurrency,\n deviceMemory: (navigator as Navigator & { deviceMemory?: number })\n .deviceMemory,\n platform: uaData?.platform,\n connectionType: connection?.type,\n connectionEffectiveType: connection?.effectiveType,\n connectionDownlink: connection?.downlink,\n connectionRtt: connection?.rtt,\n saveData: connection?.saveData,\n darkMode: window.matchMedia('(prefers-color-scheme: dark)').matches,\n reducedMotion: window.matchMedia('(prefers-reduced-motion: reduce)')\n .matches,\n historyLength: window.history.length,\n }\n}\n\nexport type GeolocationData = {\n geolocationLatitude: number\n geolocationLongitude: number\n geolocationAccuracy?: number\n geolocationCity?: string\n}\n\nexport type ReverseGeocodeFn = (\n lat: number,\n lon: number,\n) => Promise<string | undefined>\n\n/**\n * Collects geolocation data if the user has already granted permission.\n * Uses the Permissions API to avoid triggering a browser prompt.\n * Returns null if permission is not granted or geolocation is unavailable.\n * @param reverseGeocode - optional callback to resolve city name from coordinates (e.g. via backend proxy)\n */\nexport async function collectGeolocation(\n reverseGeocode?: ReverseGeocodeFn,\n): Promise<GeolocationData | null> {\n if (!navigator.geolocation || !navigator.permissions) {\n return null\n }\n\n try {\n const permission = await navigator.permissions.query({\n name: 'geolocation',\n })\n if (permission.state !== 'granted') {\n return null\n }\n\n const position = await new Promise<GeolocationPosition>(\n (resolve, reject) => {\n navigator.geolocation.getCurrentPosition(resolve, reject, {\n timeout: 10_000,\n })\n },\n )\n\n const { latitude, longitude, accuracy } = position.coords\n const city = reverseGeocode\n ? await reverseGeocode(latitude, longitude).catch(() => undefined)\n : undefined\n\n return {\n geolocationLatitude: latitude,\n geolocationLongitude: longitude,\n geolocationAccuracy: accuracy,\n geolocationCity: city,\n }\n } catch {\n return null\n }\n}\n","import type { Ref } from 'vue'\n\ntype ExceptionTracker = (\n error: Error,\n properties?: Record<string, string>,\n) => void\n\nlet _exceptionTracker: ExceptionTracker | undefined\n\n/**\n * Registers a callback invoked by error/warn/logError/logWarn to track exceptions\n * (e.g. Application Insights trackException).\n */\nexport const setExceptionTracker = (tracker: ExceptionTracker) => {\n _exceptionTracker = tracker\n}\n\nconst extractError = (params: unknown[]): Error => {\n const found = params.find((p): p is Error => p instanceof Error)\n if (found) {\n return found\n }\n return new Error(params.map(String).join(' '))\n}\n\nconst formatParam = (param: unknown): string => {\n if (param instanceof Error) {\n return param.stack ?? param.message\n }\n return String(param)\n}\n\nconst formatParams = (params: unknown[]): string => {\n return params.map(formatParam).join(' ')\n}\n\nconst isServerSide = typeof window === 'undefined'\nconst isLocal = isServerSide\n ? process?.env?.VITE_LOCAL === 'true'\n : import.meta.env?.VITE_LOCAL\n\nconst isLoggingEnabled = isLocal || isServerSide\n\nexport const log = (...params: unknown[]) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.log(...params)\n }\n}\n\nexport const error = (...params: unknown[]) => {\n _exceptionTracker?.(extractError(params))\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.error(formatParams(params))\n }\n}\nexport const info = (...params: unknown[]) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.info(...params)\n }\n}\nexport const debug = (...params: unknown[]) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.debug(...params)\n }\n}\nexport const warn = (...params: unknown[]) => {\n _exceptionTracker?.(extractError(params))\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.warn(formatParams(params))\n }\n}\nexport const assert = (condition: boolean | undefined, message: string) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.assert(condition, message)\n }\n}\nexport const clear = () => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.clear()\n }\n}\nexport const table = (table: unknown) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.table(table)\n }\n}\nexport const group = (name: string) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.group(name)\n }\n}\nexport const groupEnd = () => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.groupEnd()\n }\n}\nexport const time = (name: string) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.time(name)\n }\n}\nexport const timeEnd = (name: string) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.timeEnd(name)\n }\n}\nexport const timeLog = (name: string, ...params: unknown[]) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.timeLog(name, ...params)\n }\n}\n\nexport const logger = {\n log,\n error,\n info,\n debug,\n warn,\n assert,\n clear,\n table,\n group,\n groupEnd,\n time,\n timeEnd,\n timeLog,\n}\n\nexport const useErrorsLogger = (errors: Ref<Error | null | undefined>[]) => {\n // Vue is an optional runtime dependency for the backend build.\n // Lazily import it only when running in a browser/Vue environment.\n if (typeof window === 'undefined') {\n return\n }\n\n void import('vue').then(({ watch }) => {\n errors.forEach((error) => {\n watch(error, (value) => {\n logger.error(value)\n })\n })\n })\n}\n","export const stripMarkdown = (text?: string | null) => {\n if (!text) {\n return undefined\n }\n return text\n .replace(/!\\[.*?\\]\\(.*?\\)/g, '') // images\n .replace(/\\[([^\\]]+)\\]\\(.*?\\)/g, '$1') // links\n .replace(/`{1,3}[^`]*`{1,3}/g, '') // inline code / code blocks\n .replace(/#{1,6}\\s/g, '') // headings\n .replace(/(\\*{1,3}|_{1,3})(.*?)\\1/g, '$2') // bold / italic\n .replace(/~~(.*?)~~/g, '$1') // strikethrough\n .replace(/^\\s*[-*+>]\\s+/gm, '') // lists and blockquotes\n .replace(/\\n+/g, ' ') // newlines\n .trim()\n}\n","import type { UIMessage } from 'ai'\n\ntype MessagePart = UIMessage['parts'][number]\n\nexport function isTextPart(\n part: MessagePart | null | undefined,\n): part is Extract<MessagePart, { type: 'text' }> {\n if (!part) return false\n return part.type === 'text'\n}\n\nexport function isToolPart(\n part: MessagePart | null | undefined,\n): part is Extract<MessagePart, { type: `tool-${string}` }> {\n if (!part) return false\n return part.type.startsWith('tool-')\n}\n\nexport function getToolPartName(part: MessagePart): string {\n if (!isToolPart(part)) return ''\n return part.type.slice('tool-'.length)\n}\n\nexport function isFilePart(\n part: MessagePart | null | undefined,\n): part is Extract<MessagePart, { type: 'file' }> {\n if (!part) return false\n return part.type === 'file'\n}\n\nexport function isReasoningPart(\n part: MessagePart | null | undefined,\n): part is Extract<MessagePart, { type: 'reasoning' }> {\n if (!part) return false\n return part.type === 'reasoning'\n}\n\nexport function hasPartText(\n part: MessagePart | null | undefined,\n): part is Extract<MessagePart, { text: string }> {\n if (!part) return false\n if (isTextPart(part)) {\n return true\n }\n return (\n 'text' in part &&\n part.text !== undefined &&\n part.text !== null &&\n part.text !== ''\n )\n}\n\nexport function hasTextPart(message?: UIMessage): boolean {\n if (!message) return false\n return message.parts.some((part) => isTextPart(part))\n}\n\nexport function getTextPart(\n message: UIMessage | null | undefined,\n): string | undefined {\n if (!message) return undefined\n const textPart = message.parts.find((part) => isTextPart(part))\n return textPart?.text\n}\n\nexport function getMessageText(message: UIMessage | null | undefined): string {\n if (!message) return ''\n return message.parts\n .filter((p): p is Extract<MessagePart, { type: 'text' }> =>\n isTextPart(p),\n )\n .map((p) => p.text)\n .join('')\n}\n","export const removeAccents = (str: string) =>\n str.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '')\n\nexport const toCamelCase = <T extends string>(str?: string): T => {\n if (!str) return '' as unknown as T\n return removeAccents(str)\n .replace(/[^a-zA-Z0-9]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))\n .replace(/^(.)/, (match) => match.toLowerCase()) as unknown as T\n}\n\nexport const fromCamelCase = (str?: string): string => {\n if (!str) return ''\n return str.replace(/([a-z])([A-Z])/g, '$1 $2')\n}\n\nexport const toPascalCase = <T extends string>(str?: string): T => {\n if (!str) return '' as unknown as T\n return removeAccents(str)\n .replace(/[^a-zA-Z0-9]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))\n .replace(/^(.)/, (match) => match.toUpperCase()) as unknown as T\n}\n\nexport const toKebabCase = <T extends string>(str?: string): T => {\n if (!str) return '' as unknown as T\n return removeAccents(str)\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .replace(/[^a-zA-Z0-9]+/g, '-')\n .toLowerCase() as unknown as T\n}\n\nexport const fromKebabCase = (str?: string): string => {\n if (!str) return ''\n return str.replace(/-/g, ' ')\n}\n\nexport const toSnakeCase = <T extends string>(str?: string): T => {\n if (!str) return '' as unknown as T\n return removeAccents(str)\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .replace(/[^a-zA-Z0-9]+/g, '_')\n .toLowerCase() as unknown as T\n}\n\nexport const capitalizeFirstLetter = (str?: string) => {\n if (!str) return ''\n return str.charAt(0).toUpperCase() + str.slice(1)\n}\n\nexport const lowercaseFirstLetter = (str?: string) => {\n if (!str) return ''\n return str.charAt(0).toLowerCase() + str.slice(1)\n}\n","/**\n * Check if URL points to an HTML page based on extension and content-type\n * @param url - The URL to check\n * @param contentType - Optional content-type header from response\n * @returns true if URL appears to be HTML, false otherwise\n */\nexport function isHtmlUrl(url: string, contentType?: string): boolean {\n // Check content-type if available\n if (contentType) {\n return contentType.includes('text/html')\n }\n\n // Check URL extension\n let urlObj: URL\n try {\n urlObj = new URL(url)\n } catch {\n return false\n }\n const pathname = urlObj.pathname.toLowerCase()\n\n // Exclude common non-HTML extensions\n const nonHtmlExtensions = [\n '.pdf',\n '.doc',\n '.docx',\n '.xls',\n '.xlsx',\n '.ppt',\n '.pptx',\n '.zip',\n '.rar',\n '.tar',\n '.gz',\n '.jpg',\n '.jpeg',\n '.png',\n '.gif',\n '.svg',\n '.webp',\n '.mp4',\n '.avi',\n '.mov',\n '.mp3',\n '.wav',\n '.css',\n '.js',\n '.json',\n '.xml',\n '.txt',\n ]\n\n return !nonHtmlExtensions.some((ext) => pathname.endsWith(ext))\n}\n\n/**\n * Checks if a URL has an initial slash\n * @param url - The URL string to check\n * @returns true if URL has an initial slash, false otherwise\n */\nexport function hasInitialSlash(url: string): boolean {\n return url.startsWith('/')\n}\n\n/**\n * Adds an initial slash to a URL if it doesn't already have one\n * @param url - The URL string to modify\n * @returns The URL string with an initial slash\n */\nexport function addInitialSlash(url: string): string {\n return hasInitialSlash(url) ? url : `/${url}`\n}\n\n/**\n * Checks if a URL has a trailing slash\n * @param url - The URL string to check\n * @returns true if URL has a trailing slash, false otherwise\n */\nexport function hasTrailingSlash(url: string): boolean {\n return url.endsWith('/')\n}\n\n/**\n * Checks whether a URL belongs to the same site as the current page.\n * Relative URLs and malformed URLs are treated as same-site.\n * Comparison is based on hostname only, so http and https variants of\n * the same domain are considered the same site.\n * @param url - The URL to check\n * @returns true if the URL is same-site or relative/malformed, false otherwise\n */\nexport function isSameSite(url: string): boolean {\n try {\n const target = new URL(url, window.location.origin)\n return target.hostname === window.location.hostname\n } catch {\n return true\n }\n}\n\n/**\n * Removes the trailing slash from a URL if it exists\n * @param url - The URL string to modify\n * @returns The URL string without a trailing slash\n */\nexport function removeTrailingSlash(url: string): string {\n return hasTrailingSlash(url) ? url.slice(0, -1) : url\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"src-BfoQF6Z3.js","names":[],"sources":["../../../../packages/utils/src/cdn-css.ts","../../../../packages/utils/src/device-context.ts","../../../../packages/utils/src/logger.ts","../../../../packages/utils/src/markdown.ts","../../../../packages/utils/src/message.ts","../../../../packages/utils/src/text.ts","../../../../packages/utils/src/url-validation.ts"],"sourcesContent":["const loaded = new WeakMap<Node, Set<string>>()\n\n/**\n * Injects a CDN stylesheet `<link>` once per URL per root.\n * When a `ShadowRoot` is passed, the link is appended there so that\n * custom-element (Shadow DOM) encapsulation is respected.\n * Falls back to `document.head` for regular DOM usage.\n */\nexport function loadCdnCss(href: string, root?: ShadowRoot) {\n const target: Node = root ?? document.head\n let set = loaded.get(target)\n if (!set) {\n set = new Set()\n loaded.set(target, set)\n }\n if (set.has(href)) {\n return\n }\n const link = document.createElement('link')\n link.rel = 'stylesheet'\n link.href = href\n target.appendChild(link)\n set.add(href)\n}\n\n/** Returns the `ShadowRoot` ancestor of `el`, or `undefined` in regular DOM. */\nexport function getShadowRoot(el?: Element | null): ShadowRoot | undefined {\n const root = el?.getRootNode?.()\n return root instanceof ShadowRoot ? root : undefined\n}\n","interface NetworkInformation {\n type?: string\n effectiveType?: string\n downlink?: number\n rtt?: number\n saveData?: boolean\n}\n\ninterface NavigatorUAData {\n platform?: string\n}\n\n/**\n * Collects client-side device context information useful for chatbot interactions.\n * No additional permissions are required — all values are available by default in the browser.\n */\nexport function collectDeviceContext() {\n const connection = (\n navigator as Navigator & { connection?: NetworkInformation }\n ).connection\n\n const uaData = (\n navigator as Navigator & { userAgentData?: NavigatorUAData }\n ).userAgentData\n\n return {\n dateTime: new Date().toISOString(),\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n language: navigator.language,\n languages: [...navigator.languages],\n url: window.location.href,\n pathname: window.location.pathname,\n pageTitle: document.title,\n referrer: document.referrer || undefined,\n screenWidth: screen.width,\n screenHeight: screen.height,\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n devicePixelRatio: window.devicePixelRatio,\n maxTouchPoints: navigator.maxTouchPoints,\n hardwareConcurrency: navigator.hardwareConcurrency,\n deviceMemory: (navigator as Navigator & { deviceMemory?: number })\n .deviceMemory,\n platform: uaData?.platform,\n connectionType: connection?.type,\n connectionEffectiveType: connection?.effectiveType,\n connectionDownlink: connection?.downlink,\n connectionRtt: connection?.rtt,\n saveData: connection?.saveData,\n darkMode: window.matchMedia('(prefers-color-scheme: dark)').matches,\n reducedMotion: window.matchMedia('(prefers-reduced-motion: reduce)')\n .matches,\n historyLength: window.history.length,\n }\n}\n\nexport type GeolocationData = {\n geolocationLatitude: number\n geolocationLongitude: number\n geolocationAccuracy?: number\n geolocationCity?: string\n}\n\nexport type ReverseGeocodeFn = (\n lat: number,\n lon: number,\n) => Promise<string | undefined>\n\n/**\n * Collects geolocation data if the user has already granted permission.\n * Uses the Permissions API to avoid triggering a browser prompt.\n * Returns null if permission is not granted or geolocation is unavailable.\n * @param reverseGeocode - optional callback to resolve city name from coordinates (e.g. via backend proxy)\n */\nexport async function collectGeolocation(\n reverseGeocode?: ReverseGeocodeFn,\n): Promise<GeolocationData | null> {\n if (!navigator.geolocation || !navigator.permissions) {\n return null\n }\n\n try {\n const permission = await navigator.permissions.query({\n name: 'geolocation',\n })\n if (permission.state !== 'granted') {\n return null\n }\n\n const position = await new Promise<GeolocationPosition>(\n (resolve, reject) => {\n navigator.geolocation.getCurrentPosition(resolve, reject, {\n timeout: 10_000,\n })\n },\n )\n\n const { latitude, longitude, accuracy } = position.coords\n const city = reverseGeocode\n ? await reverseGeocode(latitude, longitude).catch(() => undefined)\n : undefined\n\n return {\n geolocationLatitude: latitude,\n geolocationLongitude: longitude,\n geolocationAccuracy: accuracy,\n geolocationCity: city,\n }\n } catch {\n return null\n }\n}\n","import type { Ref } from 'vue'\n\ntype ExceptionTracker = (\n error: Error,\n properties?: Record<string, string>,\n) => void\n\nlet _exceptionTracker: ExceptionTracker | undefined\n\n/**\n * Registers a callback invoked by error/warn/logError/logWarn to track exceptions\n * (e.g. Application Insights trackException).\n */\nexport const setExceptionTracker = (tracker: ExceptionTracker) => {\n _exceptionTracker = tracker\n}\n\nconst extractError = (params: unknown[]): Error => {\n const found = params.find((p): p is Error => p instanceof Error)\n if (found) {\n return found\n }\n return new Error(params.map(String).join(' '))\n}\n\nconst formatParam = (param: unknown): string => {\n if (param instanceof Error) {\n return param.stack ?? param.message\n }\n return String(param)\n}\n\nconst formatParams = (params: unknown[]): string => {\n return params.map(formatParam).join(' ')\n}\n\nconst isServerSide = typeof window === 'undefined'\nconst isLocal = isServerSide\n ? process?.env?.VITE_LOCAL === 'true'\n : import.meta.env?.VITE_LOCAL\n\nconst isLoggingEnabled = isLocal || isServerSide\n\nexport const log = (...params: unknown[]) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.log(...params)\n }\n}\n\nexport const error = (...params: unknown[]) => {\n _exceptionTracker?.(extractError(params))\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.error(formatParams(params))\n }\n}\nexport const info = (...params: unknown[]) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.info(...params)\n }\n}\nexport const debug = (...params: unknown[]) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.debug(...params)\n }\n}\nexport const warn = (...params: unknown[]) => {\n _exceptionTracker?.(extractError(params))\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.warn(formatParams(params))\n }\n}\nexport const assert = (condition: boolean | undefined, message: string) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.assert(condition, message)\n }\n}\nexport const clear = () => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.clear()\n }\n}\nexport const table = (table: unknown) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.table(table)\n }\n}\nexport const group = (name: string) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.group(name)\n }\n}\nexport const groupEnd = () => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.groupEnd()\n }\n}\nexport const time = (name: string) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.time(name)\n }\n}\nexport const timeEnd = (name: string) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.timeEnd(name)\n }\n}\nexport const timeLog = (name: string, ...params: unknown[]) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.timeLog(name, ...params)\n }\n}\n\nexport const logger = {\n log,\n error,\n info,\n debug,\n warn,\n assert,\n clear,\n table,\n group,\n groupEnd,\n time,\n timeEnd,\n timeLog,\n}\n\nexport const useErrorsLogger = (errors: Ref<Error | null | undefined>[]) => {\n // Vue is an optional runtime dependency for the backend build.\n // Lazily import it only when running in a browser/Vue environment.\n if (typeof window === 'undefined') {\n return\n }\n\n void import('vue').then(({ watch }) => {\n errors.forEach((error) => {\n watch(error, (value) => {\n logger.error(value)\n })\n })\n })\n}\n","export const stripMarkdown = (text?: string | null) => {\n if (!text) {\n return undefined\n }\n return text\n .replace(/!\\[.*?\\]\\(.*?\\)/g, '') // images\n .replace(/\\[([^\\]]+)\\]\\(.*?\\)/g, '$1') // links\n .replace(/`{1,3}[^`]*`{1,3}/g, '') // inline code / code blocks\n .replace(/#{1,6}\\s/g, '') // headings\n .replace(/(\\*{1,3}|_{1,3})(.*?)\\1/g, '$2') // bold / italic\n .replace(/~~(.*?)~~/g, '$1') // strikethrough\n .replace(/^\\s*[-*+>]\\s+/gm, '') // lists and blockquotes\n .replace(/\\n+/g, ' ') // newlines\n .trim()\n}\n","import type { UIMessage } from 'ai'\n\ntype MessagePart = UIMessage['parts'][number]\n\nexport function isTextPart(\n part: MessagePart | null | undefined,\n): part is Extract<MessagePart, { type: 'text' }> {\n if (!part) return false\n return part.type === 'text'\n}\n\nexport function isToolPart(\n part: MessagePart | null | undefined,\n): part is Extract<MessagePart, { type: `tool-${string}` }> {\n if (!part) return false\n return part.type.startsWith('tool-')\n}\n\nexport function getToolPartName(part: MessagePart): string {\n if (!isToolPart(part)) return ''\n return part.type.slice('tool-'.length)\n}\n\nexport function isFilePart(\n part: MessagePart | null | undefined,\n): part is Extract<MessagePart, { type: 'file' }> {\n if (!part) return false\n return part.type === 'file'\n}\n\nexport function isReasoningPart(\n part: MessagePart | null | undefined,\n): part is Extract<MessagePart, { type: 'reasoning' }> {\n if (!part) return false\n return part.type === 'reasoning'\n}\n\nexport function hasPartText(\n part: MessagePart | null | undefined,\n): part is Extract<MessagePart, { text: string }> {\n if (!part) return false\n if (isTextPart(part)) {\n return true\n }\n return (\n 'text' in part &&\n part.text !== undefined &&\n part.text !== null &&\n part.text !== ''\n )\n}\n\nexport function hasTextPart(message?: UIMessage): boolean {\n if (!message) return false\n return message.parts.some((part) => isTextPart(part))\n}\n\nexport function getTextPart(\n message: UIMessage | null | undefined,\n): string | undefined {\n if (!message) return undefined\n const textPart = message.parts.find((part) => isTextPart(part))\n return textPart?.text\n}\n\nexport function getMessageText(message: UIMessage | null | undefined): string {\n if (!message) return ''\n return message.parts\n .filter((p): p is Extract<MessagePart, { type: 'text' }> =>\n isTextPart(p),\n )\n .map((p) => p.text)\n .join('')\n}\n","export const removeAccents = (str: string) =>\n str.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '')\n\nexport const toCamelCase = <T extends string>(str?: string): T => {\n if (!str) return '' as unknown as T\n return removeAccents(str)\n .replace(/[^a-zA-Z0-9]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))\n .replace(/^(.)/, (match) => match.toLowerCase()) as unknown as T\n}\n\nexport const fromCamelCase = (str?: string): string => {\n if (!str) return ''\n return str.replace(/([a-z])([A-Z])/g, '$1 $2')\n}\n\nexport const toPascalCase = <T extends string>(str?: string): T => {\n if (!str) return '' as unknown as T\n return removeAccents(str)\n .replace(/[^a-zA-Z0-9]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))\n .replace(/^(.)/, (match) => match.toUpperCase()) as unknown as T\n}\n\nexport const toKebabCase = <T extends string>(str?: string): T => {\n if (!str) return '' as unknown as T\n return removeAccents(str)\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .replace(/[^a-zA-Z0-9]+/g, '-')\n .toLowerCase() as unknown as T\n}\n\nexport const fromKebabCase = (str?: string): string => {\n if (!str) return ''\n return str.replace(/-/g, ' ')\n}\n\nexport const toSnakeCase = <T extends string>(str?: string): T => {\n if (!str) return '' as unknown as T\n return removeAccents(str)\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .replace(/[^a-zA-Z0-9]+/g, '_')\n .toLowerCase() as unknown as T\n}\n\nexport const capitalizeFirstLetter = (str?: string) => {\n if (!str) return ''\n return str.charAt(0).toUpperCase() + str.slice(1)\n}\n\nexport const lowercaseFirstLetter = (str?: string) => {\n if (!str) return ''\n return str.charAt(0).toLowerCase() + str.slice(1)\n}\n","/**\n * Check if URL points to an HTML page based on extension and content-type\n * @param url - The URL to check\n * @param contentType - Optional content-type header from response\n * @returns true if URL appears to be HTML, false otherwise\n */\nexport function isHtmlUrl(url: string, contentType?: string): boolean {\n // Check content-type if available\n if (contentType) {\n return contentType.includes('text/html')\n }\n\n // Check URL extension\n let urlObj: URL\n try {\n urlObj = new URL(url)\n } catch {\n return false\n }\n const pathname = urlObj.pathname.toLowerCase()\n\n // Exclude common non-HTML extensions\n const nonHtmlExtensions = [\n '.pdf',\n '.doc',\n '.docx',\n '.xls',\n '.xlsx',\n '.ppt',\n '.pptx',\n '.zip',\n '.rar',\n '.tar',\n '.gz',\n '.jpg',\n '.jpeg',\n '.png',\n '.gif',\n '.svg',\n '.webp',\n '.mp4',\n '.avi',\n '.mov',\n '.mp3',\n '.wav',\n '.css',\n '.js',\n '.json',\n '.xml',\n '.txt',\n ]\n\n return !nonHtmlExtensions.some((ext) => pathname.endsWith(ext))\n}\n\n/**\n * Checks if a URL has an initial slash\n * @param url - The URL string to check\n * @returns true if URL has an initial slash, false otherwise\n */\nexport function hasInitialSlash(url: string): boolean {\n return url.startsWith('/')\n}\n\n/**\n * Adds an initial slash to a URL if it doesn't already have one\n * @param url - The URL string to modify\n * @returns The URL string with an initial slash\n */\nexport function addInitialSlash(url: string): string {\n return hasInitialSlash(url) ? url : `/${url}`\n}\n\n/**\n * Checks if a URL has a trailing slash\n * @param url - The URL string to check\n * @returns true if URL has a trailing slash, false otherwise\n */\nexport function hasTrailingSlash(url: string): boolean {\n return url.endsWith('/')\n}\n\n/**\n * Checks whether a URL belongs to the same site as the current page.\n * Relative URLs and malformed URLs are treated as same-site.\n * Comparison is based on hostname only, so http and https variants of\n * the same domain are considered the same site.\n * @param url - The URL to check\n * @returns true if the URL is same-site or relative/malformed, false otherwise\n */\nexport function isSameSite(url: string): boolean {\n try {\n const target = new URL(url, window.location.origin)\n return target.hostname === window.location.hostname\n } catch {\n return true\n }\n}\n\n/**\n * Removes the trailing slash from a URL if it exists\n * @param url - The URL string to modify\n * @returns The URL string without a trailing slash\n */\nexport function removeTrailingSlash(url: string): string {\n return hasTrailingSlash(url) ? url.slice(0, -1) : url\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { I as e, ft as t, mt as n } from "./vue.runtime.esm-bundler-
|
|
2
|
-
import { g as r } from "./src-
|
|
1
|
+
import { I as e, ft as t, mt as n } from "./vue.runtime.esm-bundler-Dq29dQrz.js";
|
|
2
|
+
import { g as r } from "./src-BfoQF6Z3.js";
|
|
3
3
|
//#region ../../packages/components/src/composables/useLightbox.ts
|
|
4
4
|
var i = "https://cdn.jsdelivr.net/npm/photoswipe@5/dist/photoswipe.css", a = {
|
|
5
5
|
width: 1200,
|
|
@@ -110,4 +110,4 @@ function p() {
|
|
|
110
110
|
//#endregion
|
|
111
111
|
export { o as n, s as t };
|
|
112
112
|
|
|
113
|
-
//# sourceMappingURL=useLightbox-
|
|
113
|
+
//# sourceMappingURL=useLightbox-DL_oVBep.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLightbox-CH1KeVqr.js","names":[],"sources":["../../../../packages/components/src/composables/useLightbox.ts"],"sourcesContent":["import {\n onBeforeUnmount,\n ref,\n shallowRef,\n type Ref,\n type ShallowRef,\n} from 'vue'\nimport type PhotoSwipeLightbox from 'photoswipe/lightbox'\nimport type PhotoSwipe from 'photoswipe'\nimport { loadCdnCss } from 'utils'\n\nconst PHOTOSWIPE_CSS =\n 'https://cdn.jsdelivr.net/npm/photoswipe@5/dist/photoswipe.css'\n\nconst DEFAULT_IMAGE_SIZE = { width: 1200, height: 800 }\n\nexport interface LightboxImage {\n url: string\n caption?: string\n alt?: string\n /** Natural width in px — used by PhotoSwipe for proper sizing. */\n width?: number\n /** Natural height in px — used by PhotoSwipe for proper sizing. */\n height?: number\n}\n\nexport interface LightboxOptions {\n /** Container element whose child anchors are the gallery items */\n gallery: Ref<HTMLElement | undefined>\n /** CSS selector for gallery items inside the container (default: `'a[data-pswp-src]'`) */\n children?: string\n loop?: boolean\n /** Show a download button in the lightbox toolbar */\n downloadable?: boolean\n /** Show an open-in-new-tab button in the lightbox toolbar */\n openInNewTab?: boolean\n}\n\nexport interface UseLightboxReturn {\n lightbox: ShallowRef<PhotoSwipeLightbox | null>\n /** Initialises PhotoSwipe. Call this inside `onMounted`. */\n init: () => Promise<void>\n}\n\n/**\n * Encapsulates PhotoSwipe 5 initialisation, toolbar customisation, and lifecycle cleanup.\n * CSS is injected into `document.head` so the overlay works in both regular DOM and Shadow DOM.\n *\n * Usage:\n * ```ts\n * const { init } = useLightbox({ gallery: galleryRef, downloadable: true })\n * onMounted(init)\n * ```\n */\nexport function useLightbox(options: LightboxOptions): UseLightboxReturn {\n const {\n gallery,\n children = 'a[data-pswp-src]',\n loop = true,\n downloadable = true,\n openInNewTab = true,\n } = options\n\n const lightbox = shallowRef<PhotoSwipeLightbox | null>(null)\n\n const init = async () => {\n if (!gallery.value) {\n return\n }\n\n // PhotoSwipe renders its overlay into document.body, so CSS must be in\n // document.head — not inside a shadow root.\n loadCdnCss(PHOTOSWIPE_CSS)\n injectPhotoSwipeOverrides()\n\n const { default: PhotoSwipeLightbox } =\n await import('photoswipe/lightbox')\n\n lightbox.value = new PhotoSwipeLightbox({\n gallery: gallery.value,\n children,\n pswpModule: () => import('photoswipe'),\n loop,\n arrowPrevSVG:\n '<svg aria-hidden=\"true\" class=\"pswp__icn\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"#ffffff\" d=\"m10.828 12l4.95 4.95l-1.414 1.415L8 12l6.364-6.364l1.414 1.414z\"/></svg>',\n arrowNextSVG:\n '<svg aria-hidden=\"true\" class=\"pswp__icn\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"#ffffff\" d=\"m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z\"/></svg>',\n closeSVG:\n '<svg aria-hidden=\"true\" class=\"pswp__icn\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"#ffffff\" d=\"m12 10.587l4.95-4.95l1.414 1.414l-4.95 4.95l4.95 4.95l-1.415 1.414l-4.95-4.95l-4.949 4.95l-1.414-1.415l4.95-4.95l-4.95-4.95L7.05 5.638z\"/></svg>',\n zoomSVG:\n '<svg aria-hidden=\"true\" class=\"pswp__icn\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g class=\"pswp__icn--zoom-in\"><path fill=\"#ffffff\" d=\"m18.031 16.617l4.283 4.282l-1.415 1.415l-4.282-4.283A8.96 8.96 0 0 1 11 20c-4.968 0-9-4.032-9-9s4.032-9 9-9s9 4.032 9 9a8.96 8.96 0 0 1-1.969 5.617m-2.006-.742A6.98 6.98 0 0 0 18 11c0-3.867-3.133-7-7-7s-7 3.133-7 7s3.133 7 7 7a6.98 6.98 0 0 0 4.875-1.975zM10 10V7h2v3h3v2h-3v3h-2v-3H7v-2z\"/></g><g class=\"pswp__icn--zoom-out\"><path fill=\"#ffffff\" d=\"m18.031 16.617l4.283 4.282l-1.415 1.415l-4.282-4.283A8.96 8.96 0 0 1 11 20c-4.968 0-9-4.032-9-9s4.032-9 9-9s9 4.032 9 9a8.96 8.96 0 0 1-1.969 5.617m-2.006-.742A6.98 6.98 0 0 0 18 11c0-3.867-3.133-7-7-7s-7 3.133-7 7s3.133 7 7 7a6.98 6.98 0 0 0 4.875-1.975zM7 10h8v2H7z\"/></g></svg>',\n })\n\n if (openInNewTab || downloadable) {\n lightbox.value.on('uiRegister', () => {\n const ui = lightbox.value!.pswp?.ui\n if (!ui) {\n return\n }\n\n if (openInNewTab) {\n ui.registerElement({\n name: 'open-in-new-tab-button',\n order: 8,\n isButton: true,\n html: '<svg aria-hidden=\"true\" class=\"pswp__icn\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"#ffffff\" d=\"M10 6v2H5v11h11v-5h2v6a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1zm11-3v8h-2V6.413l-7.793 7.794l-1.414-1.414L17.585 5H13V3z\"/></svg>',\n title: 'Open in new tab',\n onClick: (_, __, pswp) => {\n const url = getCurrentSlideUrl(pswp)\n if (url) {\n window.open(\n url,\n '_blank',\n 'noopener,noreferrer',\n )\n }\n },\n })\n }\n\n if (downloadable) {\n ui.registerElement({\n name: 'download-button',\n order: 9,\n isButton: true,\n html: '<svg aria-hidden=\"true\" class=\"pswp__icn\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"#ffffff\" d=\"M3 19h18v2H3zm10-5.828L19.071 7.1l1.414 1.414L12 17L3.515 8.515L4.929 7.1L11 13.173V2h2z\"/></svg>',\n title: 'Download',\n onClick: (_, __, pswp) => {\n const url = getCurrentSlideUrl(pswp)\n if (url) {\n downloadImage(url)\n }\n },\n })\n }\n })\n }\n\n lightbox.value.init()\n }\n\n onBeforeUnmount(() => {\n lightbox.value?.destroy()\n lightbox.value = null\n })\n\n return { lightbox, init }\n}\n\n// ---------------------------------------------------------------------------\n// Image size preloading\n// ---------------------------------------------------------------------------\n\nexport interface UseImageSizesReturn {\n preload: (\n images: Array<{ url: string; width?: number; height?: number }>,\n ) => void\n getSize: (url: string) => { width: number; height: number }\n}\n\n/**\n * Preloads natural image dimensions so PhotoSwipe can size its slides correctly.\n * When `width`/`height` are already provided they are used as-is;\n * otherwise the image is loaded in the background to read `naturalWidth`/`naturalHeight`.\n */\nexport function useImageSizes(): UseImageSizesReturn {\n const sizes = ref(new Map<string, { width: number; height: number }>())\n\n const preload = (\n images: Array<{ url: string; width?: number; height?: number }>,\n ) => {\n for (const image of images) {\n if (image.width && image.height) {\n sizes.value.set(image.url, {\n width: image.width,\n height: image.height,\n })\n continue\n }\n const img = new Image()\n img.onload = () => {\n sizes.value.set(image.url, {\n width: img.naturalWidth,\n height: img.naturalHeight,\n })\n }\n img.src = image.url\n }\n }\n\n const getSize = (url: string) => sizes.value.get(url) ?? DEFAULT_IMAGE_SIZE\n\n return { preload, getSize }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction getCurrentSlideUrl(pswp: PhotoSwipe): string | undefined {\n return (\n pswp.currSlide?.data?.src ??\n pswp.currSlide?.data?.element\n ?.querySelector('img')\n ?.getAttribute('src') ??\n undefined\n )\n}\n\n/**\n * Triggers a client-side download for an image URL.\n *\n * For backend media URLs (.../media/:file/view), navigates to the\n * corresponding /download endpoint which redirects to an Azure SAS URL\n * with `Content-Disposition: attachment` — no CORS issues.\n *\n * For blob: URLs (in-session uploads), uses the fetch → blob approach.\n *\n * Falls back to opening in a new tab for all other cases.\n */\nfunction downloadImage(url: string): void {\n const downloadUrl = toDownloadUrl(url)\n\n const anchor = document.createElement('a')\n anchor.href = downloadUrl\n anchor.target = '_blank'\n anchor.rel = 'noopener noreferrer'\n // `download` attribute works for same-origin and blob: URLs; for\n // cross-origin it is ignored but the browser still follows Content-Disposition.\n anchor.download = getFilenameFromUrl(url)\n document.body.appendChild(anchor)\n anchor.click()\n document.body.removeChild(anchor)\n}\n\n/**\n * Converts a `/view` media URL to its `/download` counterpart.\n * Leaves blob: and all other URLs untouched.\n */\nfunction toDownloadUrl(url: string): string {\n return url.replace(/\\/view(\\?|$)/, '/download$1')\n}\n\nfunction getFilenameFromUrl(url: string): string {\n try {\n const pathname = new URL(url).pathname\n const name = pathname.split('/').pop()\n return name && name.includes('.') ? name : 'image'\n } catch {\n return 'image'\n }\n}\n\nlet overridesInjected = false\n\n/**\n * Injects a one-time `<style>` into `document.head` that raises\n * PhotoSwipe's z-index above any host UI (e.g. floating chat widgets\n * that use `z-index: 2147483647`).\n */\nfunction injectPhotoSwipeOverrides(): void {\n if (overridesInjected) {\n return\n }\n overridesInjected = true\n const style = document.createElement('style')\n style.textContent = [\n '.pswp { z-index: 2147483647 !important; }',\n '.pswp__icn { width: 20px; height: 20px; }',\n '.pswp__button { width: 40px; height: 40px; }',\n '.pswp__icn--zoom-out { display: none; }',\n '.pswp--zoomed-in .pswp__icn--zoom-in { display: none; }',\n '.pswp--zoomed-in .pswp__icn--zoom-out { display: block; }',\n ].join(' ')\n document.head.appendChild(style)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useLightbox-DL_oVBep.js","names":[],"sources":["../../../../packages/components/src/composables/useLightbox.ts"],"sourcesContent":["import {\n onBeforeUnmount,\n ref,\n shallowRef,\n type Ref,\n type ShallowRef,\n} from 'vue'\nimport type PhotoSwipeLightbox from 'photoswipe/lightbox'\nimport type PhotoSwipe from 'photoswipe'\nimport { loadCdnCss } from 'utils'\n\nconst PHOTOSWIPE_CSS =\n 'https://cdn.jsdelivr.net/npm/photoswipe@5/dist/photoswipe.css'\n\nconst DEFAULT_IMAGE_SIZE = { width: 1200, height: 800 }\n\nexport interface LightboxImage {\n url: string\n caption?: string\n alt?: string\n /** Natural width in px — used by PhotoSwipe for proper sizing. */\n width?: number\n /** Natural height in px — used by PhotoSwipe for proper sizing. */\n height?: number\n}\n\nexport interface LightboxOptions {\n /** Container element whose child anchors are the gallery items */\n gallery: Ref<HTMLElement | undefined>\n /** CSS selector for gallery items inside the container (default: `'a[data-pswp-src]'`) */\n children?: string\n loop?: boolean\n /** Show a download button in the lightbox toolbar */\n downloadable?: boolean\n /** Show an open-in-new-tab button in the lightbox toolbar */\n openInNewTab?: boolean\n}\n\nexport interface UseLightboxReturn {\n lightbox: ShallowRef<PhotoSwipeLightbox | null>\n /** Initialises PhotoSwipe. Call this inside `onMounted`. */\n init: () => Promise<void>\n}\n\n/**\n * Encapsulates PhotoSwipe 5 initialisation, toolbar customisation, and lifecycle cleanup.\n * CSS is injected into `document.head` so the overlay works in both regular DOM and Shadow DOM.\n *\n * Usage:\n * ```ts\n * const { init } = useLightbox({ gallery: galleryRef, downloadable: true })\n * onMounted(init)\n * ```\n */\nexport function useLightbox(options: LightboxOptions): UseLightboxReturn {\n const {\n gallery,\n children = 'a[data-pswp-src]',\n loop = true,\n downloadable = true,\n openInNewTab = true,\n } = options\n\n const lightbox = shallowRef<PhotoSwipeLightbox | null>(null)\n\n const init = async () => {\n if (!gallery.value) {\n return\n }\n\n // PhotoSwipe renders its overlay into document.body, so CSS must be in\n // document.head — not inside a shadow root.\n loadCdnCss(PHOTOSWIPE_CSS)\n injectPhotoSwipeOverrides()\n\n const { default: PhotoSwipeLightbox } =\n await import('photoswipe/lightbox')\n\n lightbox.value = new PhotoSwipeLightbox({\n gallery: gallery.value,\n children,\n pswpModule: () => import('photoswipe'),\n loop,\n arrowPrevSVG:\n '<svg aria-hidden=\"true\" class=\"pswp__icn\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"#ffffff\" d=\"m10.828 12l4.95 4.95l-1.414 1.415L8 12l6.364-6.364l1.414 1.414z\"/></svg>',\n arrowNextSVG:\n '<svg aria-hidden=\"true\" class=\"pswp__icn\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"#ffffff\" d=\"m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z\"/></svg>',\n closeSVG:\n '<svg aria-hidden=\"true\" class=\"pswp__icn\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"#ffffff\" d=\"m12 10.587l4.95-4.95l1.414 1.414l-4.95 4.95l4.95 4.95l-1.415 1.414l-4.95-4.95l-4.949 4.95l-1.414-1.415l4.95-4.95l-4.95-4.95L7.05 5.638z\"/></svg>',\n zoomSVG:\n '<svg aria-hidden=\"true\" class=\"pswp__icn\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g class=\"pswp__icn--zoom-in\"><path fill=\"#ffffff\" d=\"m18.031 16.617l4.283 4.282l-1.415 1.415l-4.282-4.283A8.96 8.96 0 0 1 11 20c-4.968 0-9-4.032-9-9s4.032-9 9-9s9 4.032 9 9a8.96 8.96 0 0 1-1.969 5.617m-2.006-.742A6.98 6.98 0 0 0 18 11c0-3.867-3.133-7-7-7s-7 3.133-7 7s3.133 7 7 7a6.98 6.98 0 0 0 4.875-1.975zM10 10V7h2v3h3v2h-3v3h-2v-3H7v-2z\"/></g><g class=\"pswp__icn--zoom-out\"><path fill=\"#ffffff\" d=\"m18.031 16.617l4.283 4.282l-1.415 1.415l-4.282-4.283A8.96 8.96 0 0 1 11 20c-4.968 0-9-4.032-9-9s4.032-9 9-9s9 4.032 9 9a8.96 8.96 0 0 1-1.969 5.617m-2.006-.742A6.98 6.98 0 0 0 18 11c0-3.867-3.133-7-7-7s-7 3.133-7 7s3.133 7 7 7a6.98 6.98 0 0 0 4.875-1.975zM7 10h8v2H7z\"/></g></svg>',\n })\n\n if (openInNewTab || downloadable) {\n lightbox.value.on('uiRegister', () => {\n const ui = lightbox.value!.pswp?.ui\n if (!ui) {\n return\n }\n\n if (openInNewTab) {\n ui.registerElement({\n name: 'open-in-new-tab-button',\n order: 8,\n isButton: true,\n html: '<svg aria-hidden=\"true\" class=\"pswp__icn\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"#ffffff\" d=\"M10 6v2H5v11h11v-5h2v6a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1zm11-3v8h-2V6.413l-7.793 7.794l-1.414-1.414L17.585 5H13V3z\"/></svg>',\n title: 'Open in new tab',\n onClick: (_, __, pswp) => {\n const url = getCurrentSlideUrl(pswp)\n if (url) {\n window.open(\n url,\n '_blank',\n 'noopener,noreferrer',\n )\n }\n },\n })\n }\n\n if (downloadable) {\n ui.registerElement({\n name: 'download-button',\n order: 9,\n isButton: true,\n html: '<svg aria-hidden=\"true\" class=\"pswp__icn\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"#ffffff\" d=\"M3 19h18v2H3zm10-5.828L19.071 7.1l1.414 1.414L12 17L3.515 8.515L4.929 7.1L11 13.173V2h2z\"/></svg>',\n title: 'Download',\n onClick: (_, __, pswp) => {\n const url = getCurrentSlideUrl(pswp)\n if (url) {\n downloadImage(url)\n }\n },\n })\n }\n })\n }\n\n lightbox.value.init()\n }\n\n onBeforeUnmount(() => {\n lightbox.value?.destroy()\n lightbox.value = null\n })\n\n return { lightbox, init }\n}\n\n// ---------------------------------------------------------------------------\n// Image size preloading\n// ---------------------------------------------------------------------------\n\nexport interface UseImageSizesReturn {\n preload: (\n images: Array<{ url: string; width?: number; height?: number }>,\n ) => void\n getSize: (url: string) => { width: number; height: number }\n}\n\n/**\n * Preloads natural image dimensions so PhotoSwipe can size its slides correctly.\n * When `width`/`height` are already provided they are used as-is;\n * otherwise the image is loaded in the background to read `naturalWidth`/`naturalHeight`.\n */\nexport function useImageSizes(): UseImageSizesReturn {\n const sizes = ref(new Map<string, { width: number; height: number }>())\n\n const preload = (\n images: Array<{ url: string; width?: number; height?: number }>,\n ) => {\n for (const image of images) {\n if (image.width && image.height) {\n sizes.value.set(image.url, {\n width: image.width,\n height: image.height,\n })\n continue\n }\n const img = new Image()\n img.onload = () => {\n sizes.value.set(image.url, {\n width: img.naturalWidth,\n height: img.naturalHeight,\n })\n }\n img.src = image.url\n }\n }\n\n const getSize = (url: string) => sizes.value.get(url) ?? DEFAULT_IMAGE_SIZE\n\n return { preload, getSize }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction getCurrentSlideUrl(pswp: PhotoSwipe): string | undefined {\n return (\n pswp.currSlide?.data?.src ??\n pswp.currSlide?.data?.element\n ?.querySelector('img')\n ?.getAttribute('src') ??\n undefined\n )\n}\n\n/**\n * Triggers a client-side download for an image URL.\n *\n * For backend media URLs (.../media/:file/view), navigates to the\n * corresponding /download endpoint which redirects to an Azure SAS URL\n * with `Content-Disposition: attachment` — no CORS issues.\n *\n * For blob: URLs (in-session uploads), uses the fetch → blob approach.\n *\n * Falls back to opening in a new tab for all other cases.\n */\nfunction downloadImage(url: string): void {\n const downloadUrl = toDownloadUrl(url)\n\n const anchor = document.createElement('a')\n anchor.href = downloadUrl\n anchor.target = '_blank'\n anchor.rel = 'noopener noreferrer'\n // `download` attribute works for same-origin and blob: URLs; for\n // cross-origin it is ignored but the browser still follows Content-Disposition.\n anchor.download = getFilenameFromUrl(url)\n document.body.appendChild(anchor)\n anchor.click()\n document.body.removeChild(anchor)\n}\n\n/**\n * Converts a `/view` media URL to its `/download` counterpart.\n * Leaves blob: and all other URLs untouched.\n */\nfunction toDownloadUrl(url: string): string {\n return url.replace(/\\/view(\\?|$)/, '/download$1')\n}\n\nfunction getFilenameFromUrl(url: string): string {\n try {\n const pathname = new URL(url).pathname\n const name = pathname.split('/').pop()\n return name && name.includes('.') ? name : 'image'\n } catch {\n return 'image'\n }\n}\n\nlet overridesInjected = false\n\n/**\n * Injects a one-time `<style>` into `document.head` that raises\n * PhotoSwipe's z-index above any host UI (e.g. floating chat widgets\n * that use `z-index: 2147483647`).\n */\nfunction injectPhotoSwipeOverrides(): void {\n if (overridesInjected) {\n return\n }\n overridesInjected = true\n const style = document.createElement('style')\n style.textContent = [\n '.pswp { z-index: 2147483647 !important; }',\n '.pswp__icn { width: 20px; height: 20px; }',\n '.pswp__button { width: 40px; height: 40px; }',\n '.pswp__icn--zoom-out { display: none; }',\n '.pswp--zoomed-in .pswp__icn--zoom-in { display: none; }',\n '.pswp--zoomed-in .pswp__icn--zoom-out { display: block; }',\n ].join(' ')\n document.head.appendChild(style)\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { D as e, E as t, L as n, R as r, Z as i, _ as a, ft as o, g as s, h as c, j as l, k as u, lt as d, mt as f, nt as p, rt as m, st as h, t as g, w as _ } from "./vue.runtime.esm-bundler-
|
|
1
|
+
import { D as e, E as t, L as n, R as r, Z as i, _ as a, ft as o, g as s, h as c, j as l, k as u, lt as d, mt as f, nt as p, rt as m, st as h, t as g, w as _ } from "./vue.runtime.esm-bundler-Dq29dQrz.js";
|
|
2
2
|
//#region ../../node_modules/.pnpm/@intlify+shared@11.4.0/node_modules/@intlify/shared/dist/shared.mjs
|
|
3
3
|
function v(e, t) {
|
|
4
4
|
typeof console < "u" && (console.warn("[intlify] " + e), t && console.warn(t.stack));
|
|
@@ -1470,7 +1470,7 @@ function jn(e, t, n, r) {
|
|
|
1470
1470
|
}
|
|
1471
1471
|
Ve();
|
|
1472
1472
|
//#endregion
|
|
1473
|
-
//#region ../../node_modules/.pnpm/vue-i18n@11.4.0_vue@3.5.
|
|
1473
|
+
//#region ../../node_modules/.pnpm/vue-i18n@11.4.0_vue@3.5.34_typescript@6.0.3_/node_modules/vue-i18n/dist/vue-i18n.mjs
|
|
1474
1474
|
var Mn = "11.4.0";
|
|
1475
1475
|
function Nn() {
|
|
1476
1476
|
typeof __INTLIFY_PROD_DEVTOOLS__ != "boolean" && (A().__INTLIFY_PROD_DEVTOOLS__ = !1);
|
|
@@ -2128,4 +2128,4 @@ if (Nn(), Ht(pt), Wt(It), Kt(Ct), __INTLIFY_PROD_DEVTOOLS__) {
|
|
|
2128
2128
|
//#endregion
|
|
2129
2129
|
export { fr as n, dr as t };
|
|
2130
2130
|
|
|
2131
|
-
//# sourceMappingURL=vue-i18n-
|
|
2131
|
+
//# sourceMappingURL=vue-i18n-DAH6nDTN.js.map
|