@eka-care/medassist-widget-embed 0.2.116-0 → 0.2.116-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -38
- package/dist/eka-agents.html +4 -4
- package/dist/iframe.js +1 -1
- package/dist/index.d.ts +23 -36
- package/dist/index.js +22 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -54,7 +54,7 @@ The widget appears as a floating button; clicking it loads and opens the chat.
|
|
|
54
54
|
|
|
55
55
|
### Optional attributes
|
|
56
56
|
|
|
57
|
-
- **`icon-url`** – Custom icon URL for the
|
|
57
|
+
- **`icon-url`** – Custom icon URL for the launcher button. When omitted, the launcher uses the agent's configured icon (`theme.icon_img` from agent config) and is only shown once that config has loaded — there is no built-in default icon
|
|
58
58
|
- **`title`** – Widget title
|
|
59
59
|
- **`base-url`** – Base URL for API/agent config
|
|
60
60
|
- **`display-mode`** – `"widget"` (floating button), `"full"` (inline full view) or `"side_panel"` (docked panel, see [Side panel mode](#side-panel-mode))
|
|
@@ -231,42 +231,6 @@ window.addEventListener("eka-medassist:side-panel-push", (e) => {
|
|
|
231
231
|
});
|
|
232
232
|
```
|
|
233
233
|
|
|
234
|
-
## Client tools
|
|
235
|
-
|
|
236
|
-
Give the agent functions that run **in your page** (read or edit your app's state). The page declares them; the backend tells the LLM they exist; when the LLM calls one, the SDK runs your `run` and sends the result back. Declarations follow MCP's `Tool` shape; only `name / description / inputSchema / outputSchema / annotations` leave the page — `run` never does.
|
|
237
|
-
|
|
238
|
-
```js
|
|
239
|
-
EkaMedAssist.init({
|
|
240
|
-
agentId: "<agent-id>",
|
|
241
|
-
tools: [
|
|
242
|
-
{
|
|
243
|
-
name: "read_note",
|
|
244
|
-
description: "Read the note the user has open.",
|
|
245
|
-
inputSchema: { type: "object", properties: { section_keys: { type: "array", items: { type: "string" } } } },
|
|
246
|
-
annotations: { title: "Reading the note", readOnlyHint: true },
|
|
247
|
-
run: async (input, ctx) => {
|
|
248
|
-
ctx.progress({ message: "Collecting sections…" });
|
|
249
|
-
return { sections: getSections(input.section_keys) }; // plain object → structured result
|
|
250
|
-
},
|
|
251
|
-
},
|
|
252
|
-
],
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
// Replace the list at any time (before or after the widget opens):
|
|
256
|
-
EkaMedAssist.registerTools([...]);
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
Rules:
|
|
260
|
-
|
|
261
|
-
- `run` must read live page state at call time — tools are registered once and reused.
|
|
262
|
-
- Return a plain object (becomes `structuredContent`) or a full MCP `CallToolResult`.
|
|
263
|
-
- Report a failure the model should handle by throwing an `Error` with `code` (string) and optional `data` (object); it becomes `{ isError: true, structuredContent: { code, message, ...data } }`.
|
|
264
|
-
- `annotations.title` is the label shown while the tool runs; `ctx.progress({ message })` updates it live.
|
|
265
|
-
- `ctx.signal` aborts on timeout (`timeoutMs`, default 30 s), server cancel, or session end.
|
|
266
|
-
- Not supported in the iframe embed (functions cannot cross frames).
|
|
267
|
-
|
|
268
|
-
Protocol details: `docs/client-tools-plan.md` in the repo.
|
|
269
|
-
|
|
270
234
|
## How it works
|
|
271
235
|
|
|
272
236
|
1. **Initial load** – The script registers the custom element `<eka-medassist-widget>`.
|
|
@@ -292,7 +256,7 @@ widget-embed/
|
|
|
292
256
|
│ ├── iframe.js # Optional iframe helper
|
|
293
257
|
│ └── iframe.html # Optional iframe template
|
|
294
258
|
├── assets/
|
|
295
|
-
│ └── bot-icon.svg #
|
|
259
|
+
│ └── bot-icon.svg # Sample icon for the test pages (not a runtime default)
|
|
296
260
|
└── README.md
|
|
297
261
|
```
|
|
298
262
|
|
package/dist/eka-agents.html
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
CORS mode — the browser would download it twice. -->
|
|
19
19
|
<link
|
|
20
20
|
rel="modulepreload"
|
|
21
|
-
href="https://cdn.jsdelivr.net/npm/@eka-care/medassist-widget@0.1.138-
|
|
21
|
+
href="https://cdn.jsdelivr.net/npm/@eka-care/medassist-widget@0.1.138-dev.1/dist/medassist-widget.js"
|
|
22
22
|
fetchpriority="high"
|
|
23
23
|
crossorigin
|
|
24
24
|
/>
|
|
@@ -27,14 +27,14 @@
|
|
|
27
27
|
<link
|
|
28
28
|
rel="preload"
|
|
29
29
|
as="style"
|
|
30
|
-
href="https://cdn.jsdelivr.net/npm/@eka-care/medassist-widget@0.1.138-
|
|
30
|
+
href="https://cdn.jsdelivr.net/npm/@eka-care/medassist-widget@0.1.138-dev.1/dist/medassist-widget.css"
|
|
31
31
|
onload="this.rel='stylesheet'"
|
|
32
32
|
crossorigin
|
|
33
33
|
/>
|
|
34
34
|
<noscript>
|
|
35
35
|
<link
|
|
36
36
|
rel="stylesheet"
|
|
37
|
-
href="https://cdn.jsdelivr.net/npm/@eka-care/medassist-widget@0.1.138-
|
|
37
|
+
href="https://cdn.jsdelivr.net/npm/@eka-care/medassist-widget@0.1.138-dev.1/dist/medassist-widget.css"
|
|
38
38
|
/>
|
|
39
39
|
</noscript>
|
|
40
40
|
|
|
@@ -149,7 +149,7 @@
|
|
|
149
149
|
window.renderMedAssist would never be set. -->
|
|
150
150
|
<script
|
|
151
151
|
type="module"
|
|
152
|
-
src="https://cdn.jsdelivr.net/npm/@eka-care/medassist-widget@0.1.138-
|
|
152
|
+
src="https://cdn.jsdelivr.net/npm/@eka-care/medassist-widget@0.1.138-dev.1/dist/medassist-widget.js"
|
|
153
153
|
onload="init()"
|
|
154
154
|
fetchpriority="high"
|
|
155
155
|
crossorigin
|
package/dist/iframe.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";(function(){const $=()=>{if(typeof document=="undefined")return null;const{currentScript:e}=document;if(e instanceof HTMLScriptElement)return e;const t=document.getElementsByTagName("script");return t.length?t[t.length-1]:null},C=e=>{if(e==="production"||e==="development"||e==="staging")return e};function z(e){if(!e)return;const t=e.mode==="dark"?"white":e.mode==="light"?"black":void 0;return{...e.background&&{background:e.background},...e.background_img&&{backgroundImage:e.background_img},...e.accent&&{primary:e.accent},...t&&{textColor:t},...e.mode&&{mode:e.mode},...e.header_tinted!==void 0&&{headerTinted:e.header_tinted},...e.title_img&&{titleImg:e.title_img},...e.tagline&&{tagline:e.tagline},...e.consent_content&&{consentContent:e.consent_content},...e.feature!==void 0&&{feature:e.feature}}}function S(e){if(!(!e||typeof document=="undefined"))try{const t=document.createElement("link");t.rel="preload",t.as="image",t.href=e,document.head.appendChild(t)}catch{const t=new Image;t.src=e}}async function F(e,t,r){var n;try{return await h(),await((n=window.fetchAgentConfig)===null||n===void 0?void 0:n.call(window,{agentId:t,serverUrl:e,environment:r,channel:"web"}))}catch{return}}const U="https://cdn.jsdelivr.net/npm/@eka-care/medassist-widget@0.1.138-
|
|
1
|
+
"use strict";(function(){const $=()=>{if(typeof document=="undefined")return null;const{currentScript:e}=document;if(e instanceof HTMLScriptElement)return e;const t=document.getElementsByTagName("script");return t.length?t[t.length-1]:null},C=e=>{if(e==="production"||e==="development"||e==="staging")return e};function z(e){if(!e)return;const t=e.mode==="dark"?"white":e.mode==="light"?"black":void 0;return{...e.background&&{background:e.background},...e.background_img&&{backgroundImage:e.background_img},...e.accent&&{primary:e.accent},...t&&{textColor:t},...e.mode&&{mode:e.mode},...e.header_tinted!==void 0&&{headerTinted:e.header_tinted},...e.title_img&&{titleImg:e.title_img},...e.tagline&&{tagline:e.tagline},...e.consent_content&&{consentContent:e.consent_content},...e.feature!==void 0&&{feature:e.feature}}}function S(e){if(!(!e||typeof document=="undefined"))try{const t=document.createElement("link");t.rel="preload",t.as="image",t.href=e,document.head.appendChild(t)}catch{const t=new Image;t.src=e}}async function F(e,t,r){var n;try{return await h(),await((n=window.fetchAgentConfig)===null||n===void 0?void 0:n.call(window,{agentId:t,serverUrl:e,environment:r,channel:"web"}))}catch{return}}const U="https://cdn.jsdelivr.net/npm/@eka-care/medassist-widget@0.1.138-dev.1/dist/",s=$(),b=(()=>{if(!s)return"";try{return new URL(".",s.src||window.location.href).href}catch{return""}})(),u=(()=>{if(!s)return U;const e=s.dataset.widgetAssets;if(e==="local")return`${b}src/`;if(e&&e.length>0)try{return new URL(e,b).href}catch{return e.endsWith("/")?e:`${e}/`}return U})(),a=`${u}medassist-widget.js`,g=`${u}medassist-widget.css`;let m=null,f=null;const i=new URLSearchParams(typeof window!="undefined"?window.location.search:""),A=i.get("agentId"),w=i.get("baseUrl")||"https://matrix.eka.care/reloaded";if(typeof document!="undefined"&&document.head){try{const e=new URL(u).origin,t=new URL(w).origin,r=document.createElement("link");if(r.rel="preconnect",r.href=e,r.crossOrigin="anonymous",document.head.appendChild(r),e!==t){const c=document.createElement("link");c.rel="preconnect",c.href=t,c.crossOrigin="anonymous",document.head.appendChild(c)}const n=document.createElement("link");n.rel="modulepreload",n.href=a,document.head.appendChild(n);const d=document.createElement("link");d.rel="preload",d.as="style",d.href=g,document.head.appendChild(d)}catch{}M(),h()}const L=A&&w?F(w,A,C(i.get("environment"))):Promise.resolve(void 0);if(typeof document!="undefined"&&document.head){const e=i.get("theme");if(e)try{const t=JSON.parse(e);t.backgroundImage&&S(t.backgroundImage)}catch{}L.then(t=>{var r;const n=(r=t==null?void 0:t.theme)===null||r===void 0?void 0:r.background_img;n&&S(n)})}const I=async()=>{var e,t,r,n,d,c,p;const P=i.get("agentId");if(!P){console.error("Agent ID is required in URL parameters");return}let v=i.get("title")||"Medi Clinic",y=i.get("iconUrl")||void 0;const x=i.get("context"),G=i.get("baseUrl")||"https://matrix.eka.care/reloaded",O=i.get("auth-token")||void 0;let k=i.get("resize")==="true"?!0:void 0;const J=(e=C(i.get("environment")))!==null&&e!==void 0?e:"production",_=i.get("connectivity"),N=_==="http_stream"||_==="socket"?_:void 0,E=i.get("theme")?(()=>{try{return JSON.parse(i.get("theme")||"{}")}catch{return}})():void 0,q=document.getElementById("root")||document.body;try{const[,,o]=await Promise.all([M(),h(),L]);if(!(window!=null&&window.renderMedAssist)||typeof(window==null?void 0:window.renderMedAssist)!="function")throw new Error("renderMedAssist is not available on window");let l,W,R,B,D=!1;o&&(v=(t=o==null?void 0:o.name)!==null&&t!==void 0?t:v,y=(n=(r=o==null?void 0:o.theme)===null||r===void 0?void 0:r.icon_img)!==null&&n!==void 0?n:y,l=z((d=o==null?void 0:o.theme)!==null&&d!==void 0?d:void 0),W=o==null?void 0:o.allowed,R=o==null?void 0:o.connectivity,B=o==null?void 0:o.initial_message,D=(p=(c=o==null?void 0:o.theme)===null||c===void 0?void 0:c.hide_watermark)!==null&&p!==void 0?p:!1,k=k||(o==null?void 0:o.resize)||void 0);const H={title:v,iconUrl:y,environment:J,connectionType:R||N||"socket",onClose:()=>{window.parent!==window&&window.parent.postMessage({type:"WIDGET_CLOSE"},"*")},context:x?JSON.parse(x):void 0,baseUrl:G,displayMode:"full",allowed:W,showCloseButton:!1,resize:k,initialMessage:B,hideWatermark:D,...O&&{authToken:O},theme:{...l!=null?l:{},...E!=null?E:{}}};window.renderMedAssist(q,P,H)}catch(o){throw console.error("Failed to initialize MedAssist widget",o),o}};async function M(){document.querySelector("link[data-medassist-style='true']")||(f||(f=new Promise((t,r)=>{const n=document.createElement("link");n.rel="stylesheet",n.href=g,n.setAttribute("data-medassist-style","true"),n.onload=()=>{t("")},n.onerror=()=>{r(new Error(`Failed to load ${g}`))},document.head.appendChild(n)})),await f)}function h(){return m||(m=new Promise((e,t)=>{const r=document.querySelector(`script[src="${a}"]`);if(r){if(r.dataset.loaded==="true"){e();return}r.addEventListener("load",()=>e()),r.addEventListener("error",d=>t(d.error||new Error("Unknown script loading error")));return}const n=document.createElement("script");n.src=a,n.type="module",n.async=!0,n.dataset.widget="medassist",n.onload=()=>{n.dataset.loaded="true",e()},n.onerror=d=>{if(d instanceof ErrorEvent&&d.error){t(d.error);return}t(new Error(`Failed to load ${a}`))},document.head.appendChild(n)})),m}if(typeof document!="undefined")if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",I);else try{I()}catch(e){console.error("Failed to initialize MedAssist widget",e)}})();
|
package/dist/index.d.ts
CHANGED
|
@@ -59,38 +59,7 @@ type AgentConfig = {
|
|
|
59
59
|
/** Client-side flag set when the user clicks "Don't show again" on the feedback modal. */
|
|
60
60
|
feedback_hidden?: boolean;
|
|
61
61
|
};
|
|
62
|
-
/**
|
|
63
|
-
* Host-page function the LLM may call (MCP `Tool` declaration + `run`).
|
|
64
|
-
* Declared structurally — the loader is built without a bundler and cannot
|
|
65
|
-
* import @synapse/core. Kept in memory only, never serialised to an attribute.
|
|
66
|
-
*/
|
|
67
|
-
type MedAssistClientTool = {
|
|
68
|
-
name: string;
|
|
69
|
-
description: string;
|
|
70
|
-
inputSchema: Record<string, unknown>;
|
|
71
|
-
outputSchema?: Record<string, unknown>;
|
|
72
|
-
annotations?: {
|
|
73
|
-
title?: string;
|
|
74
|
-
readOnlyHint?: boolean;
|
|
75
|
-
destructiveHint?: boolean;
|
|
76
|
-
idempotentHint?: boolean;
|
|
77
|
-
};
|
|
78
|
-
run: (input: Record<string, unknown>, ctx: {
|
|
79
|
-
requestId: string | number;
|
|
80
|
-
messageId?: string;
|
|
81
|
-
signal: AbortSignal;
|
|
82
|
-
progress: (update: {
|
|
83
|
-
message: string;
|
|
84
|
-
progress?: number;
|
|
85
|
-
total?: number;
|
|
86
|
-
}) => void;
|
|
87
|
-
}) => unknown;
|
|
88
|
-
parse?: (input: unknown) => Record<string, unknown>;
|
|
89
|
-
timeoutMs?: number;
|
|
90
|
-
};
|
|
91
62
|
type MedAssistInitConfig = {
|
|
92
|
-
/** Client tools; replace later with `EkaMedAssist.registerTools()`. */
|
|
93
|
-
tools?: MedAssistClientTool[];
|
|
94
63
|
/** Partner JWT/JWE — the only host-supplied credential; absent -> guest. */
|
|
95
64
|
authToken?: string;
|
|
96
65
|
agentId?: string;
|
|
@@ -226,8 +195,6 @@ type SidePanelPushDetail = {
|
|
|
226
195
|
interface EkaMedAssistWindow extends Window {
|
|
227
196
|
EkaMedAssist?: {
|
|
228
197
|
init: (config: MedAssistInitConfig) => void;
|
|
229
|
-
/** Replace the client tools — before or after the widget renders. */
|
|
230
|
-
registerTools: (tools: MedAssistClientTool[]) => void;
|
|
231
198
|
onClose?: () => void;
|
|
232
199
|
/**
|
|
233
200
|
* Side-panel push mode only. Called with `true` when the panel opens and
|
|
@@ -240,8 +207,6 @@ interface EkaMedAssistWindow extends Window {
|
|
|
240
207
|
};
|
|
241
208
|
__ekaMedAssistConfig__?: MedAssistInitConfig;
|
|
242
209
|
renderMedAssist?: (container: HTMLElement, agentId: string, config: MedAssistInitConfig) => ReactRoot;
|
|
243
|
-
/** Exposed by the widget bundle once loaded; swaps tools in the running SDK. */
|
|
244
|
-
registerMedAssistTools?: (tools: MedAssistClientTool[]) => void;
|
|
245
210
|
}
|
|
246
211
|
declare const globalMedAssistConfig: MedAssistInitConfig;
|
|
247
212
|
declare const getWidgetElement: () => HTMLElement | null;
|
|
@@ -278,7 +243,6 @@ declare let widgetCssTextPromise: Promise<string> | null;
|
|
|
278
243
|
/** Start fetching widget CSS (shared promise). Used for preload and by loadWidgetCss. */
|
|
279
244
|
declare function getWidgetCssTextPromise(): Promise<string>;
|
|
280
245
|
declare class MedAssistWidgetLoader extends HTMLElement {
|
|
281
|
-
private defaultIconUrl;
|
|
282
246
|
private widgetLoaded;
|
|
283
247
|
private displayMode;
|
|
284
248
|
private hostPushStyleEl;
|
|
@@ -374,6 +338,29 @@ declare class MedAssistWidgetLoader extends HTMLElement {
|
|
|
374
338
|
private showNudgePopup;
|
|
375
339
|
private dismissNudgePopup;
|
|
376
340
|
private applyCustomLauncherStyles;
|
|
341
|
+
/** Agent id from init() or the attribute — the same precedence as everywhere else in this loader. */
|
|
342
|
+
private getAgentId;
|
|
343
|
+
/** Bumped on every renderLauncher() call so an older, still-awaiting resolution never overwrites a newer one. */
|
|
344
|
+
private launcherRenderSeq;
|
|
345
|
+
/**
|
|
346
|
+
* Render the launcher skeleton now and reveal it once its icon is known:
|
|
347
|
+
* 1. host-supplied `icon-url` (attribute or init({ iconUrl })) → shown now;
|
|
348
|
+
* 2. otherwise agent-config `theme.icon_img` — a cached copy shows at once
|
|
349
|
+
* and is refreshed at idle; with no cache the launcher stays hidden
|
|
350
|
+
* until the fetch resolves.
|
|
351
|
+
* There is deliberately no built-in fallback icon, so a host never sees a
|
|
352
|
+
* generic icon flash before their own appears. If neither source yields an
|
|
353
|
+
* icon the launcher is still revealed (the chat must stay reachable), just
|
|
354
|
+
* without an image.
|
|
355
|
+
*/
|
|
356
|
+
private renderLauncher;
|
|
357
|
+
/** Set (or clear) the launcher image and reveal the launcher. */
|
|
358
|
+
private setLauncherIcon;
|
|
359
|
+
/**
|
|
360
|
+
* Render the launcher skeleton (idempotent). The launcher starts `pending`
|
|
361
|
+
* (not displayed) and is revealed by setLauncherIcon() once renderLauncher()
|
|
362
|
+
* has decided which icon it carries — see that method for the order.
|
|
363
|
+
*/
|
|
377
364
|
renderButton(): void;
|
|
378
365
|
initializeFullMode(): void;
|
|
379
366
|
loadAndRender(): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"use strict";const getCurrentScript=()=>{if(typeof document=="undefined")return console.error("document is not defined"),null;const{currentScript:e}=document;if(e instanceof HTMLScriptElement)return e;const t=Array.from(document.getElementsByTagName("script")),i=t.find(s=>s.hasAttribute("data-widget-assets"));if(i)return i;const n=t.filter(s=>/(^|\/)index\.js(\?.*)?$/.test(s.src));return n.length?n[n.length-1]:t.length?t[t.length-1]:null},getEnvironment=e=>{if(e==="production"||e==="development"||e==="staging")return e},scriptEl=getCurrentScript(),DEFAULT_WIDGET_ASSET_BASE=(()=>{var e;return!((e=scriptEl==null?void 0:scriptEl.src)===null||e===void 0)&&e.includes("@dev"),"https://cdn.jsdelivr.net/npm/@eka-care/medassist-widget@0.1.138-0/dist/"})();var FeedbackTypeEnum;(function(e){e.DEFAULT="default",e.NPS="nps"})(FeedbackTypeEnum||(FeedbackTypeEnum={}));function mapAgentConfigThemeToWidgetTheme(e){if(!e)return;const t=e.mode==="dark"?"white":e.mode==="light"?"black":void 0;return{...e.background_img&&{backgroundImage:e.background_img},...e.accent&&{primary:e.accent},...t&&{textColor:t},...e.mode&&{mode:e.mode},...e.header_tinted!==void 0&&{headerTinted:e.header_tinted},...e.title_img&&{titleImg:e.title_img},...e.tagline&&{tagline:e.tagline},...e.hide_watermark&&{hideWatermark:e.hide_watermark},...e.explicit_disclaimer&&{explicitDisclaimer:e.explicit_disclaimer},...e.consent_content&&{consentContent:e.consent_content},...e.upfront_consent&&{upfrontConsent:e.upfront_consent},...e.feature!==void 0&&{feature:e.feature}}}function preloadImage(e){if(!(!e||typeof document=="undefined"))try{const t=document.createElement("link");t.rel="preload",t.as="image",t.href=e,document.head.appendChild(t)}catch{const t=new Image;t.src=e}}function channelFromDisplayMode(e){return e==="full"?"web":e==="side_panel"?"side_panel":"widget"}function normalizeDisplayMode(e){return e==="full"?"full":e==="side_panel"?"side_panel":"widget"}const NUDGE_STORAGE_KEY="eka-medassist-nudges",AGENT_CONFIG_CACHE_KEY="eka-medassist-agent-config";function readAgentConfigCache(e){try{const t=localStorage.getItem(AGENT_CONFIG_CACHE_KEY);return(t?JSON.parse(t):{})[e]}catch{return}}function writeAgentConfigCache(e,t){try{const i=localStorage.getItem(AGENT_CONFIG_CACHE_KEY),n=i?JSON.parse(i):{};n[e]={...n[e]||{},...t},localStorage.setItem(AGENT_CONFIG_CACHE_KEY,JSON.stringify(n))}catch{}}function getNudgeStore(){try{const e=localStorage.getItem(NUDGE_STORAGE_KEY);return e?JSON.parse(e):{}}catch{return{}}}function setNudgeStore(e){try{localStorage.setItem(NUDGE_STORAGE_KEY,JSON.stringify(e))}catch{}}function normalizePath(e){let t=e.replace(/\/+$/,"");return t.startsWith("/")||(t="/"+t),t||"/"}function getNudgePathCandidates(e){const t=e.split("/").filter(Boolean),i=[];for(let n=t.length;n>=0;n--)i.push(n===0?"/":"/"+t.slice(0,n).join("/"));return i}function findCachedNudgeForCandidates(e,t,i){const s=getNudgeStore()[e];if(!s)return null;const o=t.host,d=s[o];if(!d)return null;for(const r of i){if(d[r]!==void 0)return{domain:o,path:r,data:d[r]};const a=r==="/"?"/*":r+"/*";if(d[a]!==void 0)return{domain:o,path:a,data:d[a]}}return null}function findFreshCachedNudge(e,t,i){const n=findCachedNudgeForCandidates(e,t,i);if(!n)return null;const s=Math.floor(Date.now()/1e3);return n.data.expiry<=s?(clearNudgeForPath(e,n.domain,n.path),null):n}function clearNudgeForPath(e,t,i){const n=getNudgeStore(),s=n[e];!s||!s[t]||(delete s[t][i],setNudgeStore(n))}function storeNudgeResponse(e,t,i){var n,s,o,d;const r=(n=t==null?void 0:t.url_pattern)===null||n===void 0?void 0:n.domain,a=(s=t==null?void 0:t.url_pattern)===null||s===void 0?void 0:s.path;if(!(!((o=t.nudges)===null||o===void 0)&&o.length)||!t.expiry||!r||!a)return;const c=getNudgeStore();c[e]||(c[e]={}),c[e][r]||(c[e][r]={});const h={nudges:t.nudges,expiry:t.expiry,delay:(d=t.delay)!==null&&d!==void 0?d:5};c[e][r][a]=h,i&&i!==a&&(c[e][r][i]=h),setNudgeStore(c)}const NUDGE_COOKIE_PREFIX="eka-nudge";function setNudgeCookie(e,t){const i=new Date(Date.now()+864e5).toUTCString();document.cookie=`${NUDGE_COOKIE_PREFIX}-${e}=${t}; expires=${i}; path=/; SameSite=Lax`}function getNudgeCookie(e){const t=document.cookie.split(";").map(n=>n.trim()).find(n=>n.startsWith(`${NUDGE_COOKIE_PREFIX}-${e}=`));if(!t)return null;const i=t.split("=")[1];return i==="open"||i==="closed"?i:null}const WIDGET_STORE_KEY_PREFIX="med-assist-store-";function readPersistedSessToken(e){var t,i;try{const n=sessionStorage.getItem(`${WIDGET_STORE_KEY_PREFIX}${e}`),s=n?(i=(t=JSON.parse(n))===null||t===void 0?void 0:t.state)===null||i===void 0?void 0:i.sessToken:void 0;return typeof s=="string"&&s?s:void 0}catch{return}}async function fetchNudgeData(e,t,i,n="widget"){const s=`${i}/med-assist/user-nudge`,o=[];typeof document!="undefined"&&document.querySelectorAll("meta").forEach(d=>{var r,a,c;const h=(r=d.getAttribute("name"))!==null&&r!==void 0?r:void 0,f=(a=d.getAttribute("property"))!==null&&a!==void 0?a:void 0,p=(c=d.getAttribute("content"))!==null&&c!==void 0?c:void 0;(h||f)&&o.push({name:h,property:f,content:p})});try{const d=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json","x-agent-id":e,"x-channel":n,referer:typeof window!="undefined"?window.location.href:"",Authorization:`Bearer ${t}`},body:JSON.stringify({meta_tags:o,url:typeof window!="undefined"?window.location.href:""})});return d.ok?await d.json():void 0}catch{return}}const SIDE_PANEL_PUSH_EVENT="eka-medassist:side-panel-push",globalMedAssistConfig={},getWidgetElement=()=>typeof document=="undefined"?null:document.querySelector("eka-medassist-widget");if(typeof window!="undefined"){const e=window;e.__ekaMedAssistConfig__=globalMedAssistConfig,e.EkaMedAssist={registerTools(t){var i;globalMedAssistConfig.tools=t,(i=e.registerMedAssistTools)===null||i===void 0||i.call(e,t)},init(t){var i,n,s,o;Object.assign(globalMedAssistConfig,t),t.tools&&((i=e.registerMedAssistTools)===null||i===void 0||i.call(e,t.tools));const d=getWidgetElement();if(d){if(t.agentId&&d.setAttribute("agent-id",t.agentId),t.authToken&&d.setAttribute("auth-token",t.authToken),t.title&&d.setAttribute("title",t.title),t.iconUrl&&d.setAttribute("icon-url",t.iconUrl),t.baseUrl&&d.setAttribute("base-url",t.baseUrl),t.resize!==void 0&&d.setAttribute("resize",String(t.resize)),(t.displayMode==="full"||t.displayMode==="widget"||t.displayMode==="side_panel")&&d.setAttribute("display-mode",t.displayMode),t.sidePanelMode&&d.setAttribute("side-panel-mode",t.sidePanelMode),t.sidePanelWidth!==void 0&&d.setAttribute("side-panel-width",String(t.sidePanelWidth)),t.side&&d.setAttribute("side",t.side),t.context)try{d.setAttribute("context",JSON.stringify(t.context))}catch{console.warn("Failed to stringify context passed to init")}typeof t.customLauncherStyles=="string"&&d.setAttribute("custom-launcher-styles",t.customLauncherStyles),t.redirectUrl&&d.setAttribute("redirect-url",t.redirectUrl),!((n=t.theme)===null||n===void 0)&&n.backgroundImage&&preloadImage(t.theme.backgroundImage),(o=(s=d).openFromBridge)===null||o===void 0||o.call(s)}}}}const scriptBaseUrl=(()=>{if(!scriptEl)return"";try{return new URL(".",scriptEl.src||window.location.href).href}catch{return""}})(),widgetAssetBaseUrl=(()=>{if(!scriptEl)return DEFAULT_WIDGET_ASSET_BASE;const e=scriptEl.dataset.widgetAssets;if(e==="local")return`${scriptBaseUrl}src/`;if(e&&e.length>0)try{return new URL(e,scriptBaseUrl).href}catch{return e.endsWith("/")?e:`${e}/`}return DEFAULT_WIDGET_ASSET_BASE})(),WIDGET_JS_URL=`${widgetAssetBaseUrl}medassist-widget.js`,WIDGET_CSS_URL=`${widgetAssetBaseUrl}medassist-widget.css`;let widgetModulePromise=null,widgetCssTextPromise=null;function getWidgetCssTextPromise(){return widgetCssTextPromise||(widgetCssTextPromise=fetch(WIDGET_CSS_URL).then(e=>{if(!e.ok)throw new Error(`Unable to fetch widget styles from ${WIDGET_CSS_URL}`);return e.text()})),widgetCssTextPromise}class MedAssistWidgetLoader extends HTMLElement{setLauncherState(t){var i;const n=(i=this.shadowRoot)===null||i===void 0?void 0:i.getElementById("medassist-open-btn");n&&(n.classList.toggle("loading",t==="loading"),n.classList.toggle("hidden",t==="open"),t==="loading"?n.setAttribute("aria-busy","true"):n.removeAttribute("aria-busy"))}getChannel(){const t=this.getAttribute("display-mode");if(t)return channelFromDisplayMode(t);const i=typeof window!="undefined"?window.__ekaMedAssistConfig__:void 0;return channelFromDisplayMode(i==null?void 0:i.displayMode)}getAgentConfig(){var t;if(!this.agentConfigPromise){const i=(typeof window!="undefined"?window.__ekaMedAssistConfig__:void 0)||{},n=i.baseUrl||this.getAttribute("base-url")||"https://matrix.eka.care/reloaded",s=i.agentId||this.getAttribute("agent-id")||"";if(!s)return Promise.resolve(void 0);const o=(t=getEnvironment(this.getAttribute("environment")))!==null&&t!==void 0?t:"production";this.agentConfigPromise=this.loadWidgetModule().then(d=>{var r;return(r=d.fetchAgentConfig)===null||r===void 0?void 0:r.call(d,{agentId:s,serverUrl:n,environment:o,channel:this.getChannel()})}).catch(()=>{this.agentConfigPromise=null})}return this.agentConfigPromise}constructor(){super(),this.hostPushStyleEl=null,this.hostPushState=null,this.reactRoot=null,this.agentConfigPromise=null,this.loading=!1,this.authPrefetchPromise=null,this.attachShadow({mode:"open"}),this.defaultIconUrl="https://cdn.eka.care/bot-icon.svg",this.widgetLoaded=!1,this.displayMode=normalizeDisplayMode(this.getAttribute("display-mode")),this.setupAuthExpirationListener()}static get observedAttributes(){return["icon-url","display-mode","custom-launcher-styles","redirect-url","side-panel-mode","side-panel-width","side"]}connectedCallback(){this.displayMode==="full"?(this.initializeFullMode(),this.loadAndRender().catch(t=>{console.error("Failed to load MedAssist widget in full mode",t)})):(this.renderButton(),this.scheduleIdle(()=>{this.preloadWidgetAssets(),this.prefetchAuthTokens(),this.initNudge()}))}disconnectedCallback(){var t,i,n,s,o;(t=this.reactRoot)===null||t===void 0||t.unmount(),this.reactRoot=null,(i=document.body)===null||i===void 0||i.classList.remove("eka-medassist-pushed"),(n=document.documentElement)===null||n===void 0||n.style.removeProperty("--eka-medassist-panel-width"),(s=document.documentElement)===null||s===void 0||s.style.removeProperty("--eka-medassist-panel-side"),(o=this.hostPushStyleEl)===null||o===void 0||o.remove(),this.hostPushStyleEl=null,this.hostPushState=null}applyHostPush(t,i,n){var s;if(typeof document=="undefined")return;const o=t?{width:i,side:n}:null,d=this.hostPushState;if(d===o||d&&o&&d.width===o.width&&d.side===o.side)return;this.hostPushState=o,this.hostPushStyleEl||(this.hostPushStyleEl=document.createElement("style"),this.hostPushStyleEl.setAttribute("data-medassist-side-panel-push","true"),document.head.appendChild(this.hostPushStyleEl));const r=n==="left"?"margin-left":"margin-right";this.hostPushStyleEl.textContent=`
|
|
1
|
+
"use strict";const getCurrentScript=()=>{if(typeof document=="undefined")return console.error("document is not defined"),null;const{currentScript:i}=document;if(i instanceof HTMLScriptElement)return i;const e=Array.from(document.getElementsByTagName("script")),t=e.find(o=>o.hasAttribute("data-widget-assets"));if(t)return t;const n=e.filter(o=>/(^|\/)index\.js(\?.*)?$/.test(o.src));return n.length?n[n.length-1]:e.length?e[e.length-1]:null},getEnvironment=i=>{if(i==="production"||i==="development"||i==="staging")return i},scriptEl=getCurrentScript(),DEFAULT_WIDGET_ASSET_BASE=(()=>{var i;return!((i=scriptEl==null?void 0:scriptEl.src)===null||i===void 0)&&i.includes("@dev"),"https://cdn.jsdelivr.net/npm/@eka-care/medassist-widget@0.1.138-dev.1/dist/"})();var FeedbackTypeEnum;(function(i){i.DEFAULT="default",i.NPS="nps"})(FeedbackTypeEnum||(FeedbackTypeEnum={}));function mapAgentConfigThemeToWidgetTheme(i){if(!i)return;const e=i.mode==="dark"?"white":i.mode==="light"?"black":void 0;return{...i.background_img&&{backgroundImage:i.background_img},...i.accent&&{primary:i.accent},...e&&{textColor:e},...i.mode&&{mode:i.mode},...i.header_tinted!==void 0&&{headerTinted:i.header_tinted},...i.title_img&&{titleImg:i.title_img},...i.tagline&&{tagline:i.tagline},...i.hide_watermark&&{hideWatermark:i.hide_watermark},...i.explicit_disclaimer&&{explicitDisclaimer:i.explicit_disclaimer},...i.consent_content&&{consentContent:i.consent_content},...i.upfront_consent&&{upfrontConsent:i.upfront_consent},...i.feature!==void 0&&{feature:i.feature}}}function preloadImage(i){if(!(!i||typeof document=="undefined"))try{const e=document.createElement("link");e.rel="preload",e.as="image",e.href=i,document.head.appendChild(e)}catch{const e=new Image;e.src=i}}function channelFromDisplayMode(i){return i==="full"?"web":i==="side_panel"?"side_panel":"widget"}function normalizeDisplayMode(i){return i==="full"?"full":i==="side_panel"?"side_panel":"widget"}const NUDGE_STORAGE_KEY="eka-medassist-nudges",AGENT_CONFIG_CACHE_KEY="eka-medassist-agent-config";function readAgentConfigCache(i){try{const e=localStorage.getItem(AGENT_CONFIG_CACHE_KEY);return(e?JSON.parse(e):{})[i]}catch{return}}function writeAgentConfigCache(i,e){try{const t=localStorage.getItem(AGENT_CONFIG_CACHE_KEY),n=t?JSON.parse(t):{};n[i]={...n[i]||{},...e},localStorage.setItem(AGENT_CONFIG_CACHE_KEY,JSON.stringify(n))}catch{}}function getNudgeStore(){try{const i=localStorage.getItem(NUDGE_STORAGE_KEY);return i?JSON.parse(i):{}}catch{return{}}}function setNudgeStore(i){try{localStorage.setItem(NUDGE_STORAGE_KEY,JSON.stringify(i))}catch{}}function normalizePath(i){let e=i.replace(/\/+$/,"");return e.startsWith("/")||(e="/"+e),e||"/"}function getNudgePathCandidates(i){const e=i.split("/").filter(Boolean),t=[];for(let n=e.length;n>=0;n--)t.push(n===0?"/":"/"+e.slice(0,n).join("/"));return t}function findCachedNudgeForCandidates(i,e,t){const o=getNudgeStore()[i];if(!o)return null;const s=e.host,r=o[s];if(!r)return null;for(const d of t){if(r[d]!==void 0)return{domain:s,path:d,data:r[d]};const a=d==="/"?"/*":d+"/*";if(r[a]!==void 0)return{domain:s,path:a,data:r[a]}}return null}function findFreshCachedNudge(i,e,t){const n=findCachedNudgeForCandidates(i,e,t);if(!n)return null;const o=Math.floor(Date.now()/1e3);return n.data.expiry<=o?(clearNudgeForPath(i,n.domain,n.path),null):n}function clearNudgeForPath(i,e,t){const n=getNudgeStore(),o=n[i];!o||!o[e]||(delete o[e][t],setNudgeStore(n))}function storeNudgeResponse(i,e,t){var n,o,s,r;const d=(n=e==null?void 0:e.url_pattern)===null||n===void 0?void 0:n.domain,a=(o=e==null?void 0:e.url_pattern)===null||o===void 0?void 0:o.path;if(!(!((s=e.nudges)===null||s===void 0)&&s.length)||!e.expiry||!d||!a)return;const l=getNudgeStore();l[i]||(l[i]={}),l[i][d]||(l[i][d]={});const h={nudges:e.nudges,expiry:e.expiry,delay:(r=e.delay)!==null&&r!==void 0?r:5};l[i][d][a]=h,t&&t!==a&&(l[i][d][t]=h),setNudgeStore(l)}const NUDGE_COOKIE_PREFIX="eka-nudge";function setNudgeCookie(i,e){const t=new Date(Date.now()+864e5).toUTCString();document.cookie=`${NUDGE_COOKIE_PREFIX}-${i}=${e}; expires=${t}; path=/; SameSite=Lax`}function getNudgeCookie(i){const e=document.cookie.split(";").map(n=>n.trim()).find(n=>n.startsWith(`${NUDGE_COOKIE_PREFIX}-${i}=`));if(!e)return null;const t=e.split("=")[1];return t==="open"||t==="closed"?t:null}const WIDGET_STORE_KEY_PREFIX="med-assist-store-";function readPersistedSessToken(i){var e,t;try{const n=sessionStorage.getItem(`${WIDGET_STORE_KEY_PREFIX}${i}`),o=n?(t=(e=JSON.parse(n))===null||e===void 0?void 0:e.state)===null||t===void 0?void 0:t.sessToken:void 0;return typeof o=="string"&&o?o:void 0}catch{return}}async function fetchNudgeData(i,e,t,n="widget"){const o=`${t}/med-assist/user-nudge`,s=[];typeof document!="undefined"&&document.querySelectorAll("meta").forEach(r=>{var d,a,l;const h=(d=r.getAttribute("name"))!==null&&d!==void 0?d:void 0,f=(a=r.getAttribute("property"))!==null&&a!==void 0?a:void 0,p=(l=r.getAttribute("content"))!==null&&l!==void 0?l:void 0;(h||f)&&s.push({name:h,property:f,content:p})});try{const r=await fetch(o,{method:"POST",headers:{"Content-Type":"application/json","x-agent-id":i,"x-channel":n,referer:typeof window!="undefined"?window.location.href:"",Authorization:`Bearer ${e}`},body:JSON.stringify({meta_tags:s,url:typeof window!="undefined"?window.location.href:""})});return r.ok?await r.json():void 0}catch{return}}const SIDE_PANEL_PUSH_EVENT="eka-medassist:side-panel-push",globalMedAssistConfig={},getWidgetElement=()=>typeof document=="undefined"?null:document.querySelector("eka-medassist-widget");if(typeof window!="undefined"){const i=window;i.__ekaMedAssistConfig__=globalMedAssistConfig,i.EkaMedAssist={init(e){var t,n,o;Object.assign(globalMedAssistConfig,e);const s=getWidgetElement();if(s){if(e.agentId&&s.setAttribute("agent-id",e.agentId),e.authToken&&s.setAttribute("auth-token",e.authToken),e.title&&s.setAttribute("title",e.title),e.iconUrl&&s.setAttribute("icon-url",e.iconUrl),e.baseUrl&&s.setAttribute("base-url",e.baseUrl),e.resize!==void 0&&s.setAttribute("resize",String(e.resize)),(e.displayMode==="full"||e.displayMode==="widget"||e.displayMode==="side_panel")&&s.setAttribute("display-mode",e.displayMode),e.sidePanelMode&&s.setAttribute("side-panel-mode",e.sidePanelMode),e.sidePanelWidth!==void 0&&s.setAttribute("side-panel-width",String(e.sidePanelWidth)),e.side&&s.setAttribute("side",e.side),e.context)try{s.setAttribute("context",JSON.stringify(e.context))}catch{console.warn("Failed to stringify context passed to init")}typeof e.customLauncherStyles=="string"&&s.setAttribute("custom-launcher-styles",e.customLauncherStyles),e.redirectUrl&&s.setAttribute("redirect-url",e.redirectUrl),!((t=e.theme)===null||t===void 0)&&t.backgroundImage&&preloadImage(e.theme.backgroundImage),(o=(n=s).openFromBridge)===null||o===void 0||o.call(n)}}}}const scriptBaseUrl=(()=>{if(!scriptEl)return"";try{return new URL(".",scriptEl.src||window.location.href).href}catch{return""}})(),widgetAssetBaseUrl=(()=>{if(!scriptEl)return DEFAULT_WIDGET_ASSET_BASE;const i=scriptEl.dataset.widgetAssets;if(i==="local")return`${scriptBaseUrl}src/`;if(i&&i.length>0)try{return new URL(i,scriptBaseUrl).href}catch{return i.endsWith("/")?i:`${i}/`}return DEFAULT_WIDGET_ASSET_BASE})(),WIDGET_JS_URL=`${widgetAssetBaseUrl}medassist-widget.js`,WIDGET_CSS_URL=`${widgetAssetBaseUrl}medassist-widget.css`;let widgetModulePromise=null,widgetCssTextPromise=null;function getWidgetCssTextPromise(){return widgetCssTextPromise||(widgetCssTextPromise=fetch(WIDGET_CSS_URL).then(i=>{if(!i.ok)throw new Error(`Unable to fetch widget styles from ${WIDGET_CSS_URL}`);return i.text()})),widgetCssTextPromise}class MedAssistWidgetLoader extends HTMLElement{setLauncherState(e){var t;const n=(t=this.shadowRoot)===null||t===void 0?void 0:t.getElementById("medassist-open-btn");n&&(n.classList.toggle("loading",e==="loading"),n.classList.toggle("hidden",e==="open"),e==="loading"?n.setAttribute("aria-busy","true"):n.removeAttribute("aria-busy"))}getChannel(){const e=this.getAttribute("display-mode");if(e)return channelFromDisplayMode(e);const t=typeof window!="undefined"?window.__ekaMedAssistConfig__:void 0;return channelFromDisplayMode(t==null?void 0:t.displayMode)}getAgentConfig(){var e;if(!this.agentConfigPromise){const t=(typeof window!="undefined"?window.__ekaMedAssistConfig__:void 0)||{},n=t.baseUrl||this.getAttribute("base-url")||"https://matrix.eka.care/reloaded",o=t.agentId||this.getAttribute("agent-id")||"";if(!o)return Promise.resolve(void 0);const s=(e=getEnvironment(this.getAttribute("environment")))!==null&&e!==void 0?e:"production";this.agentConfigPromise=this.loadWidgetModule().then(r=>{var d;return(d=r.fetchAgentConfig)===null||d===void 0?void 0:d.call(r,{agentId:o,serverUrl:n,environment:s,channel:this.getChannel()})}).catch(()=>{this.agentConfigPromise=null})}return this.agentConfigPromise}constructor(){super(),this.hostPushStyleEl=null,this.hostPushState=null,this.reactRoot=null,this.agentConfigPromise=null,this.loading=!1,this.authPrefetchPromise=null,this.launcherRenderSeq=0,this.attachShadow({mode:"open"}),this.widgetLoaded=!1,this.displayMode=normalizeDisplayMode(this.getAttribute("display-mode")),this.setupAuthExpirationListener()}static get observedAttributes(){return["icon-url","display-mode","custom-launcher-styles","redirect-url","side-panel-mode","side-panel-width","side"]}connectedCallback(){this.displayMode==="full"?(this.initializeFullMode(),this.loadAndRender().catch(e=>{console.error("Failed to load MedAssist widget in full mode",e)})):(this.renderLauncher(),this.scheduleIdle(()=>{this.preloadWidgetAssets(),this.prefetchAuthTokens(),this.initNudge()}))}disconnectedCallback(){var e,t,n,o,s;(e=this.reactRoot)===null||e===void 0||e.unmount(),this.reactRoot=null,(t=document.body)===null||t===void 0||t.classList.remove("eka-medassist-pushed"),(n=document.documentElement)===null||n===void 0||n.style.removeProperty("--eka-medassist-panel-width"),(o=document.documentElement)===null||o===void 0||o.style.removeProperty("--eka-medassist-panel-side"),(s=this.hostPushStyleEl)===null||s===void 0||s.remove(),this.hostPushStyleEl=null,this.hostPushState=null}applyHostPush(e,t,n){var o;if(typeof document=="undefined")return;const s=e?{width:t,side:n}:null,r=this.hostPushState;if(r===s||r&&s&&r.width===s.width&&r.side===s.side)return;this.hostPushState=s,this.hostPushStyleEl||(this.hostPushStyleEl=document.createElement("style"),this.hostPushStyleEl.setAttribute("data-medassist-side-panel-push","true"),document.head.appendChild(this.hostPushStyleEl));const d=n==="left"?"margin-left":"margin-right";this.hostPushStyleEl.textContent=`
|
|
2
2
|
body.eka-medassist-pushed {
|
|
3
|
-
${
|
|
3
|
+
${d}: ${t}px;
|
|
4
4
|
transition: margin 300ms ease;
|
|
5
5
|
}
|
|
6
6
|
body.eka-medassist-pushed > * {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
@media (prefers-reduced-motion: reduce) {
|
|
10
10
|
body.eka-medassist-pushed { transition: none !important; }
|
|
11
11
|
}
|
|
12
|
-
`;const a=document.documentElement.style;
|
|
12
|
+
`;const a=document.documentElement.style;e?(a.setProperty("--eka-medassist-panel-width",`${t}px`),a.setProperty("--eka-medassist-panel-side",n),document.body.classList.add("eka-medassist-pushed")):(document.body.classList.remove("eka-medassist-pushed"),a.removeProperty("--eka-medassist-panel-width"),a.removeProperty("--eka-medassist-panel-side"),this.hostPushStyleEl.remove(),this.hostPushStyleEl=null);const l={pushed:e,width:t,side:n};if(typeof window!="undefined"){try{window.dispatchEvent(new CustomEvent(SIDE_PANEL_PUSH_EVENT,{detail:l}))}catch{}const h=(o=window.EkaMedAssist)===null||o===void 0?void 0:o.onSidePanelPushChange;if(typeof h=="function")try{h(e,t,n)}catch(f){console.error("EkaMedAssist.onSidePanelPushChange threw",f)}}}scheduleIdle(e){if(typeof window=="undefined"){e();return}const t=window.requestIdleCallback;typeof t=="function"?t(e,{timeout:3e3}):setTimeout(e,200)}attributeChangedCallback(e){if(e==="icon-url"&&this.displayMode!=="full"&&this.renderLauncher(),e==="display-mode"){const t=normalizeDisplayMode(this.getAttribute("display-mode"));t!==this.displayMode&&(this.displayMode=t,t==="full"?this.initializeFullMode():this.renderLauncher())}e==="custom-launcher-styles"&&this.applyCustomLauncherStyles()}preloadWidgetAssets(){getWidgetCssTextPromise(),this.loadWidgetModule(),this.preloadBackgroundImage()}prefetchAuthTokens(){var e;if(this.authPrefetchPromise)return this.authPrefetchPromise;const t=(typeof window!="undefined"?window.__ekaMedAssistConfig__:void 0)||{},n=t.agentId||this.getAttribute("agent-id")||"";if(!n)return Promise.resolve(void 0);const o=t.authToken||this.getAttribute("auth-token")||void 0,s=t.baseUrl||this.getAttribute("base-url")||"https://matrix.eka.care/reloaded",r=(e=getEnvironment(this.getAttribute("environment")))!==null&&e!==void 0?e:"production";return this.authPrefetchPromise=this.loadWidgetModule().then(d=>{var a;return(a=d.prefetchAuth)===null||a===void 0?void 0:a.call(d,{agentId:n,authToken:o,serverUrl:s,environment:r,channel:this.getChannel()})}).catch(()=>{this.authPrefetchPromise=null}),this.authPrefetchPromise}async resolveSessToken(e){const t=readPersistedSessToken(e);if(t)return t;const n=await this.prefetchAuthTokens();return(n==null?void 0:n.sess_token)||readPersistedSessToken(e)}preloadBackgroundImage(){var e;const t=typeof window!="undefined"?window.__ekaMedAssistConfig__:void 0,n=this.getAttribute("theme")?(()=>{try{return JSON.parse(this.getAttribute("theme")||"{}")}catch{return}})():void 0,o=(e=t==null?void 0:t.theme)===null||e===void 0?void 0:e.backgroundImage,s=n==null?void 0:n.backgroundImage;o&&preloadImage(o),s&&s!==o&&preloadImage(s),this.getAgentConfig().then(r=>{var d;const a=(d=r==null?void 0:r.theme)===null||d===void 0?void 0:d.background_img;a&&preloadImage(a)}).catch(()=>{})}setupAuthExpirationListener(){if(typeof window=="undefined")return;const e=t=>{var n;((n=t.data)===null||n===void 0?void 0:n.type)==="AUTH_EXPIRED"&&window.parent!==window&&window.parent.postMessage({type:"AUTH_EXPIRED",message:"Authentication expired"},"*")};window.addEventListener("message",e)}openFromBridge(){this.displayMode=normalizeDisplayMode(this.getAttribute("display-mode")),this.displayMode==="full"?this.initializeFullMode():this.renderLauncher(),this.loadAndRender().catch(e=>{console.error("Failed to open MedAssist widget from bridge",e)})}async initNudge(){var e,t,n,o;const s=typeof window!="undefined"?window.__ekaMedAssistConfig__:void 0,r=(s==null?void 0:s.agentId)||this.getAttribute("agent-id")||"";if(!r)return;const d=await this.getAgentConfig();if(!(d!=null&&d.nudge))return;const a=(t=(e=d==null?void 0:d.theme)===null||e===void 0?void 0:e.nudge_color)!==null&&t!==void 0?t:"#ffffff",l=typeof window!="undefined"?window.location.href:"";let h;try{h=new URL(l)}catch{return}const f=getNudgePathCandidates(h.pathname),p=f.slice(0,1),y=f.slice(1);let g=findFreshCachedNudge(r,h,p);if(!g){const w=(s==null?void 0:s.baseUrl)||this.getAttribute("base-url")||"https://matrix.eka.care/reloaded",m=await this.resolveSessToken(r).catch(()=>{});if(m){const u=await fetchNudgeData(r,m,w,this.getChannel()).catch(()=>{});!((n=u==null?void 0:u.nudges)===null||n===void 0)&&n.length&&(storeNudgeResponse(r,u,normalizePath(h.pathname)),g=findFreshCachedNudge(r,h,f))}}if(g||(g=findFreshCachedNudge(r,h,y)),!g)return;const v=g.data.nudges[Math.floor(Math.random()*g.data.nudges.length)],b=(o=g.data.delay)!==null&&o!==void 0?o:5;setTimeout(()=>{this.showNudgePopup(v,a)},b*1e3)}showNudgePopup(e,t){var n,o;const s=this.shadowRoot;if(!s||!(!((n=s.getElementById("medassist-widget-root"))===null||n===void 0)&&n.classList.contains("hidden")))return;const d=((typeof window!="undefined"?window.__ekaMedAssistConfig__:void 0)||{}).agentId||this.getAttribute("agent-id")||"";if(d&&getNudgeCookie(d)!==null||s.getElementById("medassist-nudge-popup"))return;const l=s.getElementById("medassist-open-btn"),h=l==null?void 0:l.getBoundingClientRect(),f=272,p=12,y=8,g=16,v=16;let b=window.innerWidth-f-p,w=76,m=f-g-y*2;if(h&&h.width>0){const A=h.left+h.width/2,S=A-f/2,C=window.innerWidth-f-p;b=Math.max(p,Math.min(S,C)),w=window.innerHeight-h.top+v,m=Math.max(g,Math.min(A-b-y,f-g-y*2))}const u=document.createElement("div");u.id="medassist-nudge-popup",u.innerHTML=`
|
|
13
13
|
<style>
|
|
14
14
|
@keyframes nudge-slide-up {
|
|
15
15
|
from { opacity: 0; transform: translateY(12px) scale(0.97); }
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
}
|
|
18
18
|
#medassist-nudge-popup {
|
|
19
19
|
position: fixed;
|
|
20
|
-
bottom: ${
|
|
20
|
+
bottom: ${w}px;
|
|
21
21
|
left: ${b}px;
|
|
22
22
|
width: ${f}px;
|
|
23
|
-
background: ${
|
|
23
|
+
background: ${t};
|
|
24
24
|
border-radius: 16px;
|
|
25
25
|
box-shadow: 0 8px 32px rgba(0,0,0,0.14), 0 2px 8px rgba(0,0,0,0.08);
|
|
26
26
|
padding: 16px 16px 14px 16px;
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
left: ${m}px;
|
|
41
41
|
width: 16px;
|
|
42
42
|
height: 10px;
|
|
43
|
-
background: ${
|
|
43
|
+
background: ${t};
|
|
44
44
|
clip-path: polygon(0 0, 100% 0, 50% 100%);
|
|
45
45
|
}
|
|
46
46
|
#medassist-nudge-popup {
|
|
@@ -87,10 +87,10 @@
|
|
|
87
87
|
}
|
|
88
88
|
</style>
|
|
89
89
|
<div class="nudge-header">
|
|
90
|
-
<p class="nudge-text">${
|
|
90
|
+
<p class="nudge-text">${e.replace(/</g,"<").replace(/>/g,">")}</p>
|
|
91
91
|
<button class="nudge-close" aria-label="Dismiss">✕</button>
|
|
92
92
|
</div>
|
|
93
|
-
`,(
|
|
93
|
+
`,(o=u.querySelector(".nudge-close"))===null||o===void 0||o.addEventListener("click",A=>{A.stopPropagation(),d&&setNudgeCookie(d,"closed"),this.dismissNudgePopup()}),u.addEventListener("click",()=>{d&&setNudgeCookie(d,"closed"),this.dismissNudgePopup(),this.loadAndRender()}),s.appendChild(u)}dismissNudgePopup(){var e;const t=(e=this.shadowRoot)===null||e===void 0?void 0:e.getElementById("medassist-nudge-popup");t==null||t.remove()}applyCustomLauncherStyles(){var e;const t=this.shadowRoot;if(!t||this.displayMode==="full")return;const n=t.querySelector('style[data-medassist-custom-launcher="true"]'),o=(e=this.getAttribute("custom-launcher-styles"))!==null&&e!==void 0?e:"";if(!o){n==null||n.remove();return}if(n){n.textContent=o;return}const s=document.createElement("style");s.setAttribute("data-medassist-custom-launcher","true"),s.textContent=o,t.appendChild(s)}getAgentId(){return((typeof window!="undefined"?window.__ekaMedAssistConfig__:void 0)||{}).agentId||this.getAttribute("agent-id")||""}async renderLauncher(){var e,t;if(this.displayMode==="full")return;const n=++this.launcherRenderSeq;this.renderButton();const o=this.getAttribute("icon-url");if(o){this.setLauncherIcon(o);return}const s=this.getAgentId();if(!s)return;const r=(t=(e=readAgentConfigCache(s))===null||e===void 0?void 0:e.theme)===null||t===void 0?void 0:t.icon_img;r&&this.setLauncherIcon(r);const d=async()=>{var a;const l=await this.getAgentConfig().catch(()=>{});n===this.launcherRenderSeq&&(l&&writeAgentConfigCache(s,l),this.setLauncherIcon(((a=l==null?void 0:l.theme)===null||a===void 0?void 0:a.icon_img)||r))};r?this.scheduleIdle(()=>{d()}):await d()}setLauncherIcon(e){var t;const n=this.shadowRoot;if(!n)return;const o=n.querySelector("#medassist-open-btn img");o&&(e?o.src=e:o.removeAttribute("src")),(t=n.getElementById("medassist-open-btn"))===null||t===void 0||t.classList.remove("pending")}renderButton(){var e;const t=this.shadowRoot;if(!t){console.error("Shadow root was not created");return}t.querySelector("button")||(t.innerHTML=`
|
|
94
94
|
<style>
|
|
95
95
|
#medassist-open-btn {
|
|
96
96
|
width: 60px;
|
|
@@ -111,6 +111,16 @@
|
|
|
111
111
|
border-radius: 50%;
|
|
112
112
|
object-fit: cover;
|
|
113
113
|
}
|
|
114
|
+
/* No icon from the host or agent-config: keep the launcher clickable
|
|
115
|
+
but never show a broken-image glyph. */
|
|
116
|
+
#medassist-open-btn img:not([src]) {
|
|
117
|
+
display: none;
|
|
118
|
+
}
|
|
119
|
+
/* Icon not resolved yet (waiting on agent-config): nothing is shown \u2014
|
|
120
|
+
there is no default icon to fall back to. */
|
|
121
|
+
#medassist-open-btn.pending {
|
|
122
|
+
display: none !important;
|
|
123
|
+
}
|
|
114
124
|
:host {
|
|
115
125
|
position: fixed;
|
|
116
126
|
bottom: 20px;
|
|
@@ -159,12 +169,12 @@
|
|
|
159
169
|
}
|
|
160
170
|
</style>
|
|
161
171
|
|
|
162
|
-
<button id="medassist-open-btn">
|
|
163
|
-
<img
|
|
172
|
+
<button id="medassist-open-btn" class="pending" aria-label="Open MedAssist">
|
|
173
|
+
<img alt="MedAssist Icon">
|
|
164
174
|
<span id="medassist-loader" aria-hidden="true"></span>
|
|
165
175
|
</button>
|
|
166
176
|
<div id="medassist-widget-root" class="hidden"></div>
|
|
167
|
-
`,(t
|
|
177
|
+
`,(e=t.getElementById("medassist-open-btn"))===null||e===void 0||e.addEventListener("click",()=>{const n=this.getAgentId();n&&setNudgeCookie(n,"closed"),this.dismissNudgePopup(),this.loadAndRender()})),this.applyCustomLauncherStyles()}initializeFullMode(){const e=this.shadowRoot;if(!e){console.error("Shadow root is not available");return}e.getElementById("medassist-widget-root")||(e.innerHTML=`
|
|
168
178
|
<style>
|
|
169
179
|
:host {
|
|
170
180
|
display: block;
|
|
@@ -181,4 +191,4 @@
|
|
|
181
191
|
}
|
|
182
192
|
</style>
|
|
183
193
|
<div id="medassist-widget-root"></div>
|
|
184
|
-
`)}async loadAndRender(){var t,
|
|
194
|
+
`)}async loadAndRender(){var e,t,n;const o=this.shadowRoot;if(!o){console.error("Shadow root is not available");return}if(this.loading)return;this.prefetchAuthTokens(),this.style.display="";const s=o.getElementById("medassist-widget-root"),r=this.getAttribute("agent-id");let d=this.getAttribute("icon-url")||void 0;const a=(e=getEnvironment(this.getAttribute("environment")))!==null&&e!==void 0?e:"production",l=this.getAttribute("connectivity"),h=l==="http_stream"||l==="socket"?l:void 0,f=this.getAttribute("force-start")==="true";let p=this.getAttribute("title")||"Medi Clinic";const y=this.getAttribute("base-url")||"https://matrix.eka.care/reloaded",g=this.getAttribute("display-mode"),v=normalizeDisplayMode(g),b=this.getAttribute("context")?JSON.parse(this.getAttribute("context")||"{}"):void 0,w=this.getAttribute("theme")?(()=>{try{return JSON.parse(this.getAttribute("theme")||"{}")}catch{return}})():void 0,m=this.getAttribute("feedback")?(()=>{try{return JSON.parse(this.getAttribute("feedback")||"{}")}catch{return}})():void 0,u=(typeof window!="undefined"?window.__ekaMedAssistConfig__:void 0)||{},A=this.getAttribute("side-panel-mode"),S=u.sidePanelMode||(A==="overlay"?"overlay":"push"),C=this.getAttribute("side-panel-width"),F=(t=u.sidePanelWidth)!==null&&t!==void 0?t:C?Number(C):void 0,O=u.side||this.getAttribute("side")||(typeof document!="undefined"&&document.dir==="rtl"?"left":"right"),D={...b||{},...u.context||{}},H=u.authToken||this.getAttribute("auth-token")||void 0,_=u.agentId||r,q=u.baseUrl||y,E=typeof window!="undefined"?(n=window.EkaMedAssist)===null||n===void 0?void 0:n.onClose:void 0,J=this.getAttribute("redirect-url")||void 0,P=u.redirectUrl||J,j=!!P||u.showCloseButton===!0;if(!_){console.error("Agent ID is required");return}if(!s){console.error("Widget root element is missing");return}this.loading=!0,this.setLauncherState("loading"),s.classList.remove("hidden");let L,R,N,U=!1,T,W=!1,M;const B=c=>{var x,k,I;p=c.name||p,d=((x=c.theme)===null||x===void 0?void 0:x.icon_img)||d,L=mapAgentConfigThemeToWidgetTheme(c.theme||void 0),R=c.allowed,N=c.connectivity,U=c.resize||(u==null?void 0:u.resize)||!1,T=c.initial_message,W=(I=(k=c.theme)===null||k===void 0?void 0:k.hide_watermark)!==null&&I!==void 0?I:!1,M=c.feedback},$=readAgentConfigCache(_);if($)B($),this.getAgentConfig().then(c=>{c&&writeAgentConfigCache(_,c)}).catch(()=>{});else try{const c=await this.getAgentConfig();c&&(writeAgentConfigCache(_,c),B(c))}catch{}const G=h||N||"socket",z={title:u.title||p,iconUrl:d||u.iconUrl,showCloseButton:j,allowed:R,environment:a,connectionType:G,onClose:()=>{var c;if((c=this.reactRoot)===null||c===void 0||c.unmount(),this.reactRoot=null,E&&typeof E=="function"&&E(),P){window.location.href=P;return}v==="full"?this.style.display="none":(this.setLauncherState("idle"),s.classList.add("hidden"))},baseUrl:q,context:D,displayMode:v,sidePanelMode:S,sidePanelWidth:F,side:O,onSidePanelPushChange:(c,x,k)=>this.applyHostPush(c,x,k),resize:U||this.getAttribute("resize")==="true",authToken:H,force:f,initialMessage:T,hideWatermark:W,...(m||M)&&{feedback:m||M},theme:{...L||{},...w||{},...u.theme||{}}},X=window;if(this.widgetLoaded){this.reactRoot=X.renderMedAssist(s,_,z),this.setLauncherState("open"),this.loading=!1;return}try{const[,c]=await Promise.all([this.loadWidgetCss(),this.loadWidgetModule()]);this.reactRoot=c.renderMedAssist(s,_,z),this.widgetLoaded=!0,this.setLauncherState("open")}catch(c){console.error("Failed to load MedAssist widget",c),this.setLauncherState("idle"),s.classList.add("hidden")}finally{this.loading=!1}}async loadWidgetCss(){const e=this.shadowRoot;if(!e)throw new Error("Shadow root is not available");if(e.querySelector("[data-medassist-style='true']"))return;const t=await getWidgetCssTextPromise(),n=document.createElement("style");n.setAttribute("data-medassist-style","true"),n.textContent=t,e.appendChild(n)}loadWidgetModule(){return widgetModulePromise||(widgetModulePromise=import(WIDGET_JS_URL)),widgetModulePromise}}customElements.define("eka-medassist-widget",MedAssistWidgetLoader);
|