blocfeed 0.4.0 → 0.6.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/CHANGELOG.md CHANGED
@@ -1,5 +1,41 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.6.0 — 2026-02-20
4
+
5
+ ### New features
6
+
7
+ - **Console log capture** — `config.diagnostics` automatically intercepts `console.error` and `console.warn` (configurable levels) and attaches the last 20 entries (configurable) to every feedback submission as `metadata._consoleLogs`. Messages and stacks are truncated at 2KB.
8
+ - **Network error capture** — When `config.diagnostics` is set, failed `fetch` requests (status >= 400 or network errors) are captured and attached as `metadata._networkErrors` (last 15 entries). BlocFeed's own API calls are excluded.
9
+ - **i18n / Localization** — `config.ui.strings` overrides all UI text (panel title, buttons, hints, placeholders, status messages). Full `BlocFeedStrings` interface exported for type safety.
10
+ - **Watermark** — "Powered by BlocFeed" link in the panel footer. Shown by default (`config.ui.branding: true`), can be hidden for paid plans.
11
+ - **Backlog** — `BACKLOG.md` added with 15 future feature ideas for reference.
12
+
13
+ ### Improvements
14
+
15
+ - New types exported: `BlocFeedStrings`, `ConsoleEntry`, `NetworkEntry`, `DiagnosticsConfig`.
16
+ - Engine exports: `installDiagnostics`, `uninstallDiagnostics`, `drainDiagnostics`, `clearDiagnostics` for headless usage.
17
+
18
+ ---
19
+
20
+ ## 0.5.0 — 2026-02-20
21
+
22
+ ### New features
23
+
24
+ - **Custom trigger label** — `config.ui.triggerLabel` sets the text shown on the trigger button (default: `"Feedback"`). Applies to all trigger styles.
25
+ - **Keyboard shortcut** — `config.ui.shortcut` (e.g., `"mod+shift+f"`) toggles the widget open/closed. Supports `ctrl`, `meta`/`cmd`, `shift`, `alt`/`option` modifiers; `mod` maps to Ctrl on Windows/Linux and Cmd on Mac.
26
+ - **Beacon trigger style** — new `"beacon"` trigger with a lighthouse-style sweeping beam and glowing dot that expands to a pill on hover.
27
+ - **Typewriter trigger style** — new `"typewriter"` trigger with text that types out character by character with a blinking cursor, fully visible on hover.
28
+ - **Offline queue badge** — when submissions are queued for retry, a red badge with the count appears on the trigger button across all styles.
29
+ - **Success checkmark** — after a successful submission, the trigger briefly shows a checkmark icon for 1.5 seconds before returning to normal.
30
+ - **Panel / toast / hint animations** — the feedback panel slides in from below, the success toast slides up, and the hint bar slides down using CSS keyframe animations.
31
+
32
+ ### Improvements
33
+
34
+ - **`prefers-reduced-motion` support** — all framer-motion animations and CSS keyframe animations are disabled when the user prefers reduced motion. Animated triggers use instant transitions; panel/toast/hint entrance animations are suppressed.
35
+ - **`TriggerStyle` type** updated to include `"beacon"` and `"typewriter"`.
36
+
37
+ ---
38
+
3
39
  ## 0.4.0 — 2026-02-20
4
40
 
5
41
  ### New features
package/README.md CHANGED
@@ -105,7 +105,9 @@ All configuration is passed via the `config` prop on `<BlocFeedWidget>` or `<Blo
105
105
  // Widget position, theme & trigger style
106
106
  ui: {
107
107
  position: "bottom-right", // "bottom-left" | "top-right" | "top-left"
108
- triggerStyle: "dot", // "classic" | "bubble" | "edge-tab" | "pulse-ring" | "minimal" | "icon-pop"
108
+ triggerStyle: "dot", // "classic" | "bubble" | "edge-tab" | "pulse-ring" | "minimal" | "icon-pop" | "beacon" | "typewriter"
109
+ triggerLabel: "Feedback", // custom label text
110
+ shortcut: "mod+shift+f", // keyboard shortcut to toggle widget
109
111
  zIndex: 99999,
110
112
  theme: {
111
113
  accentColor: "#12D393",
@@ -115,6 +117,12 @@ All configuration is passed via the `config` prop on `<BlocFeedWidget>` or `<Blo
115
117
  },
116
118
  },
117
119
 
120
+ // Diagnostics (console + network capture)
121
+ diagnostics: {
122
+ console: true,
123
+ network: true,
124
+ },
125
+
118
126
  // Screenshot defaults
119
127
  capture: {
120
128
  element: true,
@@ -201,8 +209,32 @@ config={{
201
209
  | `"pulse-ring"` | Sonar-style pulsing rings around a dot, expands on hover | Yes |
202
210
  | `"minimal"` | Text-only "Feedback" with animated underline on hover | Yes |
203
211
  | `"icon-pop"` | Wobbling icon that pops and reveals text on hover | Yes |
212
+ | `"beacon"` | Lighthouse-style sweeping beam with glowing dot, expands on hover | Yes |
213
+ | `"typewriter"` | Text types out character by character with blinking cursor | Yes |
214
+
215
+ All animated styles include smooth enter/exit transitions. Animations automatically simplify when `prefers-reduced-motion: reduce` is active.
216
+
217
+ ### Custom trigger label
218
+
219
+ ```tsx
220
+ config={{
221
+ ui: { triggerLabel: "Report Bug" }
222
+ }}
223
+ ```
224
+
225
+ The label defaults to `"Feedback"` and is used across all trigger styles.
226
+
227
+ ### Keyboard shortcut
204
228
 
205
- All animated styles include smooth enter/exit transitions powered by framer-motion's spring physics.
229
+ Open/close the widget with a keyboard shortcut:
230
+
231
+ ```tsx
232
+ config={{
233
+ ui: { shortcut: "mod+shift+f" }
234
+ }}
235
+ ```
236
+
237
+ Use `mod` for platform-aware behavior (Ctrl on Windows/Linux, Cmd on Mac). Supports `ctrl`, `meta`/`cmd`, `shift`, `alt`/`option` modifiers.
206
238
 
207
239
  ### Installing framer-motion
208
240
 
@@ -212,6 +244,64 @@ All styles except `"classic"` require `framer-motion` as a peer dependency:
212
244
  npm install framer-motion
213
245
  ```
214
246
 
247
+ ## i18n / Localization
248
+
249
+ Override all UI text via `config.ui.strings`:
250
+
251
+ ```tsx
252
+ config={{
253
+ ui: {
254
+ strings: {
255
+ triggerLabel: "Rückmeldung",
256
+ panelTitle: "Rückmeldung",
257
+ hintText: "Klicken Sie auf ein Element. Drücken Sie Esc zum Abbrechen.",
258
+ cancelButton: "Abbrechen",
259
+ rePickButton: "Neu wählen",
260
+ closeButton: "Schließen",
261
+ textareaPlaceholder: "Was ist passiert? Was haben Sie erwartet?",
262
+ screenshotElement: "Element-Screenshot",
263
+ screenshotFullPage: "Ganze Seite",
264
+ capturingText: "Screenshots werden aufgenommen…",
265
+ submittingText: "Wird gesendet…",
266
+ successText: "Gesendet. Vielen Dank!",
267
+ toastText: "Feedback gesendet",
268
+ sendButton: "Senden",
269
+ },
270
+ },
271
+ }}
272
+ ```
273
+
274
+ All fields are optional — only override the ones you need.
275
+
276
+ ## Console & Network Diagnostics
277
+
278
+ Automatically capture console errors and failed network requests to include with every feedback submission:
279
+
280
+ ```tsx
281
+ config={{
282
+ diagnostics: {
283
+ console: true, // capture console.error & console.warn
284
+ consoleLevels: ["error", "warn"], // which levels to capture
285
+ consoleLimit: 20, // max entries retained
286
+ network: true, // capture failed fetch requests
287
+ networkLimit: 15, // max entries retained
288
+ },
289
+ }}
290
+ ```
291
+
292
+ Captured data is attached to `metadata._consoleLogs` and `metadata._networkErrors` in the payload. BlocFeed's own API calls are excluded. Messages and stacks are truncated at 2KB.
293
+
294
+ ### Headless diagnostics
295
+
296
+ ```ts
297
+ import {
298
+ installDiagnostics,
299
+ uninstallDiagnostics,
300
+ drainDiagnostics,
301
+ clearDiagnostics,
302
+ } from "blocfeed/engine";
303
+ ```
304
+
215
305
  ## Theme Customization
216
306
 
217
307
  Override the widget's visual appearance via CSS variables:
@@ -346,9 +436,11 @@ The widget supports full keyboard navigation:
346
436
  - **Shift+Tab** cycles backward
347
437
  - **Escape** cancels picking or closes the panel
348
438
  - **Ctrl/Cmd+Enter** submits feedback from the textarea
439
+ - **Custom shortcut** — configurable via `config.ui.shortcut` (e.g., `"mod+shift+f"`)
349
440
  - Focus is trapped within the panel when open
350
441
  - All interactive elements have `aria-label` attributes
351
442
  - Status messages use `aria-live="polite"` for screen reader announcements
443
+ - Animations respect `prefers-reduced-motion: reduce` — all motion is disabled when the user prefers reduced motion
352
444
 
353
445
  ## Client-Side Rate Limiting
354
446
 
@@ -0,0 +1,2 @@
1
+ 'use strict';function m(){return typeof window<"u"&&typeof document<"u"}function te(e){let t=globalThis.CSS;return typeof t?.escape=="function"?t.escape(e):e.replace(/[^a-zA-Z0-9_-]/g,n=>{let r=n.codePointAt(0);return r===void 0?"":`\\${r.toString(16)} `})}function Q(e){return {x:e.x,y:e.y,width:e.width,height:e.height}}function Te(e){return {x:e.x+window.scrollX,y:e.y+window.scrollY,width:e.width,height:e.height}}function Re(e){return e.replace(/\s+/g," ").trim()}function Ae(e,t=140){let n=e.textContent;if(!n)return;let r=Re(n);if(r)return r.length<=t?r:`${r.slice(0,t-1)}\u2026`}function Ce(e){let t=1;for(let n=e.previousElementSibling;n;n=n.previousElementSibling)n.tagName===e.tagName&&(t+=1);return t}var oe=["data-testid","data-test-id","data-test","data-qa","data-cy"],ne="data-blocfeed-component";function Me(e){let t=e.closest(`[${ne}]`);if(!t)return;let r=t.getAttribute(ne)?.trim();return r||void 0}function Be(e){for(let t of oe){let n=e.closest(`[${t}]`);if(!n)continue;let o=n.getAttribute(t)?.trim();if(o)return o}}function Le(e){try{let t=e,n=Object.getOwnPropertyNames(t);for(let r of n)if(r.startsWith("__reactFiber$")||r.startsWith("__reactInternalInstance$")){let o=t[r];if(o&&typeof o=="object")return o}}catch{}return null}function B(e){if(e&&typeof e!="string"){if(typeof e=="function"){let t=e;return typeof t.displayName=="string"&&t.displayName?t.displayName:typeof t.name=="string"&&t.name?t.name:void 0}if(typeof e=="object"){let t=e,n=t.displayName;if(typeof n=="string"&&n)return n;let r=t.render;if(typeof r=="function"){let i=r;if(typeof i.displayName=="string"&&i.displayName)return i.displayName;if(typeof i.name=="string"&&i.name)return i.name}let o=t.type;return B(o)}}}function _e(e){let t=Le(e);if(!t)return;let n=t._debugOwner!==void 0;if(n){let i=t._debugOwner;for(let a=0;i&&a<50;a+=1){let s=B(i.type)??B(i.elementType);if(s)return s;i=i._debugOwner;}}let r=t,o=n?80:10;for(let i=0;r&&i<o;i+=1){let a=B(r.type)??B(r.elementType);if(a)return a;r=r.return;}}function Ie(e){let t=e.tagName.toLowerCase(),n=e.getAttribute("id");if(n)return `#${te(n)}`;for(let r of oe){let o=e.getAttribute(r);if(o)return `${t}[${r}="${te(o)}"]`}return `${t}:nth-of-type(${Ce(e)})`}function De(e,t=10){let n=[],r=e;for(;r&&n.length<t;){let o=Ie(r);if(n.unshift(o),o.startsWith("#"))break;r=r.parentElement;}return n.join(" > ")}function re(e,t){if(!t||t.length===0)return false;for(let n of t)if(e.closest(n))return true;return false}function W(e,t){if(!e||re(e,t.ignoreSelectors))return null;let n=e;for(;n;){if(re(n,t.ignoreSelectors))return null;if(t.isSelectable?.(n)??Ne(n))return n;n=n.parentElement;}return null}function Ne(e){let t=e.tagName;return !(t==="HTML"||t==="BODY")}function ie(e){let t=e.getBoundingClientRect(),n={selector:De(e),tagName:e.tagName.toLowerCase(),rect:Q(t),pageRect:Te(t)},r=e.getAttribute("id");r&&(n.id=r);let o=e.className;typeof o=="string"&&o.trim()&&(n.className=o);let i=Ae(e);i&&(n.textSnippet=i);let a=Me(e)??_e(e);a&&(n.componentName=a);let s=Be(e);return s&&(n.testId=s),n}var z=null;async function ae(){return z||(z=import('html-to-image')),z}async function Ue(e){return await new Promise((t,n)=>{let r=new Image;r.onload=()=>t({width:r.naturalWidth,height:r.naturalHeight}),r.onerror=()=>n(new Error("Failed to load generated screenshot")),r.src=e;})}async function se(e,t){let{width:n,height:r}=await Ue(e);return {dataUrl:e,mime:t,width:n,height:r}}function A(e){if(e?.aborted)throw new Error("Aborted")}function le(){return {async captureElement(e,t){if(!m())throw new Error("captureElement can only run in the browser");A(t.signal);let n=await ae();A(t.signal);let r=t.mime==="image/jpeg"?await n.toJpeg(e,{quality:t.quality??.92,pixelRatio:t.pixelRatio}):await n.toPng(e,{pixelRatio:t.pixelRatio});return A(t.signal),await se(r,t.mime)},async captureFullPage(e){if(!m())throw new Error("captureFullPage can only run in the browser");A(e.signal);let t=document.documentElement,n=Math.max(t.scrollWidth,t.clientWidth),r=Math.max(t.scrollHeight,t.clientHeight),o=Math.min(1,e.maxDimension/Math.max(n,r)),i=Math.max(1,Math.round(n*o)),a=Math.max(1,Math.round(r*o)),s=await ae();A(e.signal);let f=e.mime==="image/jpeg"?await s.toJpeg(t,{width:i,height:a,quality:e.quality??.92,pixelRatio:e.pixelRatio}):await s.toPng(t,{width:i,height:a,pixelRatio:e.pixelRatio});return A(e.signal),await se(f,e.mime)}}}function Oe(e){if(e instanceof Error)return e.message;if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return "Unknown error"}}function p(e,t,n){let r={kind:e,message:Oe(t)};return n&&(r.detail=n),r}var He=12e3,qe=2048,$e=.92;function ce(){return Date.now()}function je(e){return new Promise((t,n)=>{let r=()=>n(new Error("Aborted"));if(e.aborted){r();return}e.addEventListener("abort",r,{once:true});})}async function ue(e,t,n){let r=new Promise((i,a)=>{let s=setTimeout(()=>a(new Error("Timeout")),t);typeof s.unref=="function"&&s.unref();}),o=[e,r];return n&&o.push(je(n)),await Promise.race(o)}function Qe(e){if(!m())return 1;let t=window.devicePixelRatio||1,n=e?.pixelRatio??Math.min(t,2);return Math.max(.1,n)}function We(e){return !!(e?.element||e?.fullPage)}function de(e){let t={mime:e.mime,pixelRatio:e.pixelRatio,maxDimension:e.maxDimension};return e.includeQuality&&(t.quality=e.quality),e.signal&&(t.signal=e.signal),t}async function fe(e){let{selectionElement:t,capture:n,signal:r}=e;if(!m()||!We(n))return;let o=ce(),i=[],a=n?.timeoutMs??He,s=n?.maxDimension??qe,f=n?.mime??"image/png",g=n?.quality??$e,w=n?.adapter??le(),y={},E=Qe(n);if(n?.element&&t)try{let c=t.getBoundingClientRect(),u=Math.min(1,s/Math.max(c.width,c.height)),v=Math.min(E,E*u),x=await ue(Promise.resolve(w.captureElement(t,{...de({mime:f,quality:g,pixelRatio:v,maxDimension:s,includeQuality:f==="image/jpeg",...r?{signal:r}:{}})})),a,r);y.element=x;}catch(c){if(r?.aborted)throw c;i.push(p("capture_failed",c,{target:"element"}));}if(n?.fullPage)try{let c=await ue(Promise.resolve(w.captureFullPage(de({mime:f,quality:g,pixelRatio:E,maxDimension:s,includeQuality:f==="image/jpeg",...r?{signal:r}:{}}))),a,r);y.fullPage=c;}catch(c){if(r?.aborted)throw c;i.push(p("capture_failed",c,{target:"fullPage"}));}let h=ce(),l={startedAt:o,finishedAt:h,durationMs:Math.max(0,h-o)};return i.length>0&&(l.errors=i),{...y,diagnostics:l}}function ze(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return}}function Je(){return m()?{url:window.location.href,title:document.title,referrer:document.referrer||void 0,userAgent:navigator.userAgent,language:navigator.language,platform:navigator.platform,viewport:{width:window.innerWidth,height:window.innerHeight},screen:{width:window.screen.width,height:window.screen.height},scroll:{x:window.scrollX,y:window.scrollY},devicePixelRatio:window.devicePixelRatio||1,timezone:ze()}:{}}function Ye(e){if(!e)return {};let t={};return e.id&&(t.userId=e.id),e.email&&(t.userEmail=e.email),e.name&&(t.userName=e.name),t}async function me(e){let{config:t,context:n,user:r}=e;if(t?.enabled===false)return {};let o={...Je(),...Ye(r)},i=t?.enrich;if(!i)return o;try{let a=await i(n);return {...o,...a}}catch(a){let s=p("unknown",a);return {...o,blocfeedMetadataError:s.message}}}var J="blocfeed-queue",Ke=50;function Y(){if(!m())return [];try{let e=localStorage.getItem(J);if(!e)return [];let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return []}}function K(e){if(m())try{e.length===0?localStorage.removeItem(J):localStorage.setItem(J,JSON.stringify(e));}catch{}}function Xe(e){let t={...e};if(t.screenshots){let n={...t.screenshots};n.element&&(n.element={...n.element,dataUrl:""}),n.fullPage&&(n.fullPage={...n.fullPage,dataUrl:""}),t.screenshots=n;}return t}function X(e){let t=Y(),n=Xe(e);for(n.metadata={...n.metadata,_queued:true},t.push({payload:n,timestamp:Date.now()});t.length>Ke;)t.shift();K(t);}function pe(){let e=Y();return e.length===0?[]:(K([]),e.map(t=>t.payload))}function vt(){K([]);}function Pt(){return Y().length}function G(e){let t=null,n=null,r=(...o)=>{n=o,t===null&&(t=requestAnimationFrame(()=>{if(t=null,!n)return;let i=n;n=null,e(...i);}));};return r.cancel=()=>{t!==null&&cancelAnimationFrame(t),t=null,n=null;},r}function U(e){return e instanceof Element?!!e.closest("[data-blocfeed-ui]"):false}function O(e){e.stopPropagation(),e.stopImmediatePropagation?.();}function ge(e,t){if(!m())throw new Error("BlocFeed picker can only run in a browser environment.");let n=e.ignoreSelectors,r=e.isSelectable,o={};n&&n.length>0&&(o.ignoreSelectors=n),r&&(o.isSelectable=r);let i=null,a=null,s=(l,c=false)=>{if(!l){i=null,a=null,t.onHover(null);return}let u=Q(l.getBoundingClientRect()),v=`${Math.round(u.x)}:${Math.round(u.y)}:${Math.round(u.width)}:${Math.round(u.height)}`;!c&&l===i&&v===a||(i=l,a=v,t.onHover({element:l,rect:u}));},f=G(l=>{if(U(l.target))return;let c=document.elementFromPoint(l.clientX,l.clientY),u=W(c,o);s(u);}),g=G(()=>{i&&s(i,true);}),w=l=>{U(l.target)||(O(l),l.pointerType==="mouse"&&l.preventDefault());},y=l=>{U(l.target)||(O(l),l.pointerType==="mouse"&&l.preventDefault());},E=l=>{if(U(l.target))return;O(l),l.preventDefault();let c=document.elementFromPoint(l.clientX,l.clientY),u=W(c,o);u&&t.onSelect({element:u,descriptor:ie(u)});},h=l=>{l.key==="Escape"&&(O(l),l.preventDefault(),t.onCancel());};return window.addEventListener("pointermove",f,{capture:true,passive:true}),window.addEventListener("pointerdown",w,{capture:true}),window.addEventListener("pointerup",y,{capture:true}),window.addEventListener("click",E,{capture:true}),window.addEventListener("keydown",h,{capture:true}),window.addEventListener("scroll",g,{capture:true,passive:true}),window.addEventListener("resize",g,{passive:true}),{stop(){window.removeEventListener("pointermove",f,{capture:true}),window.removeEventListener("pointerdown",w,{capture:true}),window.removeEventListener("pointerup",y,{capture:true}),window.removeEventListener("click",E,{capture:true}),window.removeEventListener("keydown",h,{capture:true}),window.removeEventListener("scroll",g,{capture:true}),window.removeEventListener("resize",g),f.cancel(),g.cancel(),t.onHover(null);}}}var Ge=12e3,Ze=2,Ve=500,et=2e3,ye="https://blocfeed.com/api/feedback",he=0;function we(e,t){return new Promise((n,r)=>{if(t?.aborted){r(new Error("Aborted"));return}let o=setTimeout(n,e),i=()=>{clearTimeout(o),r(new Error("Aborted"));};t?.addEventListener("abort",i,{once:true});})}function tt(e){return e>=500&&e<=599}function nt(e){let[t,n]=e.split(",",2);if(!t||!n)throw new Error("Invalid data URL");let o=/data:(.*?);base64/.exec(t)?.[1]||"application/octet-stream",i=atob(n),a=new Uint8Array(i.length);for(let s=0;s<i.length;s+=1)a[s]=i.charCodeAt(s);return new Blob([a],{type:o})}function rt(e){let t={},n={...e};if(n.screenshots){let r={},o={...n.screenshots};o.element&&(t.element=o.element.dataUrl,r.element={mime:o.element.mime,width:o.element.width,height:o.element.height},o.element={...o.element,dataUrl:""}),o.fullPage&&(t.fullPage=o.fullPage.dataUrl,r.fullPage={mime:o.fullPage.mime,width:o.fullPage.width,height:o.fullPage.height},o.fullPage={...o.fullPage,dataUrl:""}),n.screenshots=o,(r.element||r.fullPage)&&(n.screenshot_intent=r);}return {lean:n,extracted:t}}async function be(e,t,n){let r=nt(t);await fetch(e,{method:"PUT",body:r,headers:{"content-type":r.type},...n?{signal:n}:{}});}async function ot(e){let{feedbackId:t,extracted:n,screenshots:r,signal:o}=e,i={};n.element&&r?.element&&(i.element={dataUrl:n.element,mime:r.element.mime,width:r.element.width,height:r.element.height}),n.fullPage&&r?.fullPage&&(i.fullPage={dataUrl:n.fullPage,mime:r.fullPage.mime,width:r.fullPage.width,height:r.fullPage.height}),Object.keys(i).length!==0&&await fetch(`${ye}/${t}/screenshots`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(i),...o?{signal:o}:{}});}async function Ee(e){let{signal:t,transport:n}=e;if(Date.now()-he<et)return {ok:false,error:p("configuration",new Error("Please wait before submitting again"))};let o=n?.timeoutMs??Ge,i=n?.maxAttempts??Ze,a=n?.backoffMs??Ve,s=!!(e.payload.screenshots?.element?.dataUrl||e.payload.screenshots?.fullPage?.dataUrl),{lean:f,extracted:g}=s?rt(e.payload):{lean:e.payload,extracted:{}},w={...g,...e.screenshotDataUrls};for(let y=1;y<=i;y+=1){let E=new AbortController,h=setTimeout(()=>E.abort(),o),l=()=>E.abort();t&&t.addEventListener("abort",l,{once:true});try{let c=await fetch(ye,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(f),signal:E.signal});if(c.ok){he=Date.now();let u;try{u=await c.json();}catch{}if((w.element||w.fullPage)&&u){let d=u.upload_urls;if(d){let S=[];w.element&&d.element&&S.push(be(d.element,w.element,t)),w.fullPage&&d.fullPage&&S.push(be(d.fullPage,w.fullPage,t));try{await Promise.all(S);}catch{}}else if(u.feedback_id)try{await ot({feedbackId:u.feedback_id,extracted:w,screenshots:e.payload.screenshots,...t?{signal:t}:{}});}catch{}}let x={ok:!0,status:c.status};return u&&(x.apiResponse=u),x}if(y<i&&tt(c.status)){let u=.85+Math.random()*.3,v=Math.round(a*2**(y-1)*u);await we(v,t);continue}return {ok:!1,status:c.status,error:p("api_failed",new Error(`HTTP ${c.status}`))}}catch(c){if(E.signal.aborted||t?.aborted)return {ok:false,error:p("aborted",c)};if(y<i){let u=.85+Math.random()*.3,v=Math.round(a*2**(y-1)*u);await we(v,t);continue}return {ok:false,error:p("api_failed",c)}}finally{clearTimeout(h),t&&t.removeEventListener("abort",l);}}return {ok:false,error:p("api_failed",new Error("Failed"))}}async function Z(e){let{signal:t,transport:n}=e,r={ok:false};try{let o={payload:e.payload,...t?{signal:t}:{},...n?{transport:n}:{}};r.api=await Ee(o),r.ok=!!r.api?.ok;}catch(o){r.api={ok:false,error:p("api_failed",o)},r.ok=false;}return {payload:e.payload,result:r}}var it=["[data-blocfeed-ui]","[data-blocfeed-ignore]"];function at(e){let t=[...it,...e?.ignoreSelectors??[]],n=Array.from(new Set(t));return {...e,ignoreSelectors:n}}function ke(){return {phase:"idle"}}function st(e){if(e.ok)return false;let t=e.api;return t?t.status&&t.status>=400&&t.status<500||t.error?.kind==="aborted"||t.error?.kind==="configuration"?false:!t.ok:true}function $t(e){let t=e,n=ke(),r=new Set,o=new Set,i=null,a=null,s=null,f=null,g=0,w=null,y=()=>{for(let d of r)d(n);},E=d=>{for(let S of o)S(d);},h=d=>{n=d,y();},l=()=>{g+=1,f?.abort(),f=null;},c=()=>{i?.stop(),i=null,E(null),s!==null&&m()&&(document.documentElement.style.cursor=s,s=null);},u=()=>{l(),c(),a=null,h(ke());},v=()=>{if(!m())return;c(),a=null;let d=at(t.picker);s=document.documentElement.style.cursor,document.documentElement.style.cursor="crosshair",h({phase:"picking"}),i=ge(d,{onHover:E,onSelect:({element:S,descriptor:N})=>{a=S,c(),h({phase:"review",selection:N});},onCancel:()=>{u();}});},x=()=>{let d=pe();if(d.length!==0)for(let S of d)Z({payload:S,...t.transport?{transport:t.transport}:{}}).catch(()=>{X(S);});};if(m()){setTimeout(x,1e3);let d=()=>x();window.addEventListener("online",d),w=()=>window.removeEventListener("online",d);}return {getState:()=>n,subscribe(d){return r.add(d),()=>r.delete(d)},subscribeHover(d){return o.add(d),()=>o.delete(d)},start(){n.phase==="capturing"||n.phase==="submitting"||n.phase!=="picking"&&v();},stop(){u();},clearSelection(){n.phase==="capturing"||n.phase==="submitting"||v();},setConfig(d){t=d;},async submit(d,S){if(!m()){let b=p("configuration",new Error("BlocFeed submit can only run in the browser"));return h({phase:"error",lastError:b}),{ok:false}}let N=t.blocfeed_id?.trim?.()??"";if(!N){let F={phase:"error",lastError:p("configuration",new Error("Missing blocfeed_id. Create a project in BlocFeed and pass its blocfeed_id."))};return n.selection&&(F.selection=n.selection),h(F),{ok:false}}if(n.phase==="capturing"||n.phase==="submitting")return {ok:false};let C=g+1;g=C,f?.abort(),f=new AbortController;let T=f.signal,k=n.selection,q=S?.capture?{...t.capture,...S.capture}:t.capture,V=!!(q?.element||q?.fullPage),ee={phase:V?"capturing":"submitting"};k&&(ee.selection=k),h(ee);try{let b=V?await fe({selectionElement:a,capture:q,signal:T}):void 0;if(T.aborted||g!==C)return {ok:!1};let F={phase:"submitting"};k&&(F.selection=k),b&&(F.capture=b),h(F);let R={};k&&(R.selection=k),b&&(R.capture=b);let xe=await me({config:t.metadata,context:R,...t.user?{user:t.user}:{}}),M={version:1,createdAt:new Date().toISOString(),blocfeed_id:N,message:d,metadata:xe};t.user&&(M.user=t.user),k&&(M.selection=k),b&&(M.screenshots=b);let{result:P}=await Z({payload:M,signal:T,...t.transport?{transport:t.transport}:{}});if(T.aborted||g!==C)return P;if(P.ok){let j={phase:"success",lastSubmit:P};return k&&(j.selection=k),b&&(j.capture=b),h(j),P}st(P)&&X(M);let Fe=P.api?.error??p("unknown",new Error("Submission failed")),$={phase:"error",lastSubmit:P,lastError:Fe};return k&&($.selection=k),b&&($.capture=b),h($),P}catch(b){if(T.aborted||g!==C)return {ok:false};let R={phase:"error",lastError:T.aborted?p("aborted",b):p("unknown",b)};return k&&(R.selection=k),h(R),{ok:false}}finally{g===C&&(f=null);}},__unsafeGetSelectedElement(){return a},destroy(){u(),r.clear(),o.clear(),w?.(),w=null;}}}var L=[],_=[],ve=20,Pe=15,I={},D=null,H=false;function lt(e){if(e instanceof Error)return e.message;if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}function ct(e,t){let n=t.map(lt).join(" "),r=t.find(i=>i instanceof Error),o={level:e,message:n.slice(0,2e3),timestamp:Date.now()};for(r?.stack&&(o.stack=r.stack.slice(0,2e3)),L.push(o);L.length>ve;)L.shift();}function Se(e){if(!e.url.includes("blocfeed.com"))for(_.push(e);_.length>Pe;)_.shift();}function Wt(e={}){if(!(H||!m())){if(H=true,ve=e.consoleLimit??20,Pe=e.networkLimit??15,e.console!==false){let t=e.consoleLevels??["error","warn"];for(let n of t)I[n]=console[n],console[n]=(...r)=>{ct(n,r),I[n]?.apply(console,r);};}if(e.network!==false&&typeof window.fetch=="function"){D=window.fetch;let t=D;window.fetch=async function(r,o){let i=typeof r=="string"?r:r instanceof URL?r.toString():r.url,a=(o?.method??"GET").toUpperCase(),s=Date.now();try{let f=await t.call(window,r,o);return f.ok||Se({url:i.slice(0,500),method:a,status:f.status,statusText:f.statusText,timestamp:s,durationMs:Date.now()-s}),f}catch(f){throw Se({url:i.slice(0,500),method:a,status:0,statusText:f instanceof Error?f.message:"Network error",timestamp:s,durationMs:Date.now()-s}),f}};}}}function zt(){if(H){for(let[e,t]of Object.entries(I))console[e]=t;for(let e of Object.keys(I))delete I[e];D&&(window.fetch=D,D=null),H=false;}}function Jt(){return {consoleLogs:[...L],networkErrors:[..._]}}function Yt(){L=[],_=[];}
2
+ exports.a=m;exports.b=Q;exports.c=le;exports.d=fe;exports.e=me;exports.f=X;exports.g=pe;exports.h=vt;exports.i=Pt;exports.j=$t;exports.k=Wt;exports.l=zt;exports.m=Jt;exports.n=Yt;
@@ -0,0 +1,2 @@
1
+ function m(){return typeof window<"u"&&typeof document<"u"}function te(e){let t=globalThis.CSS;return typeof t?.escape=="function"?t.escape(e):e.replace(/[^a-zA-Z0-9_-]/g,n=>{let r=n.codePointAt(0);return r===void 0?"":`\\${r.toString(16)} `})}function Q(e){return {x:e.x,y:e.y,width:e.width,height:e.height}}function Te(e){return {x:e.x+window.scrollX,y:e.y+window.scrollY,width:e.width,height:e.height}}function Re(e){return e.replace(/\s+/g," ").trim()}function Ae(e,t=140){let n=e.textContent;if(!n)return;let r=Re(n);if(r)return r.length<=t?r:`${r.slice(0,t-1)}\u2026`}function Ce(e){let t=1;for(let n=e.previousElementSibling;n;n=n.previousElementSibling)n.tagName===e.tagName&&(t+=1);return t}var oe=["data-testid","data-test-id","data-test","data-qa","data-cy"],ne="data-blocfeed-component";function Me(e){let t=e.closest(`[${ne}]`);if(!t)return;let r=t.getAttribute(ne)?.trim();return r||void 0}function Be(e){for(let t of oe){let n=e.closest(`[${t}]`);if(!n)continue;let o=n.getAttribute(t)?.trim();if(o)return o}}function Le(e){try{let t=e,n=Object.getOwnPropertyNames(t);for(let r of n)if(r.startsWith("__reactFiber$")||r.startsWith("__reactInternalInstance$")){let o=t[r];if(o&&typeof o=="object")return o}}catch{}return null}function B(e){if(e&&typeof e!="string"){if(typeof e=="function"){let t=e;return typeof t.displayName=="string"&&t.displayName?t.displayName:typeof t.name=="string"&&t.name?t.name:void 0}if(typeof e=="object"){let t=e,n=t.displayName;if(typeof n=="string"&&n)return n;let r=t.render;if(typeof r=="function"){let i=r;if(typeof i.displayName=="string"&&i.displayName)return i.displayName;if(typeof i.name=="string"&&i.name)return i.name}let o=t.type;return B(o)}}}function _e(e){let t=Le(e);if(!t)return;let n=t._debugOwner!==void 0;if(n){let i=t._debugOwner;for(let a=0;i&&a<50;a+=1){let s=B(i.type)??B(i.elementType);if(s)return s;i=i._debugOwner;}}let r=t,o=n?80:10;for(let i=0;r&&i<o;i+=1){let a=B(r.type)??B(r.elementType);if(a)return a;r=r.return;}}function Ie(e){let t=e.tagName.toLowerCase(),n=e.getAttribute("id");if(n)return `#${te(n)}`;for(let r of oe){let o=e.getAttribute(r);if(o)return `${t}[${r}="${te(o)}"]`}return `${t}:nth-of-type(${Ce(e)})`}function De(e,t=10){let n=[],r=e;for(;r&&n.length<t;){let o=Ie(r);if(n.unshift(o),o.startsWith("#"))break;r=r.parentElement;}return n.join(" > ")}function re(e,t){if(!t||t.length===0)return false;for(let n of t)if(e.closest(n))return true;return false}function W(e,t){if(!e||re(e,t.ignoreSelectors))return null;let n=e;for(;n;){if(re(n,t.ignoreSelectors))return null;if(t.isSelectable?.(n)??Ne(n))return n;n=n.parentElement;}return null}function Ne(e){let t=e.tagName;return !(t==="HTML"||t==="BODY")}function ie(e){let t=e.getBoundingClientRect(),n={selector:De(e),tagName:e.tagName.toLowerCase(),rect:Q(t),pageRect:Te(t)},r=e.getAttribute("id");r&&(n.id=r);let o=e.className;typeof o=="string"&&o.trim()&&(n.className=o);let i=Ae(e);i&&(n.textSnippet=i);let a=Me(e)??_e(e);a&&(n.componentName=a);let s=Be(e);return s&&(n.testId=s),n}var z=null;async function ae(){return z||(z=import('html-to-image')),z}async function Ue(e){return await new Promise((t,n)=>{let r=new Image;r.onload=()=>t({width:r.naturalWidth,height:r.naturalHeight}),r.onerror=()=>n(new Error("Failed to load generated screenshot")),r.src=e;})}async function se(e,t){let{width:n,height:r}=await Ue(e);return {dataUrl:e,mime:t,width:n,height:r}}function A(e){if(e?.aborted)throw new Error("Aborted")}function le(){return {async captureElement(e,t){if(!m())throw new Error("captureElement can only run in the browser");A(t.signal);let n=await ae();A(t.signal);let r=t.mime==="image/jpeg"?await n.toJpeg(e,{quality:t.quality??.92,pixelRatio:t.pixelRatio}):await n.toPng(e,{pixelRatio:t.pixelRatio});return A(t.signal),await se(r,t.mime)},async captureFullPage(e){if(!m())throw new Error("captureFullPage can only run in the browser");A(e.signal);let t=document.documentElement,n=Math.max(t.scrollWidth,t.clientWidth),r=Math.max(t.scrollHeight,t.clientHeight),o=Math.min(1,e.maxDimension/Math.max(n,r)),i=Math.max(1,Math.round(n*o)),a=Math.max(1,Math.round(r*o)),s=await ae();A(e.signal);let f=e.mime==="image/jpeg"?await s.toJpeg(t,{width:i,height:a,quality:e.quality??.92,pixelRatio:e.pixelRatio}):await s.toPng(t,{width:i,height:a,pixelRatio:e.pixelRatio});return A(e.signal),await se(f,e.mime)}}}function Oe(e){if(e instanceof Error)return e.message;if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return "Unknown error"}}function p(e,t,n){let r={kind:e,message:Oe(t)};return n&&(r.detail=n),r}var He=12e3,qe=2048,$e=.92;function ce(){return Date.now()}function je(e){return new Promise((t,n)=>{let r=()=>n(new Error("Aborted"));if(e.aborted){r();return}e.addEventListener("abort",r,{once:true});})}async function ue(e,t,n){let r=new Promise((i,a)=>{let s=setTimeout(()=>a(new Error("Timeout")),t);typeof s.unref=="function"&&s.unref();}),o=[e,r];return n&&o.push(je(n)),await Promise.race(o)}function Qe(e){if(!m())return 1;let t=window.devicePixelRatio||1,n=e?.pixelRatio??Math.min(t,2);return Math.max(.1,n)}function We(e){return !!(e?.element||e?.fullPage)}function de(e){let t={mime:e.mime,pixelRatio:e.pixelRatio,maxDimension:e.maxDimension};return e.includeQuality&&(t.quality=e.quality),e.signal&&(t.signal=e.signal),t}async function fe(e){let{selectionElement:t,capture:n,signal:r}=e;if(!m()||!We(n))return;let o=ce(),i=[],a=n?.timeoutMs??He,s=n?.maxDimension??qe,f=n?.mime??"image/png",g=n?.quality??$e,w=n?.adapter??le(),y={},E=Qe(n);if(n?.element&&t)try{let c=t.getBoundingClientRect(),u=Math.min(1,s/Math.max(c.width,c.height)),v=Math.min(E,E*u),x=await ue(Promise.resolve(w.captureElement(t,{...de({mime:f,quality:g,pixelRatio:v,maxDimension:s,includeQuality:f==="image/jpeg",...r?{signal:r}:{}})})),a,r);y.element=x;}catch(c){if(r?.aborted)throw c;i.push(p("capture_failed",c,{target:"element"}));}if(n?.fullPage)try{let c=await ue(Promise.resolve(w.captureFullPage(de({mime:f,quality:g,pixelRatio:E,maxDimension:s,includeQuality:f==="image/jpeg",...r?{signal:r}:{}}))),a,r);y.fullPage=c;}catch(c){if(r?.aborted)throw c;i.push(p("capture_failed",c,{target:"fullPage"}));}let h=ce(),l={startedAt:o,finishedAt:h,durationMs:Math.max(0,h-o)};return i.length>0&&(l.errors=i),{...y,diagnostics:l}}function ze(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return}}function Je(){return m()?{url:window.location.href,title:document.title,referrer:document.referrer||void 0,userAgent:navigator.userAgent,language:navigator.language,platform:navigator.platform,viewport:{width:window.innerWidth,height:window.innerHeight},screen:{width:window.screen.width,height:window.screen.height},scroll:{x:window.scrollX,y:window.scrollY},devicePixelRatio:window.devicePixelRatio||1,timezone:ze()}:{}}function Ye(e){if(!e)return {};let t={};return e.id&&(t.userId=e.id),e.email&&(t.userEmail=e.email),e.name&&(t.userName=e.name),t}async function me(e){let{config:t,context:n,user:r}=e;if(t?.enabled===false)return {};let o={...Je(),...Ye(r)},i=t?.enrich;if(!i)return o;try{let a=await i(n);return {...o,...a}}catch(a){let s=p("unknown",a);return {...o,blocfeedMetadataError:s.message}}}var J="blocfeed-queue",Ke=50;function Y(){if(!m())return [];try{let e=localStorage.getItem(J);if(!e)return [];let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return []}}function K(e){if(m())try{e.length===0?localStorage.removeItem(J):localStorage.setItem(J,JSON.stringify(e));}catch{}}function Xe(e){let t={...e};if(t.screenshots){let n={...t.screenshots};n.element&&(n.element={...n.element,dataUrl:""}),n.fullPage&&(n.fullPage={...n.fullPage,dataUrl:""}),t.screenshots=n;}return t}function X(e){let t=Y(),n=Xe(e);for(n.metadata={...n.metadata,_queued:true},t.push({payload:n,timestamp:Date.now()});t.length>Ke;)t.shift();K(t);}function pe(){let e=Y();return e.length===0?[]:(K([]),e.map(t=>t.payload))}function vt(){K([]);}function Pt(){return Y().length}function G(e){let t=null,n=null,r=(...o)=>{n=o,t===null&&(t=requestAnimationFrame(()=>{if(t=null,!n)return;let i=n;n=null,e(...i);}));};return r.cancel=()=>{t!==null&&cancelAnimationFrame(t),t=null,n=null;},r}function U(e){return e instanceof Element?!!e.closest("[data-blocfeed-ui]"):false}function O(e){e.stopPropagation(),e.stopImmediatePropagation?.();}function ge(e,t){if(!m())throw new Error("BlocFeed picker can only run in a browser environment.");let n=e.ignoreSelectors,r=e.isSelectable,o={};n&&n.length>0&&(o.ignoreSelectors=n),r&&(o.isSelectable=r);let i=null,a=null,s=(l,c=false)=>{if(!l){i=null,a=null,t.onHover(null);return}let u=Q(l.getBoundingClientRect()),v=`${Math.round(u.x)}:${Math.round(u.y)}:${Math.round(u.width)}:${Math.round(u.height)}`;!c&&l===i&&v===a||(i=l,a=v,t.onHover({element:l,rect:u}));},f=G(l=>{if(U(l.target))return;let c=document.elementFromPoint(l.clientX,l.clientY),u=W(c,o);s(u);}),g=G(()=>{i&&s(i,true);}),w=l=>{U(l.target)||(O(l),l.pointerType==="mouse"&&l.preventDefault());},y=l=>{U(l.target)||(O(l),l.pointerType==="mouse"&&l.preventDefault());},E=l=>{if(U(l.target))return;O(l),l.preventDefault();let c=document.elementFromPoint(l.clientX,l.clientY),u=W(c,o);u&&t.onSelect({element:u,descriptor:ie(u)});},h=l=>{l.key==="Escape"&&(O(l),l.preventDefault(),t.onCancel());};return window.addEventListener("pointermove",f,{capture:true,passive:true}),window.addEventListener("pointerdown",w,{capture:true}),window.addEventListener("pointerup",y,{capture:true}),window.addEventListener("click",E,{capture:true}),window.addEventListener("keydown",h,{capture:true}),window.addEventListener("scroll",g,{capture:true,passive:true}),window.addEventListener("resize",g,{passive:true}),{stop(){window.removeEventListener("pointermove",f,{capture:true}),window.removeEventListener("pointerdown",w,{capture:true}),window.removeEventListener("pointerup",y,{capture:true}),window.removeEventListener("click",E,{capture:true}),window.removeEventListener("keydown",h,{capture:true}),window.removeEventListener("scroll",g,{capture:true}),window.removeEventListener("resize",g),f.cancel(),g.cancel(),t.onHover(null);}}}var Ge=12e3,Ze=2,Ve=500,et=2e3,ye="https://blocfeed.com/api/feedback",he=0;function we(e,t){return new Promise((n,r)=>{if(t?.aborted){r(new Error("Aborted"));return}let o=setTimeout(n,e),i=()=>{clearTimeout(o),r(new Error("Aborted"));};t?.addEventListener("abort",i,{once:true});})}function tt(e){return e>=500&&e<=599}function nt(e){let[t,n]=e.split(",",2);if(!t||!n)throw new Error("Invalid data URL");let o=/data:(.*?);base64/.exec(t)?.[1]||"application/octet-stream",i=atob(n),a=new Uint8Array(i.length);for(let s=0;s<i.length;s+=1)a[s]=i.charCodeAt(s);return new Blob([a],{type:o})}function rt(e){let t={},n={...e};if(n.screenshots){let r={},o={...n.screenshots};o.element&&(t.element=o.element.dataUrl,r.element={mime:o.element.mime,width:o.element.width,height:o.element.height},o.element={...o.element,dataUrl:""}),o.fullPage&&(t.fullPage=o.fullPage.dataUrl,r.fullPage={mime:o.fullPage.mime,width:o.fullPage.width,height:o.fullPage.height},o.fullPage={...o.fullPage,dataUrl:""}),n.screenshots=o,(r.element||r.fullPage)&&(n.screenshot_intent=r);}return {lean:n,extracted:t}}async function be(e,t,n){let r=nt(t);await fetch(e,{method:"PUT",body:r,headers:{"content-type":r.type},...n?{signal:n}:{}});}async function ot(e){let{feedbackId:t,extracted:n,screenshots:r,signal:o}=e,i={};n.element&&r?.element&&(i.element={dataUrl:n.element,mime:r.element.mime,width:r.element.width,height:r.element.height}),n.fullPage&&r?.fullPage&&(i.fullPage={dataUrl:n.fullPage,mime:r.fullPage.mime,width:r.fullPage.width,height:r.fullPage.height}),Object.keys(i).length!==0&&await fetch(`${ye}/${t}/screenshots`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(i),...o?{signal:o}:{}});}async function Ee(e){let{signal:t,transport:n}=e;if(Date.now()-he<et)return {ok:false,error:p("configuration",new Error("Please wait before submitting again"))};let o=n?.timeoutMs??Ge,i=n?.maxAttempts??Ze,a=n?.backoffMs??Ve,s=!!(e.payload.screenshots?.element?.dataUrl||e.payload.screenshots?.fullPage?.dataUrl),{lean:f,extracted:g}=s?rt(e.payload):{lean:e.payload,extracted:{}},w={...g,...e.screenshotDataUrls};for(let y=1;y<=i;y+=1){let E=new AbortController,h=setTimeout(()=>E.abort(),o),l=()=>E.abort();t&&t.addEventListener("abort",l,{once:true});try{let c=await fetch(ye,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(f),signal:E.signal});if(c.ok){he=Date.now();let u;try{u=await c.json();}catch{}if((w.element||w.fullPage)&&u){let d=u.upload_urls;if(d){let S=[];w.element&&d.element&&S.push(be(d.element,w.element,t)),w.fullPage&&d.fullPage&&S.push(be(d.fullPage,w.fullPage,t));try{await Promise.all(S);}catch{}}else if(u.feedback_id)try{await ot({feedbackId:u.feedback_id,extracted:w,screenshots:e.payload.screenshots,...t?{signal:t}:{}});}catch{}}let x={ok:!0,status:c.status};return u&&(x.apiResponse=u),x}if(y<i&&tt(c.status)){let u=.85+Math.random()*.3,v=Math.round(a*2**(y-1)*u);await we(v,t);continue}return {ok:!1,status:c.status,error:p("api_failed",new Error(`HTTP ${c.status}`))}}catch(c){if(E.signal.aborted||t?.aborted)return {ok:false,error:p("aborted",c)};if(y<i){let u=.85+Math.random()*.3,v=Math.round(a*2**(y-1)*u);await we(v,t);continue}return {ok:false,error:p("api_failed",c)}}finally{clearTimeout(h),t&&t.removeEventListener("abort",l);}}return {ok:false,error:p("api_failed",new Error("Failed"))}}async function Z(e){let{signal:t,transport:n}=e,r={ok:false};try{let o={payload:e.payload,...t?{signal:t}:{},...n?{transport:n}:{}};r.api=await Ee(o),r.ok=!!r.api?.ok;}catch(o){r.api={ok:false,error:p("api_failed",o)},r.ok=false;}return {payload:e.payload,result:r}}var it=["[data-blocfeed-ui]","[data-blocfeed-ignore]"];function at(e){let t=[...it,...e?.ignoreSelectors??[]],n=Array.from(new Set(t));return {...e,ignoreSelectors:n}}function ke(){return {phase:"idle"}}function st(e){if(e.ok)return false;let t=e.api;return t?t.status&&t.status>=400&&t.status<500||t.error?.kind==="aborted"||t.error?.kind==="configuration"?false:!t.ok:true}function $t(e){let t=e,n=ke(),r=new Set,o=new Set,i=null,a=null,s=null,f=null,g=0,w=null,y=()=>{for(let d of r)d(n);},E=d=>{for(let S of o)S(d);},h=d=>{n=d,y();},l=()=>{g+=1,f?.abort(),f=null;},c=()=>{i?.stop(),i=null,E(null),s!==null&&m()&&(document.documentElement.style.cursor=s,s=null);},u=()=>{l(),c(),a=null,h(ke());},v=()=>{if(!m())return;c(),a=null;let d=at(t.picker);s=document.documentElement.style.cursor,document.documentElement.style.cursor="crosshair",h({phase:"picking"}),i=ge(d,{onHover:E,onSelect:({element:S,descriptor:N})=>{a=S,c(),h({phase:"review",selection:N});},onCancel:()=>{u();}});},x=()=>{let d=pe();if(d.length!==0)for(let S of d)Z({payload:S,...t.transport?{transport:t.transport}:{}}).catch(()=>{X(S);});};if(m()){setTimeout(x,1e3);let d=()=>x();window.addEventListener("online",d),w=()=>window.removeEventListener("online",d);}return {getState:()=>n,subscribe(d){return r.add(d),()=>r.delete(d)},subscribeHover(d){return o.add(d),()=>o.delete(d)},start(){n.phase==="capturing"||n.phase==="submitting"||n.phase!=="picking"&&v();},stop(){u();},clearSelection(){n.phase==="capturing"||n.phase==="submitting"||v();},setConfig(d){t=d;},async submit(d,S){if(!m()){let b=p("configuration",new Error("BlocFeed submit can only run in the browser"));return h({phase:"error",lastError:b}),{ok:false}}let N=t.blocfeed_id?.trim?.()??"";if(!N){let F={phase:"error",lastError:p("configuration",new Error("Missing blocfeed_id. Create a project in BlocFeed and pass its blocfeed_id."))};return n.selection&&(F.selection=n.selection),h(F),{ok:false}}if(n.phase==="capturing"||n.phase==="submitting")return {ok:false};let C=g+1;g=C,f?.abort(),f=new AbortController;let T=f.signal,k=n.selection,q=S?.capture?{...t.capture,...S.capture}:t.capture,V=!!(q?.element||q?.fullPage),ee={phase:V?"capturing":"submitting"};k&&(ee.selection=k),h(ee);try{let b=V?await fe({selectionElement:a,capture:q,signal:T}):void 0;if(T.aborted||g!==C)return {ok:!1};let F={phase:"submitting"};k&&(F.selection=k),b&&(F.capture=b),h(F);let R={};k&&(R.selection=k),b&&(R.capture=b);let xe=await me({config:t.metadata,context:R,...t.user?{user:t.user}:{}}),M={version:1,createdAt:new Date().toISOString(),blocfeed_id:N,message:d,metadata:xe};t.user&&(M.user=t.user),k&&(M.selection=k),b&&(M.screenshots=b);let{result:P}=await Z({payload:M,signal:T,...t.transport?{transport:t.transport}:{}});if(T.aborted||g!==C)return P;if(P.ok){let j={phase:"success",lastSubmit:P};return k&&(j.selection=k),b&&(j.capture=b),h(j),P}st(P)&&X(M);let Fe=P.api?.error??p("unknown",new Error("Submission failed")),$={phase:"error",lastSubmit:P,lastError:Fe};return k&&($.selection=k),b&&($.capture=b),h($),P}catch(b){if(T.aborted||g!==C)return {ok:false};let R={phase:"error",lastError:T.aborted?p("aborted",b):p("unknown",b)};return k&&(R.selection=k),h(R),{ok:false}}finally{g===C&&(f=null);}},__unsafeGetSelectedElement(){return a},destroy(){u(),r.clear(),o.clear(),w?.(),w=null;}}}var L=[],_=[],ve=20,Pe=15,I={},D=null,H=false;function lt(e){if(e instanceof Error)return e.message;if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}function ct(e,t){let n=t.map(lt).join(" "),r=t.find(i=>i instanceof Error),o={level:e,message:n.slice(0,2e3),timestamp:Date.now()};for(r?.stack&&(o.stack=r.stack.slice(0,2e3)),L.push(o);L.length>ve;)L.shift();}function Se(e){if(!e.url.includes("blocfeed.com"))for(_.push(e);_.length>Pe;)_.shift();}function Wt(e={}){if(!(H||!m())){if(H=true,ve=e.consoleLimit??20,Pe=e.networkLimit??15,e.console!==false){let t=e.consoleLevels??["error","warn"];for(let n of t)I[n]=console[n],console[n]=(...r)=>{ct(n,r),I[n]?.apply(console,r);};}if(e.network!==false&&typeof window.fetch=="function"){D=window.fetch;let t=D;window.fetch=async function(r,o){let i=typeof r=="string"?r:r instanceof URL?r.toString():r.url,a=(o?.method??"GET").toUpperCase(),s=Date.now();try{let f=await t.call(window,r,o);return f.ok||Se({url:i.slice(0,500),method:a,status:f.status,statusText:f.statusText,timestamp:s,durationMs:Date.now()-s}),f}catch(f){throw Se({url:i.slice(0,500),method:a,status:0,statusText:f instanceof Error?f.message:"Network error",timestamp:s,durationMs:Date.now()-s}),f}};}}}function zt(){if(H){for(let[e,t]of Object.entries(I))console[e]=t;for(let e of Object.keys(I))delete I[e];D&&(window.fetch=D,D=null),H=false;}}function Jt(){return {consoleLogs:[...L],networkErrors:[..._]}}function Yt(){L=[],_=[];}
2
+ export{m as a,Q as b,le as c,fe as d,me as e,X as f,pe as g,vt as h,Pt as i,$t as j,Wt as k,zt as l,Jt as m,Yt as n};
@@ -24,13 +24,55 @@ interface TransportConfig {
24
24
  backoffMs?: number;
25
25
  }
26
26
  type WidgetPosition = "bottom-right" | "bottom-left" | "top-right" | "top-left";
27
- type TriggerStyle = "classic" | "dot" | "bubble" | "edge-tab" | "pulse-ring" | "minimal" | "icon-pop";
27
+ type TriggerStyle = "classic" | "dot" | "bubble" | "edge-tab" | "pulse-ring" | "minimal" | "icon-pop" | "beacon" | "typewriter";
28
28
  interface ThemeConfig {
29
29
  accentColor?: string;
30
30
  panelBackground?: string;
31
31
  panelForeground?: string;
32
32
  fontFamily?: string;
33
33
  }
34
+ interface BlocFeedStrings {
35
+ triggerLabel?: string;
36
+ panelTitle?: string;
37
+ hintText?: string;
38
+ cancelButton?: string;
39
+ rePickButton?: string;
40
+ closeButton?: string;
41
+ textareaPlaceholder?: string;
42
+ screenshotElement?: string;
43
+ screenshotFullPage?: string;
44
+ capturingText?: string;
45
+ submittingText?: string;
46
+ successText?: string;
47
+ toastText?: string;
48
+ sendButton?: string;
49
+ }
50
+ interface ConsoleEntry {
51
+ level: "error" | "warn" | "log";
52
+ message: string;
53
+ timestamp: number;
54
+ stack?: string;
55
+ }
56
+ interface NetworkEntry {
57
+ url: string;
58
+ method: string;
59
+ status: number;
60
+ statusText?: string;
61
+ timestamp: number;
62
+ durationMs?: number;
63
+ }
64
+ interface DiagnosticsConfig {
65
+ /** Capture console errors/warnings. Default: true when diagnostics is set. */
66
+ console?: boolean;
67
+ /** Console levels to capture. Default: ["error", "warn"] */
68
+ consoleLevels?: ("error" | "warn" | "log")[];
69
+ /** Max console entries to retain. Default: 20 */
70
+ consoleLimit?: number;
71
+ /** Capture failed network requests (fetch). Default: true when diagnostics is set. */
72
+ network?: boolean;
73
+ /** Max network entries to retain. Default: 15 */
74
+ networkLimit?: number;
75
+ }
34
76
  interface Rect {
35
77
  x: number;
36
78
  y: number;
@@ -146,6 +188,8 @@ interface BlocFeedConfig {
146
188
  user?: BlocFeedUser;
147
189
  /** Transport / retry configuration. */
148
190
  transport?: TransportConfig;
191
+ /** Diagnostics capture (console logs + failed network requests). */
192
+ diagnostics?: DiagnosticsConfig;
149
193
  ui?: {
150
194
  /** z-index for the widget overlay/panel. */
151
195
  zIndex?: number;
@@ -155,6 +199,14 @@ interface BlocFeedConfig {
155
199
  theme?: ThemeConfig;
156
200
  /** Trigger button animation style. Default: "classic" */
157
201
  triggerStyle?: TriggerStyle;
202
+ /** Custom label text for the trigger button. Default: "Feedback" */
203
+ triggerLabel?: string;
204
+ /** Keyboard shortcut to toggle the widget. e.g. "ctrl+shift+f" */
205
+ shortcut?: string;
206
+ /** UI string overrides for i18n / localization. */
207
+ strings?: BlocFeedStrings;
208
+ /** Show "Powered by BlocFeed" watermark. Default: true */
209
+ branding?: boolean;
158
210
  };
159
211
  }
160
212
  interface ScreenshotIntent {
@@ -232,4 +284,4 @@ interface BlocFeedController {
232
284
  }
233
285
  declare function createBlocFeedController(config: BlocFeedConfig): BlocFeedController;
234
286
 
235
- export { type BlocFeedConfig as B, type CaptureConfig as C, type ElementDescriptor as E, type FeedbackApiResponse as F, type HoverListener as H, type ImageAsset as I, type MaybePromise as M, type PickerConfig as P, type Rect as R, type SubmitResult as S, type ThemeConfig as T, type WidgetPosition as W, type BlocFeedState as a, type BlocFeedController as b, type BlocFeedError as c, type BlocFeedUser as d, type CaptureDiagnostics as e, type CaptureResult as f, type FeedbackPayload as g, type MetadataConfig as h, type MetadataContext as i, type ScreenshotAdapter as j, type ScreenshotAdapterOptions as k, type ScreenshotIntent as l, type ScreenshotMime as m, type SessionPhase as n, type TransportConfig as o, type TransportResult as p, type TriggerStyle as q, type StateListener as r, createBlocFeedController as s };
287
+ export { type BlocFeedConfig as B, type CaptureConfig as C, type DiagnosticsConfig as D, type ElementDescriptor as E, type FeedbackApiResponse as F, type HoverListener as H, type ImageAsset as I, type MaybePromise as M, type NetworkEntry as N, type PickerConfig as P, type Rect as R, type SubmitResult as S, type ThemeConfig as T, type WidgetPosition as W, type BlocFeedState as a, type BlocFeedController as b, type BlocFeedError as c, type BlocFeedStrings as d, type BlocFeedUser as e, type CaptureDiagnostics as f, type CaptureResult as g, type ConsoleEntry as h, type FeedbackPayload as i, type MetadataConfig as j, type MetadataContext as k, type ScreenshotAdapter as l, type ScreenshotAdapterOptions as m, type ScreenshotIntent as n, type ScreenshotMime as o, type SessionPhase as p, type TransportConfig as q, type TransportResult as r, type TriggerStyle as s, type StateListener as t, createBlocFeedController as u };
@@ -24,13 +24,55 @@ interface TransportConfig {
24
24
  backoffMs?: number;
25
25
  }
26
26
  type WidgetPosition = "bottom-right" | "bottom-left" | "top-right" | "top-left";
27
- type TriggerStyle = "classic" | "dot" | "bubble" | "edge-tab" | "pulse-ring" | "minimal" | "icon-pop";
27
+ type TriggerStyle = "classic" | "dot" | "bubble" | "edge-tab" | "pulse-ring" | "minimal" | "icon-pop" | "beacon" | "typewriter";
28
28
  interface ThemeConfig {
29
29
  accentColor?: string;
30
30
  panelBackground?: string;
31
31
  panelForeground?: string;
32
32
  fontFamily?: string;
33
33
  }
34
+ interface BlocFeedStrings {
35
+ triggerLabel?: string;
36
+ panelTitle?: string;
37
+ hintText?: string;
38
+ cancelButton?: string;
39
+ rePickButton?: string;
40
+ closeButton?: string;
41
+ textareaPlaceholder?: string;
42
+ screenshotElement?: string;
43
+ screenshotFullPage?: string;
44
+ capturingText?: string;
45
+ submittingText?: string;
46
+ successText?: string;
47
+ toastText?: string;
48
+ sendButton?: string;
49
+ }
50
+ interface ConsoleEntry {
51
+ level: "error" | "warn" | "log";
52
+ message: string;
53
+ timestamp: number;
54
+ stack?: string;
55
+ }
56
+ interface NetworkEntry {
57
+ url: string;
58
+ method: string;
59
+ status: number;
60
+ statusText?: string;
61
+ timestamp: number;
62
+ durationMs?: number;
63
+ }
64
+ interface DiagnosticsConfig {
65
+ /** Capture console errors/warnings. Default: true when diagnostics is set. */
66
+ console?: boolean;
67
+ /** Console levels to capture. Default: ["error", "warn"] */
68
+ consoleLevels?: ("error" | "warn" | "log")[];
69
+ /** Max console entries to retain. Default: 20 */
70
+ consoleLimit?: number;
71
+ /** Capture failed network requests (fetch). Default: true when diagnostics is set. */
72
+ network?: boolean;
73
+ /** Max network entries to retain. Default: 15 */
74
+ networkLimit?: number;
75
+ }
34
76
  interface Rect {
35
77
  x: number;
36
78
  y: number;
@@ -146,6 +188,8 @@ interface BlocFeedConfig {
146
188
  user?: BlocFeedUser;
147
189
  /** Transport / retry configuration. */
148
190
  transport?: TransportConfig;
191
+ /** Diagnostics capture (console logs + failed network requests). */
192
+ diagnostics?: DiagnosticsConfig;
149
193
  ui?: {
150
194
  /** z-index for the widget overlay/panel. */
151
195
  zIndex?: number;
@@ -155,6 +199,14 @@ interface BlocFeedConfig {
155
199
  theme?: ThemeConfig;
156
200
  /** Trigger button animation style. Default: "classic" */
157
201
  triggerStyle?: TriggerStyle;
202
+ /** Custom label text for the trigger button. Default: "Feedback" */
203
+ triggerLabel?: string;
204
+ /** Keyboard shortcut to toggle the widget. e.g. "ctrl+shift+f" */
205
+ shortcut?: string;
206
+ /** UI string overrides for i18n / localization. */
207
+ strings?: BlocFeedStrings;
208
+ /** Show "Powered by BlocFeed" watermark. Default: true */
209
+ branding?: boolean;
158
210
  };
159
211
  }
160
212
  interface ScreenshotIntent {
@@ -232,4 +284,4 @@ interface BlocFeedController {
232
284
  }
233
285
  declare function createBlocFeedController(config: BlocFeedConfig): BlocFeedController;
234
286
 
235
- export { type BlocFeedConfig as B, type CaptureConfig as C, type ElementDescriptor as E, type FeedbackApiResponse as F, type HoverListener as H, type ImageAsset as I, type MaybePromise as M, type PickerConfig as P, type Rect as R, type SubmitResult as S, type ThemeConfig as T, type WidgetPosition as W, type BlocFeedState as a, type BlocFeedController as b, type BlocFeedError as c, type BlocFeedUser as d, type CaptureDiagnostics as e, type CaptureResult as f, type FeedbackPayload as g, type MetadataConfig as h, type MetadataContext as i, type ScreenshotAdapter as j, type ScreenshotAdapterOptions as k, type ScreenshotIntent as l, type ScreenshotMime as m, type SessionPhase as n, type TransportConfig as o, type TransportResult as p, type TriggerStyle as q, type StateListener as r, createBlocFeedController as s };
287
+ export { type BlocFeedConfig as B, type CaptureConfig as C, type DiagnosticsConfig as D, type ElementDescriptor as E, type FeedbackApiResponse as F, type HoverListener as H, type ImageAsset as I, type MaybePromise as M, type NetworkEntry as N, type PickerConfig as P, type Rect as R, type SubmitResult as S, type ThemeConfig as T, type WidgetPosition as W, type BlocFeedState as a, type BlocFeedController as b, type BlocFeedError as c, type BlocFeedStrings as d, type BlocFeedUser as e, type CaptureDiagnostics as f, type CaptureResult as g, type ConsoleEntry as h, type FeedbackPayload as i, type MetadataConfig as j, type MetadataContext as k, type ScreenshotAdapter as l, type ScreenshotAdapterOptions as m, type ScreenshotIntent as n, type ScreenshotMime as o, type SessionPhase as p, type TransportConfig as q, type TransportResult as r, type TriggerStyle as s, type StateListener as t, createBlocFeedController as u };
package/dist/engine.cjs CHANGED
@@ -1 +1 @@
1
- 'use strict';var chunkJLPJP7DD_cjs=require('./chunk-JLPJP7DD.cjs');function c(o){if(o?.aborted)throw new Error("Aborted")}async function A(o){return await new Promise((t,e)=>{let r=new Image;r.onload=()=>t({width:r.naturalWidth,height:r.naturalHeight}),r.onerror=()=>e(new Error("Failed to load generated screenshot")),r.src=o;})}async function l(o,t){let{width:e,height:r}=await A(o);return {dataUrl:o,mime:t,width:e,height:r}}function x(o){return {async captureElement(t,e){if(!chunkJLPJP7DD_cjs.a())throw new Error("captureElement can only run in the browser");c(e.signal);let r={scale:e.pixelRatio},n=e.mime==="image/jpeg"?await o.domToJpeg(t,{...r,quality:e.quality??.92}):await o.domToPng(t,r);return c(e.signal),await l(n,e.mime)},async captureFullPage(t){if(!chunkJLPJP7DD_cjs.a())throw new Error("captureFullPage can only run in the browser");c(t.signal);let e=document.documentElement,r=Math.max(e.scrollWidth,e.clientWidth),n=Math.max(e.scrollHeight,e.clientHeight),a=Math.min(1,t.maxDimension/Math.max(r,n)),s={width:Math.max(1,Math.round(r*a)),height:Math.max(1,Math.round(n*a)),scale:t.pixelRatio},i=t.mime==="image/jpeg"?await o.domToJpeg(e,{...s,quality:t.quality??.92}):await o.domToPng(e,s);return c(t.signal),await l(i,t.mime)}}}function b(o){let[t,e]=o.split(",",2);if(!t||!e)throw new Error("Invalid data URL");let n=/data:(.*?);base64/.exec(t)?.[1]||"application/octet-stream",a=atob(e),s=new Uint8Array(a.length);for(let i=0;i<a.length;i+=1)s[i]=a.charCodeAt(i);return new Blob([s],{type:n})}Object.defineProperty(exports,"clearQueue",{enumerable:true,get:function(){return chunkJLPJP7DD_cjs.h}});Object.defineProperty(exports,"collectMetadata",{enumerable:true,get:function(){return chunkJLPJP7DD_cjs.e}});Object.defineProperty(exports,"createBlocFeedController",{enumerable:true,get:function(){return chunkJLPJP7DD_cjs.j}});Object.defineProperty(exports,"createHtmlToImageAdapter",{enumerable:true,get:function(){return chunkJLPJP7DD_cjs.c}});Object.defineProperty(exports,"dequeueAll",{enumerable:true,get:function(){return chunkJLPJP7DD_cjs.g}});Object.defineProperty(exports,"enqueue",{enumerable:true,get:function(){return chunkJLPJP7DD_cjs.f}});Object.defineProperty(exports,"getQueueSize",{enumerable:true,get:function(){return chunkJLPJP7DD_cjs.i}});Object.defineProperty(exports,"runCapture",{enumerable:true,get:function(){return chunkJLPJP7DD_cjs.d}});exports.createModernScreenshotAdapter=x;exports.dataUrlToBlob=b;
1
+ 'use strict';var chunkD5SBICBQ_cjs=require('./chunk-D5SBICBQ.cjs');function c(o){if(o?.aborted)throw new Error("Aborted")}async function b(o){return await new Promise((t,e)=>{let r=new Image;r.onload=()=>t({width:r.naturalWidth,height:r.naturalHeight}),r.onerror=()=>e(new Error("Failed to load generated screenshot")),r.src=o;})}async function d(o,t){let{width:e,height:r}=await b(o);return {dataUrl:o,mime:t,width:e,height:r}}function E(o){return {async captureElement(t,e){if(!chunkD5SBICBQ_cjs.a())throw new Error("captureElement can only run in the browser");c(e.signal);let r={scale:e.pixelRatio},n=e.mime==="image/jpeg"?await o.domToJpeg(t,{...r,quality:e.quality??.92}):await o.domToPng(t,r);return c(e.signal),await d(n,e.mime)},async captureFullPage(t){if(!chunkD5SBICBQ_cjs.a())throw new Error("captureFullPage can only run in the browser");c(t.signal);let e=document.documentElement,r=Math.max(e.scrollWidth,e.clientWidth),n=Math.max(e.scrollHeight,e.clientHeight),a=Math.min(1,t.maxDimension/Math.max(r,n)),s={width:Math.max(1,Math.round(r*a)),height:Math.max(1,Math.round(n*a)),scale:t.pixelRatio},i=t.mime==="image/jpeg"?await o.domToJpeg(e,{...s,quality:t.quality??.92}):await o.domToPng(e,s);return c(t.signal),await d(i,t.mime)}}}function B(o){let[t,e]=o.split(",",2);if(!t||!e)throw new Error("Invalid data URL");let n=/data:(.*?);base64/.exec(t)?.[1]||"application/octet-stream",a=atob(e),s=new Uint8Array(a.length);for(let i=0;i<a.length;i+=1)s[i]=a.charCodeAt(i);return new Blob([s],{type:n})}Object.defineProperty(exports,"clearDiagnostics",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.n}});Object.defineProperty(exports,"clearQueue",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.h}});Object.defineProperty(exports,"collectMetadata",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.e}});Object.defineProperty(exports,"createBlocFeedController",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.j}});Object.defineProperty(exports,"createHtmlToImageAdapter",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.c}});Object.defineProperty(exports,"dequeueAll",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.g}});Object.defineProperty(exports,"drainDiagnostics",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.m}});Object.defineProperty(exports,"enqueue",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.f}});Object.defineProperty(exports,"getQueueSize",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.i}});Object.defineProperty(exports,"installDiagnostics",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.k}});Object.defineProperty(exports,"runCapture",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.d}});Object.defineProperty(exports,"uninstallDiagnostics",{enumerable:true,get:function(){return chunkD5SBICBQ_cjs.l}});exports.createModernScreenshotAdapter=E;exports.dataUrlToBlob=B;
package/dist/engine.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { j as ScreenshotAdapter, C as CaptureConfig, f as CaptureResult, h as MetadataConfig, i as MetadataContext, d as BlocFeedUser, g as FeedbackPayload } from './controller-D7kOehzb.cjs';
2
- export { B as BlocFeedConfig, b as BlocFeedController, c as BlocFeedError, a as BlocFeedState, E as ElementDescriptor, F as FeedbackApiResponse, H as HoverListener, I as ImageAsset, R as Rect, k as ScreenshotAdapterOptions, l as ScreenshotIntent, m as ScreenshotMime, n as SessionPhase, r as StateListener, S as SubmitResult, T as ThemeConfig, o as TransportConfig, q as TriggerStyle, W as WidgetPosition, s as createBlocFeedController } from './controller-D7kOehzb.cjs';
1
+ import { l as ScreenshotAdapter, C as CaptureConfig, g as CaptureResult, j as MetadataConfig, k as MetadataContext, e as BlocFeedUser, i as FeedbackPayload } from './controller-DfhbkHXc.cjs';
2
+ export { B as BlocFeedConfig, b as BlocFeedController, c as BlocFeedError, a as BlocFeedState, d as BlocFeedStrings, h as ConsoleEntry, D as DiagnosticsConfig, E as ElementDescriptor, F as FeedbackApiResponse, H as HoverListener, I as ImageAsset, N as NetworkEntry, R as Rect, m as ScreenshotAdapterOptions, n as ScreenshotIntent, o as ScreenshotMime, p as SessionPhase, t as StateListener, S as SubmitResult, T as ThemeConfig, q as TransportConfig, s as TriggerStyle, W as WidgetPosition, u as createBlocFeedController } from './controller-DfhbkHXc.cjs';
3
3
 
4
4
  declare function createHtmlToImageAdapter(): ScreenshotAdapter;
5
5
 
@@ -62,6 +62,54 @@ declare function clearQueue(): void;
62
62
  */
63
63
  declare function getQueueSize(): number;
64
64
 
65
+ interface ConsoleEntry {
66
+ level: "error" | "warn" | "log";
67
+ message: string;
68
+ timestamp: number;
69
+ stack?: string;
70
+ }
71
+ interface NetworkEntry {
72
+ url: string;
73
+ method: string;
74
+ status: number;
75
+ statusText?: string;
76
+ timestamp: number;
77
+ durationMs?: number;
78
+ }
79
+ interface DiagnosticsConfig {
80
+ /** Capture console errors/warnings. Default: true when diagnostics is set. */
81
+ console?: boolean;
82
+ /** Console levels to capture. Default: ["error", "warn"] */
83
+ consoleLevels?: ("error" | "warn" | "log")[];
84
+ /** Max console entries to retain. Default: 20 */
85
+ consoleLimit?: number;
86
+ /** Capture failed network requests (fetch). Default: true when diagnostics is set. */
87
+ network?: boolean;
88
+ /** Max network entries to retain. Default: 15 */
89
+ networkLimit?: number;
90
+ }
91
+ interface DiagnosticsSnapshot {
92
+ consoleLogs: ConsoleEntry[];
93
+ networkErrors: NetworkEntry[];
94
+ }
95
+ /**
96
+ * Install console and/or network interceptors.
97
+ * Safe to call multiple times — subsequent calls are no-ops.
98
+ */
99
+ declare function installDiagnostics(config?: DiagnosticsConfig): void;
100
+ /**
101
+ * Remove all interceptors and restore originals.
102
+ */
103
+ declare function uninstallDiagnostics(): void;
104
+ /**
105
+ * Return a copy of all captured entries (non-destructive read).
106
+ */
107
+ declare function drainDiagnostics(): DiagnosticsSnapshot;
108
+ /**
109
+ * Clear all captured entries.
110
+ */
111
+ declare function clearDiagnostics(): void;
112
+
65
113
  declare function dataUrlToBlob(dataUrl: string): Blob;
66
114
 
67
- export { BlocFeedUser, CaptureResult, FeedbackPayload, type ModernScreenshotModule, ScreenshotAdapter, clearQueue, collectMetadata, createHtmlToImageAdapter, createModernScreenshotAdapter, dataUrlToBlob, dequeueAll, enqueue, getQueueSize, runCapture };
115
+ export { BlocFeedUser, CaptureResult, FeedbackPayload, type ModernScreenshotModule, ScreenshotAdapter, clearDiagnostics, clearQueue, collectMetadata, createHtmlToImageAdapter, createModernScreenshotAdapter, dataUrlToBlob, dequeueAll, drainDiagnostics, enqueue, getQueueSize, installDiagnostics, runCapture, uninstallDiagnostics };
package/dist/engine.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { j as ScreenshotAdapter, C as CaptureConfig, f as CaptureResult, h as MetadataConfig, i as MetadataContext, d as BlocFeedUser, g as FeedbackPayload } from './controller-D7kOehzb.js';
2
- export { B as BlocFeedConfig, b as BlocFeedController, c as BlocFeedError, a as BlocFeedState, E as ElementDescriptor, F as FeedbackApiResponse, H as HoverListener, I as ImageAsset, R as Rect, k as ScreenshotAdapterOptions, l as ScreenshotIntent, m as ScreenshotMime, n as SessionPhase, r as StateListener, S as SubmitResult, T as ThemeConfig, o as TransportConfig, q as TriggerStyle, W as WidgetPosition, s as createBlocFeedController } from './controller-D7kOehzb.js';
1
+ import { l as ScreenshotAdapter, C as CaptureConfig, g as CaptureResult, j as MetadataConfig, k as MetadataContext, e as BlocFeedUser, i as FeedbackPayload } from './controller-DfhbkHXc.js';
2
+ export { B as BlocFeedConfig, b as BlocFeedController, c as BlocFeedError, a as BlocFeedState, d as BlocFeedStrings, h as ConsoleEntry, D as DiagnosticsConfig, E as ElementDescriptor, F as FeedbackApiResponse, H as HoverListener, I as ImageAsset, N as NetworkEntry, R as Rect, m as ScreenshotAdapterOptions, n as ScreenshotIntent, o as ScreenshotMime, p as SessionPhase, t as StateListener, S as SubmitResult, T as ThemeConfig, q as TransportConfig, s as TriggerStyle, W as WidgetPosition, u as createBlocFeedController } from './controller-DfhbkHXc.js';
3
3
 
4
4
  declare function createHtmlToImageAdapter(): ScreenshotAdapter;
5
5
 
@@ -62,6 +62,54 @@ declare function clearQueue(): void;
62
62
  */
63
63
  declare function getQueueSize(): number;
64
64
 
65
+ interface ConsoleEntry {
66
+ level: "error" | "warn" | "log";
67
+ message: string;
68
+ timestamp: number;
69
+ stack?: string;
70
+ }
71
+ interface NetworkEntry {
72
+ url: string;
73
+ method: string;
74
+ status: number;
75
+ statusText?: string;
76
+ timestamp: number;
77
+ durationMs?: number;
78
+ }
79
+ interface DiagnosticsConfig {
80
+ /** Capture console errors/warnings. Default: true when diagnostics is set. */
81
+ console?: boolean;
82
+ /** Console levels to capture. Default: ["error", "warn"] */
83
+ consoleLevels?: ("error" | "warn" | "log")[];
84
+ /** Max console entries to retain. Default: 20 */
85
+ consoleLimit?: number;
86
+ /** Capture failed network requests (fetch). Default: true when diagnostics is set. */
87
+ network?: boolean;
88
+ /** Max network entries to retain. Default: 15 */
89
+ networkLimit?: number;
90
+ }
91
+ interface DiagnosticsSnapshot {
92
+ consoleLogs: ConsoleEntry[];
93
+ networkErrors: NetworkEntry[];
94
+ }
95
+ /**
96
+ * Install console and/or network interceptors.
97
+ * Safe to call multiple times — subsequent calls are no-ops.
98
+ */
99
+ declare function installDiagnostics(config?: DiagnosticsConfig): void;
100
+ /**
101
+ * Remove all interceptors and restore originals.
102
+ */
103
+ declare function uninstallDiagnostics(): void;
104
+ /**
105
+ * Return a copy of all captured entries (non-destructive read).
106
+ */
107
+ declare function drainDiagnostics(): DiagnosticsSnapshot;
108
+ /**
109
+ * Clear all captured entries.
110
+ */
111
+ declare function clearDiagnostics(): void;
112
+
65
113
  declare function dataUrlToBlob(dataUrl: string): Blob;
66
114
 
67
- export { BlocFeedUser, CaptureResult, FeedbackPayload, type ModernScreenshotModule, ScreenshotAdapter, clearQueue, collectMetadata, createHtmlToImageAdapter, createModernScreenshotAdapter, dataUrlToBlob, dequeueAll, enqueue, getQueueSize, runCapture };
115
+ export { BlocFeedUser, CaptureResult, FeedbackPayload, type ModernScreenshotModule, ScreenshotAdapter, clearDiagnostics, clearQueue, collectMetadata, createHtmlToImageAdapter, createModernScreenshotAdapter, dataUrlToBlob, dequeueAll, drainDiagnostics, enqueue, getQueueSize, installDiagnostics, runCapture, uninstallDiagnostics };
package/dist/engine.js CHANGED
@@ -1 +1 @@
1
- import {a}from'./chunk-FMFONS5S.js';export{h as clearQueue,e as collectMetadata,j as createBlocFeedController,c as createHtmlToImageAdapter,g as dequeueAll,f as enqueue,i as getQueueSize,d as runCapture}from'./chunk-FMFONS5S.js';function c(o){if(o?.aborted)throw new Error("Aborted")}async function A(o){return await new Promise((t,e)=>{let r=new Image;r.onload=()=>t({width:r.naturalWidth,height:r.naturalHeight}),r.onerror=()=>e(new Error("Failed to load generated screenshot")),r.src=o;})}async function l(o,t){let{width:e,height:r}=await A(o);return {dataUrl:o,mime:t,width:e,height:r}}function x(o){return {async captureElement(t,e){if(!a())throw new Error("captureElement can only run in the browser");c(e.signal);let r={scale:e.pixelRatio},n=e.mime==="image/jpeg"?await o.domToJpeg(t,{...r,quality:e.quality??.92}):await o.domToPng(t,r);return c(e.signal),await l(n,e.mime)},async captureFullPage(t){if(!a())throw new Error("captureFullPage can only run in the browser");c(t.signal);let e=document.documentElement,r=Math.max(e.scrollWidth,e.clientWidth),n=Math.max(e.scrollHeight,e.clientHeight),a$1=Math.min(1,t.maxDimension/Math.max(r,n)),s={width:Math.max(1,Math.round(r*a$1)),height:Math.max(1,Math.round(n*a$1)),scale:t.pixelRatio},i=t.mime==="image/jpeg"?await o.domToJpeg(e,{...s,quality:t.quality??.92}):await o.domToPng(e,s);return c(t.signal),await l(i,t.mime)}}}function b(o){let[t,e]=o.split(",",2);if(!t||!e)throw new Error("Invalid data URL");let n=/data:(.*?);base64/.exec(t)?.[1]||"application/octet-stream",a=atob(e),s=new Uint8Array(a.length);for(let i=0;i<a.length;i+=1)s[i]=a.charCodeAt(i);return new Blob([s],{type:n})}export{x as createModernScreenshotAdapter,b as dataUrlToBlob};
1
+ import {a}from'./chunk-QPAFC4IL.js';export{n as clearDiagnostics,h as clearQueue,e as collectMetadata,j as createBlocFeedController,c as createHtmlToImageAdapter,g as dequeueAll,m as drainDiagnostics,f as enqueue,i as getQueueSize,k as installDiagnostics,d as runCapture,l as uninstallDiagnostics}from'./chunk-QPAFC4IL.js';function c(o){if(o?.aborted)throw new Error("Aborted")}async function b(o){return await new Promise((t,e)=>{let r=new Image;r.onload=()=>t({width:r.naturalWidth,height:r.naturalHeight}),r.onerror=()=>e(new Error("Failed to load generated screenshot")),r.src=o;})}async function d(o,t){let{width:e,height:r}=await b(o);return {dataUrl:o,mime:t,width:e,height:r}}function E(o){return {async captureElement(t,e){if(!a())throw new Error("captureElement can only run in the browser");c(e.signal);let r={scale:e.pixelRatio},n=e.mime==="image/jpeg"?await o.domToJpeg(t,{...r,quality:e.quality??.92}):await o.domToPng(t,r);return c(e.signal),await d(n,e.mime)},async captureFullPage(t){if(!a())throw new Error("captureFullPage can only run in the browser");c(t.signal);let e=document.documentElement,r=Math.max(e.scrollWidth,e.clientWidth),n=Math.max(e.scrollHeight,e.clientHeight),a$1=Math.min(1,t.maxDimension/Math.max(r,n)),s={width:Math.max(1,Math.round(r*a$1)),height:Math.max(1,Math.round(n*a$1)),scale:t.pixelRatio},i=t.mime==="image/jpeg"?await o.domToJpeg(e,{...s,quality:t.quality??.92}):await o.domToPng(e,s);return c(t.signal),await d(i,t.mime)}}}function B(o){let[t,e]=o.split(",",2);if(!t||!e)throw new Error("Invalid data URL");let n=/data:(.*?);base64/.exec(t)?.[1]||"application/octet-stream",a=atob(e),s=new Uint8Array(a.length);for(let i=0;i<a.length;i+=1)s[i]=a.charCodeAt(i);return new Blob([s],{type:n})}export{E as createModernScreenshotAdapter,B as dataUrlToBlob};
package/dist/main.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- 'use strict';var chunkJLPJP7DD_cjs=require('./chunk-JLPJP7DD.cjs'),react=require('react'),jsxRuntime=require('react/jsx-runtime'),reactDom=require('react-dom'),framerMotion=require('framer-motion');var k=react.createContext(null);function M(t){let e=react.useMemo(()=>chunkJLPJP7DD_cjs.j({...t.config??{},blocfeed_id:t.blocfeed_id}),[]),[i,r]=react.useState(()=>e.getState());return react.useEffect(()=>e.subscribe(r),[e]),react.useEffect(()=>e.setConfig({...t.config??{},blocfeed_id:t.blocfeed_id}),[e,t.config,t.blocfeed_id]),react.useEffect(()=>()=>e.destroy(),[e]),jsxRuntime.jsx(k.Provider,{value:{controller:e,state:i},children:t.children})}var Y="blocfeed-styles-v1",Se=`
2
+ 'use strict';var chunkD5SBICBQ_cjs=require('./chunk-D5SBICBQ.cjs'),react=require('react'),jsxRuntime=require('react/jsx-runtime'),reactDom=require('react-dom'),framerMotion=require('framer-motion');var $=react.createContext(null);function J(e){let t=react.useMemo(()=>chunkD5SBICBQ_cjs.j({...e.config??{},blocfeed_id:e.blocfeed_id}),[]),[l,i]=react.useState(()=>t.getState());return react.useEffect(()=>t.subscribe(i),[t]),react.useEffect(()=>t.setConfig({...e.config??{},blocfeed_id:e.blocfeed_id}),[t,e.config,e.blocfeed_id]),react.useEffect(()=>()=>t.destroy(),[t]),jsxRuntime.jsx($.Provider,{value:{controller:t,state:l},children:e.children})}var be="blocfeed-styles-v1",ct=`
3
3
  :where([data-blocfeed-ui-root]),
4
4
  :where([data-blocfeed-ui-root]) * {
5
5
  box-sizing: border-box;
@@ -386,5 +386,118 @@
386
386
  white-space: nowrap;
387
387
  border: 0;
388
388
  }
389
- `;function J(){if(!chunkJLPJP7DD_cjs.a()||document.getElementById(Y))return;let t=document.createElement("style");t.id=Y,t.textContent=Se,document.head.appendChild(t);}function A(){let t=react.useContext(k);if(!t)throw new Error("useBlocFeed must be used within a <BlocFeedProvider />");return {state:t.state,controller:t.controller,start:t.controller.start,stop:t.controller.stop,clearSelection:t.controller.clearSelection,submit:t.controller.submit}}function c(t){switch(t){case "bottom-left":return "bf-trigger bf-trigger-bl";case "top-right":return "bf-trigger bf-trigger-tr";case "top-left":return "bf-trigger bf-trigger-tl";default:return "bf-trigger"}}function Q({position:t,onClick:e,isVisible:i}){return i?jsxRuntime.jsxs("button",{className:c(t),type:"button",onClick:e,"aria-label":"Give feedback",children:[jsxRuntime.jsx("span",{className:"bf-dot","aria-hidden":"true"}),"Feedback"]}):null}function ee({position:t,onClick:e,isVisible:i}){let[r,o]=react.useState(false);return jsxRuntime.jsx(framerMotion.AnimatePresence,{children:i&&jsxRuntime.jsxs(framerMotion.motion.button,{className:c(t),type:"button",onClick:e,onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),"aria-label":"Give feedback",initial:{scale:0,opacity:0},animate:{scale:1,opacity:1,padding:r?"10px 16px":"10px 10px"},exit:{scale:0,opacity:0},transition:{type:"spring",stiffness:500,damping:28},whileTap:{scale:.92},style:{overflow:"hidden"},children:[jsxRuntime.jsx(framerMotion.motion.span,{className:"bf-dot","aria-hidden":"true",animate:{scale:r?1:[1,1.2,1],boxShadow:r?"0 0 0 4px rgba(99, 102, 241, 0.18)":["0 0 0 4px rgba(99, 102, 241, 0.18)","0 0 0 8px rgba(99, 102, 241, 0.28)","0 0 0 4px rgba(99, 102, 241, 0.18)"]},transition:r?{type:"spring",stiffness:400,damping:20}:{duration:2,repeat:1/0,ease:"easeInOut"}}),jsxRuntime.jsx(framerMotion.AnimatePresence,{children:r&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,width:0,x:-8},animate:{opacity:1,width:"auto",x:0},exit:{opacity:0,width:0,x:-8},transition:{type:"spring",stiffness:400,damping:25},style:{whiteSpace:"nowrap",overflow:"hidden"},children:"Feedback"})}),jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{position:"absolute",inset:0,borderRadius:"inherit",border:"2px solid var(--bf-accent)",pointerEvents:"none"},initial:false,animate:{scale:1,opacity:0},whileTap:{scale:2.5,opacity:[.6,0]},transition:{duration:.4}})]})})}function te({size:t=14}){return jsxRuntime.jsx("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsxRuntime.jsx("path",{d:"M21 11.5a8.38 8.38 0 01-.9 3.8 8.5 8.5 0 01-7.6 4.7 8.38 8.38 0 01-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 01-.9-3.8 8.5 8.5 0 014.7-7.6 8.38 8.38 0 013.8-.9h.5a8.48 8.48 0 018 8v.5z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function oe({size:t=16}){return jsxRuntime.jsxs("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[jsxRuntime.jsx("path",{d:"M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),jsxRuntime.jsx("path",{d:"M22 6l-10 7L2 6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}function ie({position:t,onClick:e,isVisible:i}){let[r,o]=react.useState(false);return jsxRuntime.jsx(framerMotion.AnimatePresence,{children:i&&jsxRuntime.jsxs(framerMotion.motion.div,{style:{position:"fixed",zIndex:"var(--bf-z)"},className:c(t),initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{y:12,opacity:0,scale:.8},transition:{type:"spring",stiffness:400,damping:25},onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),children:[jsxRuntime.jsx(framerMotion.AnimatePresence,{children:r&&jsxRuntime.jsx(framerMotion.motion.div,{initial:{opacity:0,y:6,scale:.95},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:6,scale:.95},transition:{type:"spring",stiffness:500,damping:30},style:{position:"absolute",bottom:"calc(100% + 8px)",left:"50%",transform:"translateX(-50%)",padding:"6px 12px",borderRadius:"8px",background:"var(--bf-panel-bg)",border:"1px solid var(--bf-border)",boxShadow:"var(--bf-shadow)",whiteSpace:"nowrap",fontSize:"12px",color:"var(--bf-panel-fg)",pointerEvents:"none"},children:"Got feedback?"})}),jsxRuntime.jsx(framerMotion.motion.button,{type:"button",onClick:e,"aria-label":"Give feedback",style:{display:"flex",alignItems:"center",justifyContent:"center",width:"40px",height:"40px",borderRadius:"50%",border:"1px solid var(--bf-border)",background:"var(--bf-panel-bg)",color:"var(--bf-panel-fg)",boxShadow:"var(--bf-shadow)",cursor:"pointer",padding:0},animate:{y:[0,-3,0]},transition:{y:{duration:3,repeat:1/0,ease:"easeInOut"}},whileHover:{scale:1.1,borderColor:"var(--bf-accent)"},whileTap:{scale:.9},children:jsxRuntime.jsx(te,{size:16})})]})})}function ne(t){return t==="bottom-left"||t==="top-left"}function We(t){return `bf-trigger-edge ${ne(t)?"bf-trigger-edge-left":"bf-trigger-edge-right"}`}function se({position:t,onClick:e,isVisible:i}){let[r,o]=react.useState(false),l=ne(t);return jsxRuntime.jsx(framerMotion.AnimatePresence,{children:i&&jsxRuntime.jsxs(framerMotion.motion.button,{className:We(t),type:"button",onClick:e,onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),"aria-label":"Give feedback",initial:{opacity:0,width:0},animate:{opacity:1,width:r?140:22,height:r?40:90},exit:{width:0,opacity:0},transition:{type:"spring",stiffness:350,damping:30},whileTap:{scale:.97},style:{top:"50%",translateY:"-50%"},children:[jsxRuntime.jsxs(framerMotion.motion.span,{animate:{rotate:r?0:l?-90:90,opacity:r?1:.6},transition:{type:"spring",stiffness:300,damping:25},style:{display:"flex",alignItems:"center",gap:"8px",whiteSpace:"nowrap",fontSize:"12px",letterSpacing:"0.5px",textTransform:"uppercase"},children:[r&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:{type:"spring",stiffness:500,damping:20},style:{width:"6px",height:"6px",borderRadius:"50%",background:"var(--bf-accent)",flexShrink:0}}),"Feedback"]}),jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",animate:{opacity:r?1:0},style:{position:"absolute",top:0,bottom:0,[l?"left":"right"]:0,width:"2px",background:"var(--bf-accent)"}})]})})}function de({delay:t,hovered:e}){return jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{position:"absolute",width:"12px",height:"12px",borderRadius:"50%",border:"2px solid var(--bf-accent)",pointerEvents:"none",left:"50%",top:"50%",x:"-50%",y:"-50%"},animate:e?{scale:1.3,opacity:.6}:{scale:[1,2.5],opacity:[.5,0]},transition:e?{type:"spring",stiffness:300,damping:20}:{duration:2,repeat:1/0,delay:t,ease:"easeOut"}})}function pe({position:t,onClick:e,isVisible:i}){let[r,o]=react.useState(false);return jsxRuntime.jsx(framerMotion.AnimatePresence,{children:i&&jsxRuntime.jsxs(framerMotion.motion.button,{className:c(t),type:"button",onClick:e,onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),"aria-label":"Give feedback",initial:{scale:0,opacity:0},animate:{scale:1,opacity:1,padding:r?"10px 16px":"10px 10px"},exit:{scale:0,opacity:0},transition:{type:"spring",stiffness:400,damping:25},whileTap:{scale:.92},style:{position:"relative",overflow:"visible"},children:[jsxRuntime.jsxs("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",pointerEvents:"none"},children:[jsxRuntime.jsx(de,{delay:0,hovered:r}),jsxRuntime.jsx(de,{delay:.7,hovered:r})]}),jsxRuntime.jsx(framerMotion.motion.span,{className:"bf-dot","aria-hidden":"true",style:{position:"relative",zIndex:1},animate:{scale:r?1.1:1},transition:{type:"spring",stiffness:400,damping:20}}),jsxRuntime.jsx(framerMotion.AnimatePresence,{children:r&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,width:0,x:-12},animate:{opacity:1,width:"auto",x:0},exit:{opacity:0,width:0,x:-12},transition:{type:"spring",stiffness:400,damping:25},style:{whiteSpace:"nowrap",overflow:"hidden",position:"relative",zIndex:1},children:"Feedback"})})]})})}function Ge(t){switch(t){case "bottom-left":return "bf-trigger-minimal bf-trigger-bl";case "top-right":return "bf-trigger-minimal bf-trigger-tr";case "top-left":return "bf-trigger-minimal bf-trigger-tl";default:return "bf-trigger-minimal"}}function be({position:t,onClick:e,isVisible:i}){let[r,o]=react.useState(false);return jsxRuntime.jsx(framerMotion.AnimatePresence,{children:i&&jsxRuntime.jsxs(framerMotion.motion.button,{className:Ge(t),type:"button",onClick:e,onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),"aria-label":"Give feedback",initial:{opacity:0,y:5},animate:{opacity:r?1:.65,y:0},exit:{opacity:0,y:5},transition:{type:"spring",stiffness:400,damping:30},whileTap:{scale:.95},children:[jsxRuntime.jsx("span",{children:"Feedback"}),jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{position:"absolute",bottom:4,left:4,right:4,height:"2px",background:"var(--bf-accent)",borderRadius:"1px",transformOrigin:"left"},initial:false,animate:{scaleX:r?1:0},transition:{type:"spring",stiffness:400,damping:25}})]})})}function ge({position:t,onClick:e,isVisible:i}){let[r,o]=react.useState(false);return jsxRuntime.jsx(framerMotion.AnimatePresence,{children:i&&jsxRuntime.jsxs(framerMotion.motion.button,{className:c(t),type:"button",onClick:e,onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),"aria-label":"Give feedback",initial:{scale:0,opacity:0,rotate:-45},animate:{scale:1,opacity:1,rotate:0,padding:r?"10px 16px":"10px 10px"},exit:{rotate:180,scale:0,opacity:0},transition:{type:"spring",stiffness:400,damping:22},whileTap:{scale:.9,rotate:360},style:{overflow:"hidden"},children:[jsxRuntime.jsx(framerMotion.motion.span,{style:{display:"inline-flex",flexShrink:0},animate:r?{scale:1.2,rotate:0}:{rotate:[-5,5,-5]},transition:r?{type:"spring",stiffness:500,damping:12}:{duration:3,repeat:1/0,ease:"easeInOut"},children:jsxRuntime.jsx(oe,{size:16})}),jsxRuntime.jsx(framerMotion.AnimatePresence,{children:r&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,width:0,x:-16},animate:{opacity:1,width:"auto",x:0},exit:{opacity:0,width:0,x:-16},transition:{type:"spring",stiffness:350,damping:25,delay:.03},style:{whiteSpace:"nowrap",overflow:"hidden"},children:"Feedback"})})]})})}function me(t){switch(t){case "dot":return ee;case "bubble":return ie;case "edge-tab":return se;case "pulse-ring":return pe;case "minimal":return be;case "icon-pop":return ge;default:return Q}}function xe(t,e,i){return Math.max(e,Math.min(i,t))}function qe(t,e,i="bottom-right"){let o=window.innerWidth,l=window.innerHeight,n;n=xe(t.x,12,Math.max(12,o-e-12));let p=t.y+t.height+12,S=Math.max(12,t.y-240);return {top:p+240<=l?p:S,left:n}}function Ye(t){let{rect:e}=t,i={left:`${e.x}px`,top:`${e.y}px`,width:`${Math.max(0,e.width)}px`,height:`${Math.max(0,e.height)}px`};return jsxRuntime.jsx("div",{className:"bf-highlight",style:i,"aria-hidden":"true"})}function Je(t){let e=react.useRef(null);return react.useEffect(()=>{if(!t||!e.current)return;e.current.querySelector(".bf-textarea")?.focus();let r=o=>{if(o.key!=="Tab"||!e.current)return;let l=e.current.querySelectorAll('button:not([disabled]), textarea:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex="-1"])');if(l.length===0)return;let n=l[0],p=l[l.length-1];o.shiftKey&&document.activeElement===n?(o.preventDefault(),p.focus()):!o.shiftKey&&document.activeElement===p&&(o.preventDefault(),n.focus());};return document.addEventListener("keydown",r,{capture:true}),()=>document.removeEventListener("keydown",r,{capture:true})},[t]),e}function Qe(t){let{state:e,controller:i,start:r,stop:o,clearSelection:l,submit:n}=A(),p=t.config.ui?.position,[S,_]=react.useState(null),[g,D]=react.useState(""),[B,O]=react.useState(t.config.capture?.element??true),[E,G]=react.useState(t.config.capture?.fullPage??false),[ye,K]=react.useState(null),V=e.phase==="review"||e.phase==="capturing"||e.phase==="submitting"||e.phase==="error"||e.phase==="success",ve=Je(V);react.useEffect(()=>i.subscribeHover(_),[i]),react.useEffect(()=>{let s=i.__unsafeGetSelectedElement();if(!s||e.phase==="idle"||e.phase==="picking"){K(null);return}let $=()=>{K(chunkJLPJP7DD_cjs.b(s.getBoundingClientRect()));};$();let w=()=>$();return window.addEventListener("scroll",w,{capture:true,passive:true}),window.addEventListener("resize",w,{passive:true}),()=>{window.removeEventListener("scroll",w,{capture:true}),window.removeEventListener("resize",w);}},[i,e.phase,e.selection?.selector]),react.useEffect(()=>{e.phase==="review"&&(D(""),O(t.config.capture?.element??true),G(t.config.capture?.fullPage??false));},[e.phase,e.selection?.selector,t.config.capture?.element,t.config.capture?.fullPage]),react.useEffect(()=>{if(e.phase!=="success")return;let s=window.setTimeout(()=>o(),1200);return ()=>window.clearTimeout(s)},[e.phase,o]);let f=e.phase==="capturing"||e.phase==="submitting",b=e.phase==="picking"?S?.rect??null:ye??e.selection?.rect??null,N=react.useMemo(()=>b?qe(b,360,p):null,[b?.x,b?.y,b?.width,b?.height,p]),X=e.lastError?.message,z=react.useCallback(()=>{n(g,{capture:{element:B,fullPage:E}});},[n,g,B,E]),we=react.useCallback(s=>{(s.metaKey||s.ctrlKey)&&s.key==="Enter"&&g.trim().length>0&&!f&&(s.preventDefault(),z());},[z,g,f]),ke=me(t.config.ui?.triggerStyle);return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(ke,{position:p,onClick:()=>r(),isVisible:e.phase==="idle"}),e.phase!=="idle"&&jsxRuntime.jsxs("div",{className:"bf-overlay",role:"presentation",children:[e.phase!=="picking"&&jsxRuntime.jsx("div",{className:"bf-blocker",role:"presentation",onClick:()=>o()}),b&&jsxRuntime.jsx(Ye,{rect:b}),e.phase==="picking"&&jsxRuntime.jsxs("div",{className:"bf-hint",role:"status","aria-live":"polite",children:[jsxRuntime.jsxs("p",{id:"bf-hint-text",children:["Click an element to attach your feedback. Press ",jsxRuntime.jsx("strong",{children:"Esc"})," to cancel."]}),jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>o(),"aria-label":"Cancel element selection",children:"Cancel"})]}),V&&N&&jsxRuntime.jsxs("div",{ref:ve,className:"bf-panel",style:{left:N.left,top:N.top},role:"dialog","aria-modal":"true","aria-label":"Feedback form",children:[jsxRuntime.jsxs("div",{className:"bf-panelHeader",children:[jsxRuntime.jsx("div",{className:"bf-title",id:"bf-panel-title",children:"Feedback"}),jsxRuntime.jsxs("div",{className:"bf-row",style:{justifyContent:"flex-end"},children:[jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>l(),disabled:f,"aria-label":"Re-pick element",children:"Re-pick"}),jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>o(),disabled:f,"aria-label":"Close feedback form",children:"Close"})]})]}),jsxRuntime.jsxs("div",{className:"bf-panelBody",children:[jsxRuntime.jsx("textarea",{className:"bf-textarea",placeholder:"What's happening? What did you expect?",value:g,onChange:s=>D(s.target.value),onKeyDown:we,disabled:f,"aria-label":"Feedback message"}),jsxRuntime.jsxs("div",{className:"bf-row",role:"group","aria-label":"Screenshot options",children:[jsxRuntime.jsxs("label",{children:[jsxRuntime.jsx("input",{type:"checkbox",checked:B,onChange:s=>O(s.target.checked),disabled:f}),"Screenshot element"]}),jsxRuntime.jsxs("label",{children:[jsxRuntime.jsx("input",{type:"checkbox",checked:E,onChange:s=>G(s.target.checked),disabled:f}),"Full page"]})]}),e.phase==="capturing"&&jsxRuntime.jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsxRuntime.jsx("span",{className:"bf-spinner","aria-hidden":"true"}),"Capturing screenshots\u2026"]}),e.phase==="submitting"&&jsxRuntime.jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsxRuntime.jsx("span",{className:"bf-spinner","aria-hidden":"true"}),"Submitting\u2026"]}),e.phase==="success"&&jsxRuntime.jsx("div",{className:"bf-status",role:"status","aria-live":"polite",children:"Sent. Thank you!"}),e.phase==="error"&&X&&jsxRuntime.jsx("div",{className:"bf-error",role:"alert",children:X}),jsxRuntime.jsxs("div",{className:"bf-actions",children:[jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>o(),disabled:f,"aria-label":"Cancel feedback",children:"Cancel"}),jsxRuntime.jsx("button",{type:"button",className:"bf-btn bf-btnPrimary",onClick:z,disabled:f||g.trim().length===0,"aria-label":"Send feedback",children:"Send"})]})]})]})]}),e.phase==="success"&&jsxRuntime.jsx("div",{className:"bf-toast",role:"status","aria-live":"polite",children:"Feedback sent"})]})}function Ze(t){let e={...t.config??{},blocfeed_id:t.blocfeed_id},[i,r]=react.useState(null);return react.useEffect(()=>{J();let o=document.createElement("div");o.setAttribute("data-blocfeed-ui-root","true"),o.setAttribute("data-blocfeed-ui","true");let l=e.ui?.zIndex;typeof l=="number"&&o.style.setProperty("--bf-z",String(l));let n=e.ui?.theme;return n&&(n.accentColor&&o.style.setProperty("--bf-accent",n.accentColor),n.panelBackground&&o.style.setProperty("--bf-panel-bg",n.panelBackground),n.panelForeground&&o.style.setProperty("--bf-panel-fg",n.panelForeground),n.fontFamily&&o.style.setProperty("--bf-font",n.fontFamily)),document.body.appendChild(o),r(o),()=>{o.remove(),r(null);}},[e.ui?.zIndex,e.ui?.theme?.accentColor,e.ui?.theme?.panelBackground,e.ui?.theme?.panelForeground,e.ui?.theme?.fontFamily]),i?reactDom.createPortal(jsxRuntime.jsx(M,{blocfeed_id:e.blocfeed_id,...t.config?{config:t.config}:{},children:jsxRuntime.jsx(Qe,{config:e})}),i):null}
390
- exports.BlocFeedProvider=M;exports.BlocFeedWidget=Ze;exports.useBlocFeed=A;
389
+
390
+ /* ------------------------------------------------------------------ */
391
+ /* Queue badge */
392
+ /* ------------------------------------------------------------------ */
393
+
394
+ :where([data-blocfeed-ui-root]) .bf-badge {
395
+ display: inline-flex;
396
+ align-items: center;
397
+ justify-content: center;
398
+ min-width: 16px;
399
+ height: 16px;
400
+ padding: 0 4px;
401
+ border-radius: 999px;
402
+ background: var(--bf-danger);
403
+ color: white;
404
+ font-size: 10px;
405
+ font-weight: 600;
406
+ line-height: 1;
407
+ flex-shrink: 0;
408
+ }
409
+
410
+ :where([data-blocfeed-ui-root]) .bf-badge-float {
411
+ position: absolute;
412
+ top: -4px;
413
+ right: -4px;
414
+ }
415
+
416
+ /* ------------------------------------------------------------------ */
417
+ /* Typewriter cursor */
418
+ /* ------------------------------------------------------------------ */
419
+
420
+ :where([data-blocfeed-ui-root]) .bf-cursor {
421
+ display: inline-block;
422
+ width: 1px;
423
+ height: 1em;
424
+ background: var(--bf-panel-fg);
425
+ margin-left: 1px;
426
+ vertical-align: text-bottom;
427
+ animation: bf-blink 1s steps(2) infinite;
428
+ }
429
+
430
+ @keyframes bf-blink {
431
+ 0% { opacity: 1; }
432
+ 50% { opacity: 0; }
433
+ }
434
+
435
+ /* ------------------------------------------------------------------ */
436
+ /* Panel / toast / hint entrance animations */
437
+ /* ------------------------------------------------------------------ */
438
+
439
+ :where([data-blocfeed-ui-root]) .bf-panel {
440
+ animation: bf-panel-in 0.2s ease-out;
441
+ }
442
+
443
+ @keyframes bf-panel-in {
444
+ from { opacity: 0; transform: translateY(8px); }
445
+ to { opacity: 1; transform: translateY(0); }
446
+ }
447
+
448
+ :where([data-blocfeed-ui-root]) .bf-toast {
449
+ animation: bf-toast-in 0.25s ease-out;
450
+ }
451
+
452
+ @keyframes bf-toast-in {
453
+ from { opacity: 0; transform: translateX(-50%) translateY(12px); }
454
+ to { opacity: 1; transform: translateX(-50%) translateY(0); }
455
+ }
456
+
457
+ :where([data-blocfeed-ui-root]) .bf-hint {
458
+ animation: bf-hint-in 0.2s ease-out;
459
+ }
460
+
461
+ @keyframes bf-hint-in {
462
+ from { opacity: 0; transform: translateX(-50%) translateY(-10px); }
463
+ to { opacity: 1; transform: translateX(-50%) translateY(0); }
464
+ }
465
+
466
+ /* ------------------------------------------------------------------ */
467
+ /* Reduced motion */
468
+ /* ------------------------------------------------------------------ */
469
+
470
+ /* ------------------------------------------------------------------ */
471
+ /* Watermark */
472
+ /* ------------------------------------------------------------------ */
473
+
474
+ :where([data-blocfeed-ui-root]) .bf-watermark {
475
+ padding: 6px 12px;
476
+ border-top: 1px solid rgba(255, 255, 255, 0.06);
477
+ text-align: center;
478
+ }
479
+
480
+ :where([data-blocfeed-ui-root]) .bf-watermark a {
481
+ font-size: 10px;
482
+ color: rgba(243, 244, 246, 0.35);
483
+ text-decoration: none;
484
+ }
485
+
486
+ :where([data-blocfeed-ui-root]) .bf-watermark a:hover {
487
+ color: var(--bf-accent);
488
+ }
489
+
490
+ /* ------------------------------------------------------------------ */
491
+ /* Reduced motion */
492
+ /* ------------------------------------------------------------------ */
493
+
494
+ @media (prefers-reduced-motion: reduce) {
495
+ :where([data-blocfeed-ui-root]) .bf-panel,
496
+ :where([data-blocfeed-ui-root]) .bf-toast,
497
+ :where([data-blocfeed-ui-root]) .bf-hint,
498
+ :where([data-blocfeed-ui-root]) .bf-cursor {
499
+ animation: none;
500
+ }
501
+ }
502
+ `;function ge(){if(!chunkD5SBICBQ_cjs.a()||document.getElementById(be))return;let e=document.createElement("style");e.id=be,e.textContent=ct,document.head.appendChild(e);}var me={triggerLabel:"Feedback",panelTitle:"Feedback",hintText:"Click an element to attach your feedback. Press Esc to cancel.",cancelButton:"Cancel",rePickButton:"Re-pick",closeButton:"Close",textareaPlaceholder:"What's happening? What did you expect?",screenshotElement:"Screenshot element",screenshotFullPage:"Full page",capturingText:"Capturing screenshots\u2026",submittingText:"Submitting\u2026",successText:"Sent. Thank you!",toastText:"Feedback sent",sendButton:"Send"};function he(e){return e?{...me,...e}:me}function Z(){let e=react.useContext($);if(!e)throw new Error("useBlocFeed must be used within a <BlocFeedProvider />");return {state:e.state,controller:e.controller,start:e.controller.start,stop:e.controller.stop,clearSelection:e.controller.clearSelection,submit:e.controller.submit}}function m(e){switch(e){case "bottom-left":return "bf-trigger bf-trigger-bl";case "top-right":return "bf-trigger bf-trigger-tr";case "top-left":return "bf-trigger bf-trigger-tl";default:return "bf-trigger"}}function f({size:e=14}){return jsxRuntime.jsx("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsxRuntime.jsx("path",{d:"M20 6L9 17l-5-5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function xe({size:e=14}){return jsxRuntime.jsx("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsxRuntime.jsx("path",{d:"M21 11.5a8.38 8.38 0 01-.9 3.8 8.5 8.5 0 01-7.6 4.7 8.38 8.38 0 01-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 01-.9-3.8 8.5 8.5 0 014.7-7.6 8.38 8.38 0 013.8-.9h.5a8.48 8.48 0 018 8v.5z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function ye({size:e=16}){return jsxRuntime.jsxs("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[jsxRuntime.jsx("path",{d:"M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),jsxRuntime.jsx("path",{d:"M22 6l-10 7L2 6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}function we({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){return l?jsxRuntime.jsxs("button",{className:m(e),type:"button",onClick:t,"aria-label":i,children:[c?jsxRuntime.jsx("span",{style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("span",{className:"bf-dot","aria-hidden":"true"}),i]}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]}):null}function b(){let[e,t]=react.useState(()=>typeof window>"u"?false:window.matchMedia("(prefers-reduced-motion: reduce)").matches);return react.useEffect(()=>{let l=window.matchMedia("(prefers-reduced-motion: reduce)"),i=r=>t(r.matches);return l.addEventListener("change",i),()=>l.removeEventListener("change",i)},[]),e}var mt={duration:.18,ease:"easeOut"},ht={duration:0};function Te({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=react.useState(false),o=b(),n=o?ht:mt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:l&&jsxRuntime.jsx(framerMotion.motion.button,{className:m(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:n,whileTap:{scale:.92},style:{overflow:"hidden"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:n,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(framerMotion.motion.span,{className:"bf-dot","aria-hidden":"true",animate:o?{}:{scale:a?1:[1,1.2,1],boxShadow:a?"0 0 0 4px rgba(99, 102, 241, 0.18)":["0 0 0 4px rgba(99, 102, 241, 0.18)","0 0 0 8px rgba(99, 102, 241, 0.28)","0 0 0 4px rgba(99, 102, 241, 0.18)"]},transition:a||o?n:{duration:2,repeat:1/0,ease:"easeInOut"}}),jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:a&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,x:o?0:-6},animate:{opacity:1,x:0},exit:{opacity:0,x:o?0:-6},transition:n,style:{whiteSpace:"nowrap"},children:i},"label")}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"dot")})}var wt={duration:.18,ease:"easeOut"},Ee={duration:0};function Ce({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=react.useState(false),o=b(),n=o?Ee:wt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:l&&jsxRuntime.jsxs(framerMotion.motion.div,{className:m(e),initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{y:8,opacity:0},transition:n,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),style:{background:"transparent",border:"none",boxShadow:"none",padding:0},children:[jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:a&&jsxRuntime.jsx(framerMotion.motion.div,{initial:{opacity:0,y:o?0:4},animate:{opacity:1,y:0},exit:{opacity:0,y:o?0:4},transition:n,style:{position:"absolute",bottom:"calc(100% + 8px)",left:"50%",transform:"translateX(-50%)",padding:"6px 12px",borderRadius:"8px",background:"var(--bf-panel-bg)",border:"1px solid var(--bf-border)",boxShadow:"var(--bf-shadow)",whiteSpace:"nowrap",fontSize:"12px",color:"var(--bf-panel-fg)",pointerEvents:"none"},children:i},"tooltip")}),jsxRuntime.jsxs(framerMotion.motion.button,{type:"button",onClick:t,"aria-label":i,style:{position:"relative",display:"flex",alignItems:"center",justifyContent:"center",width:"40px",height:"40px",borderRadius:"50%",border:"1px solid var(--bf-border)",background:"var(--bf-panel-bg)",color:"var(--bf-panel-fg)",boxShadow:"var(--bf-shadow)",cursor:"pointer",padding:0},animate:o?{}:{y:[0,-3,0]},transition:o?Ee:{y:{duration:3,repeat:1/0,ease:"easeInOut"}},whileHover:{scale:1.1,borderColor:"var(--bf-accent)"},whileTap:{scale:.9},children:[c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:n,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:16})},"success"):jsxRuntime.jsx(xe,{size:16}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge bf-badge-float","aria-label":`${r} queued`,children:r})]})]},"bubble")})}var Pt={duration:.2,ease:"easeOut"},Et={duration:0};function Be(e){return e==="bottom-left"||e==="top-left"}function St(e){return `bf-trigger-edge ${Be(e)?"bf-trigger-edge-left":"bf-trigger-edge-right"}`}function Fe({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=react.useState(false),o=Be(e),n=b(),u=n?Et:Pt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:l&&jsxRuntime.jsx(framerMotion.motion.button,{className:St(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{opacity:0,width:0},animate:{opacity:1,width:a?140:22,height:a?40:90},exit:{width:0,opacity:0},transition:u,whileTap:{scale:.97},style:{top:"50%",translateY:"-50%"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:u,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs(framerMotion.motion.span,{animate:{rotate:n||a?0:o?-90:90,opacity:a?1:.6},transition:u,style:{display:"flex",alignItems:"center",gap:"8px",whiteSpace:"nowrap",fontSize:"12px",letterSpacing:"0.5px",textTransform:"uppercase"},children:[a&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:{duration:.12},style:{width:"6px",height:"6px",borderRadius:"50%",background:"var(--bf-accent)",flexShrink:0}}),i]}),jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",animate:{opacity:a?1:0},transition:{duration:.12},style:{position:"absolute",top:0,bottom:0,[o?"left":"right"]:0,width:"2px",background:"var(--bf-accent)"}}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"edge-tab")})}var Bt={duration:.18,ease:"easeOut"},Ft={duration:0};function Me({delay:e,hovered:t,reduced:l}){return l?null:jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{position:"absolute",width:"10px",height:"10px",borderRadius:"50%",border:"2px solid var(--bf-accent)",pointerEvents:"none"},animate:t?{scale:1,opacity:0}:{scale:[1,1.8],opacity:[.5,0]},transition:t?{duration:.15}:{duration:2,repeat:1/0,delay:e,ease:"easeOut"}})}function ze({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=react.useState(false),o=b(),n=o?Ft:Bt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:l&&jsxRuntime.jsx(framerMotion.motion.button,{className:m(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:n,whileTap:{scale:.92},style:{overflow:"hidden"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:n,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("span",{style:{position:"relative",display:"flex",alignItems:"center",justifyContent:"center",width:"10px",height:"10px",flexShrink:0},children:[jsxRuntime.jsx(Me,{delay:0,hovered:a,reduced:o}),jsxRuntime.jsx(Me,{delay:.7,hovered:a,reduced:o}),jsxRuntime.jsx(framerMotion.motion.span,{className:"bf-dot","aria-hidden":"true",style:{position:"relative",zIndex:1}})]}),jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:a&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,x:o?0:-6},animate:{opacity:1,x:0},exit:{opacity:0,x:o?0:-6},transition:n,style:{whiteSpace:"nowrap"},children:i},"label")}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"pulse-ring")})}var zt={duration:.18,ease:"easeOut"},It={duration:0};function At(e){switch(e){case "bottom-left":return "bf-trigger-minimal bf-trigger-bl";case "top-right":return "bf-trigger-minimal bf-trigger-tr";case "top-left":return "bf-trigger-minimal bf-trigger-tl";default:return "bf-trigger-minimal"}}function We({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=react.useState(false),o=b(),n=o?It:zt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:l&&jsxRuntime.jsxs(framerMotion.motion.button,{className:At(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{opacity:0,y:o?0:5},animate:{opacity:a?1:.65,y:0},exit:{opacity:0,y:o?0:5},transition:n,whileTap:{scale:.95},children:[c?jsxRuntime.jsx("span",{style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("span",{children:i}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge",style:{marginLeft:"4px"},"aria-label":`${r} queued`,children:r})]}),!o&&jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{position:"absolute",bottom:4,left:4,right:4,height:"2px",background:"var(--bf-accent)",borderRadius:"1px",transformOrigin:"left"},initial:false,animate:{scaleX:a?1:0},transition:n})]},"minimal")})}var Ot={duration:.18,ease:"easeOut"},Ht={duration:0};function Oe({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=react.useState(false),o=b(),n=o?Ht:Ot;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:l&&jsxRuntime.jsx(framerMotion.motion.button,{className:m(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:n,whileTap:{scale:.9},style:{overflow:"hidden"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:n,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(framerMotion.motion.span,{style:{display:"inline-flex",flexShrink:0},animate:o?{}:a?{scale:1.2,rotate:0}:{rotate:[-5,5,-5]},transition:a||o?n:{duration:3,repeat:1/0,ease:"easeInOut"},children:jsxRuntime.jsx(ye,{size:16})}),jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:a&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,x:o?0:-8},animate:{opacity:1,x:0},exit:{opacity:0,x:o?0:-8},transition:n,style:{whiteSpace:"nowrap"},children:i},"label")}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"icon-pop")})}var Xt={duration:.18,ease:"easeOut"},Yt={duration:0};function Ke({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=react.useState(false),o=b(),n=o?Yt:Xt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:l&&jsxRuntime.jsx(framerMotion.motion.button,{className:m(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:n,whileTap:{scale:.92},style:{overflow:"hidden"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:n,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("span",{style:{position:"relative",display:"inline-flex",alignItems:"center",justifyContent:"center",width:"10px",height:"10px",flexShrink:0},children:[jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{width:"10px",height:"10px",borderRadius:"50%",background:"var(--bf-accent)",position:"relative",zIndex:1},animate:o?{}:{opacity:a?1:[.5,1,.5],boxShadow:a?"0 0 8px 2px var(--bf-accent)":["0 0 4px 1px var(--bf-accent)","0 0 12px 4px var(--bf-accent)","0 0 4px 1px var(--bf-accent)"]},transition:a||o?n:{duration:2,repeat:1/0,ease:"easeInOut"}}),!a&&!o&&jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{position:"absolute",width:"18px",height:"2px",background:"linear-gradient(90deg, var(--bf-accent), transparent)",transformOrigin:"left center",left:"5px",top:"4px"},animate:{rotate:[0,360]},transition:{duration:4,repeat:1/0,ease:"linear"}})]}),jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:a&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,x:o?0:-6},animate:{opacity:1,x:0},exit:{opacity:0,x:o?0:-6},transition:n,style:{whiteSpace:"nowrap"},children:i},"label")}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"beacon")})}var Gt={duration:.18,ease:"easeOut"},Jt={duration:0};function Ue({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=react.useState(false),[o,n]=react.useState(0),u=b(),H=u?Jt:Gt,g=react.useRef(null);react.useEffect(()=>{if(g.current&&(clearInterval(g.current),g.current=null),!l||a||u){n(a||u?i.length:0);return}let E=8,K=i.length*2+E*2,x=0;return g.current=setInterval(()=>{x=(x+1)%K,x<=i.length?n(x):x<=i.length+E?n(i.length):x<=i.length*2+E?n(i.length*2+E-x):n(0);},100),()=>{g.current&&(clearInterval(g.current),g.current=null);}},[l,a,u,i]);let D=i.slice(0,o);return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:l&&jsxRuntime.jsx(framerMotion.motion.button,{className:m(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{opacity:0,y:u?0:5},animate:{opacity:1,y:0},exit:{opacity:0,y:u?0:5},transition:H,whileTap:{scale:.95},style:{minWidth:"44px"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:H,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("span",{className:"bf-dot","aria-hidden":"true"}),jsxRuntime.jsxs("span",{style:{whiteSpace:"nowrap",minWidth:"1ch"},children:[D,jsxRuntime.jsx("span",{className:"bf-cursor","aria-hidden":"true"})]}),r>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"typewriter")})}function je(e){switch(e){case "dot":return Te;case "bubble":return Ce;case "edge-tab":return Fe;case "pulse-ring":return ze;case "minimal":return We;case "icon-pop":return Oe;case "beacon":return Ke;case "typewriter":return Ue;default:return we}}function Ve(e,t,l){return Math.max(t,Math.min(l,e))}function eo(e,t,l="bottom-right"){let r=window.innerWidth,c=window.innerHeight,a;a=Ve(e.x,12,Math.max(12,r-t-12));let s=e.y+e.height+12,o=Math.max(12,e.y-240);return {top:s+240<=c?s:o,left:a}}function to(e){let{rect:t}=e,l={left:`${t.x}px`,top:`${t.y}px`,width:`${Math.max(0,t.width)}px`,height:`${Math.max(0,t.height)}px`};return jsxRuntime.jsx("div",{className:"bf-highlight",style:l,"aria-hidden":"true"})}function oo(e){let t=react.useRef(null);return react.useEffect(()=>{if(!e||!t.current)return;t.current.querySelector(".bf-textarea")?.focus();let i=r=>{if(r.key!=="Tab"||!t.current)return;let c=t.current.querySelectorAll('button:not([disabled]), textarea:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex="-1"])');if(c.length===0)return;let a=c[0],s=c[c.length-1];r.shiftKey&&document.activeElement===a?(r.preventDefault(),s.focus()):!r.shiftKey&&document.activeElement===s&&(r.preventDefault(),a.focus());};return document.addEventListener("keydown",i,{capture:true}),()=>document.removeEventListener("keydown",i,{capture:true})},[e]),t}function ro(e){let{state:t,controller:l,start:i,stop:r,clearSelection:c,submit:a}=Z(),s=e.config.ui?.position,o=he(e.config.ui?.strings),n=e.config.ui?.branding!==false,[u,H]=react.useState(null),[g,D]=react.useState(""),[E,K]=react.useState(e.config.capture?.element??true),[x,ee]=react.useState(e.config.capture?.fullPage??false),[Je,te]=react.useState(null),oe=t.phase==="review"||t.phase==="capturing"||t.phase==="submitting"||t.phase==="error"||t.phase==="success",Ze=oo(oe),[qe,et]=react.useState(0);react.useEffect(()=>{t.phase==="idle"&&et(chunkD5SBICBQ_cjs.i());},[t.phase]);let[tt,re]=react.useState(false),ie=react.useRef(t.phase);react.useEffect(()=>{if(ie.current==="success"&&t.phase==="idle"){re(true);let p=window.setTimeout(()=>re(false),1500);return ()=>window.clearTimeout(p)}ie.current=t.phase;},[t.phase]),react.useEffect(()=>{let p=e.config.ui?.shortcut;if(!p)return;let L=p.toLowerCase().split("+").map(v=>v.trim()),z=L[L.length-1]||"",B=new Set(L.slice(0,-1)),ae=v=>{let it=/Mac|iPod|iPhone|iPad/.test(navigator.platform);if(B.has("mod")){if(it?!v.metaKey:!v.ctrlKey)return}else if(B.has("ctrl")&&!v.ctrlKey||(B.has("meta")||B.has("cmd"))&&!v.metaKey)return;B.has("shift")&&!v.shiftKey||(B.has("alt")||B.has("option"))&&!v.altKey||v.key.toLowerCase()===z&&(v.preventDefault(),t.phase==="idle"?i():r());};return document.addEventListener("keydown",ae),()=>document.removeEventListener("keydown",ae)},[e.config.ui?.shortcut,t.phase,i,r]),react.useEffect(()=>l.subscribeHover(H),[l]),react.useEffect(()=>{let p=l.__unsafeGetSelectedElement();if(!p||t.phase==="idle"||t.phase==="picking"){te(null);return}let L=()=>{te(chunkD5SBICBQ_cjs.b(p.getBoundingClientRect()));};L();let z=()=>L();return window.addEventListener("scroll",z,{capture:true,passive:true}),window.addEventListener("resize",z,{passive:true}),()=>{window.removeEventListener("scroll",z,{capture:true}),window.removeEventListener("resize",z);}},[l,t.phase,t.selection?.selector]),react.useEffect(()=>{t.phase==="review"&&(D(""),K(e.config.capture?.element??true),ee(e.config.capture?.fullPage??false));},[t.phase,t.selection?.selector,e.config.capture?.element,e.config.capture?.fullPage]),react.useEffect(()=>{if(t.phase!=="success")return;let p=window.setTimeout(()=>r(),1200);return ()=>window.clearTimeout(p)},[t.phase,r]);let k=t.phase==="capturing"||t.phase==="submitting",S=t.phase==="picking"?u?.rect??null:Je??t.selection?.rect??null,Q=react.useMemo(()=>S?eo(S,360,s):null,[S?.x,S?.y,S?.width,S?.height,s]),ne=t.lastError?.message,V=react.useCallback(()=>{a(g,{capture:{element:E,fullPage:x}});},[a,g,E,x]),ot=react.useCallback(p=>{(p.metaKey||p.ctrlKey)&&p.key==="Enter"&&g.trim().length>0&&!k&&(p.preventDefault(),V());},[V,g,k]),rt=je(e.config.ui?.triggerStyle);return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(rt,{position:s,onClick:()=>i(),isVisible:t.phase==="idle",label:e.config.ui?.triggerLabel??o.triggerLabel,queueCount:qe,showSuccess:tt}),t.phase!=="idle"&&jsxRuntime.jsxs("div",{className:"bf-overlay",role:"presentation",children:[t.phase!=="picking"&&jsxRuntime.jsx("div",{className:"bf-blocker",role:"presentation",onClick:()=>r()}),S&&jsxRuntime.jsx(to,{rect:S}),t.phase==="picking"&&jsxRuntime.jsxs("div",{className:"bf-hint",role:"status","aria-live":"polite",children:[jsxRuntime.jsx("p",{id:"bf-hint-text",children:o.hintText}),jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>r(),"aria-label":o.cancelButton,children:o.cancelButton})]}),oe&&Q&&jsxRuntime.jsxs("div",{ref:Ze,className:"bf-panel",style:{left:Q.left,top:Q.top},role:"dialog","aria-modal":"true","aria-label":"Feedback form",children:[jsxRuntime.jsxs("div",{className:"bf-panelHeader",children:[jsxRuntime.jsx("div",{className:"bf-title",id:"bf-panel-title",children:o.panelTitle}),jsxRuntime.jsxs("div",{className:"bf-row",style:{justifyContent:"flex-end"},children:[jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>c(),disabled:k,"aria-label":o.rePickButton,children:o.rePickButton}),jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>r(),disabled:k,"aria-label":o.closeButton,children:o.closeButton})]})]}),jsxRuntime.jsxs("div",{className:"bf-panelBody",children:[jsxRuntime.jsx("textarea",{className:"bf-textarea",placeholder:o.textareaPlaceholder,value:g,onChange:p=>D(p.target.value),onKeyDown:ot,disabled:k,"aria-label":o.panelTitle}),jsxRuntime.jsxs("div",{className:"bf-row",role:"group","aria-label":o.screenshotElement,children:[jsxRuntime.jsxs("label",{children:[jsxRuntime.jsx("input",{type:"checkbox",checked:E,onChange:p=>K(p.target.checked),disabled:k}),o.screenshotElement]}),jsxRuntime.jsxs("label",{children:[jsxRuntime.jsx("input",{type:"checkbox",checked:x,onChange:p=>ee(p.target.checked),disabled:k}),o.screenshotFullPage]})]}),t.phase==="capturing"&&jsxRuntime.jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsxRuntime.jsx("span",{className:"bf-spinner","aria-hidden":"true"}),o.capturingText]}),t.phase==="submitting"&&jsxRuntime.jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsxRuntime.jsx("span",{className:"bf-spinner","aria-hidden":"true"}),o.submittingText]}),t.phase==="success"&&jsxRuntime.jsx("div",{className:"bf-status",role:"status","aria-live":"polite",children:o.successText}),t.phase==="error"&&ne&&jsxRuntime.jsx("div",{className:"bf-error",role:"alert",children:ne}),jsxRuntime.jsxs("div",{className:"bf-actions",children:[jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>r(),disabled:k,"aria-label":o.cancelButton,children:o.cancelButton}),jsxRuntime.jsx("button",{type:"button",className:"bf-btn bf-btnPrimary",onClick:V,disabled:k||g.trim().length===0,"aria-label":o.sendButton,children:o.sendButton})]})]}),n&&jsxRuntime.jsx("div",{className:"bf-watermark",children:jsxRuntime.jsx("a",{href:"https://blocfeed.com",target:"_blank",rel:"noopener noreferrer",children:"Powered by BlocFeed"})})]})]}),t.phase==="success"&&jsxRuntime.jsx("div",{className:"bf-toast",role:"status","aria-live":"polite",children:o.toastText})]})}function io(e){let t={...e.config??{},blocfeed_id:e.blocfeed_id},[l,i]=react.useState(null),r=!!t.diagnostics;react.useEffect(()=>{if(r)return chunkD5SBICBQ_cjs.k(t.diagnostics),()=>chunkD5SBICBQ_cjs.l()},[r]);let c=react.useRef(e.config?.metadata?.enrich);c.current=e.config?.metadata?.enrich;let a=react.useMemo(()=>{if(e.config)return {...e.config,metadata:{...e.config.metadata,enrich:async s=>{let o=c.current,n=o?await o(s):{},u=chunkD5SBICBQ_cjs.m();return {...n,...u.consoleLogs.length>0?{_consoleLogs:u.consoleLogs}:{},...u.networkErrors.length>0?{_networkErrors:u.networkErrors}:{}}}}}},[]);return react.useEffect(()=>{ge();let s=document.createElement("div");s.setAttribute("data-blocfeed-ui-root","true"),s.setAttribute("data-blocfeed-ui","true");let o=t.ui?.zIndex;typeof o=="number"&&s.style.setProperty("--bf-z",String(o));let n=t.ui?.theme;return n&&(n.accentColor&&s.style.setProperty("--bf-accent",n.accentColor),n.panelBackground&&s.style.setProperty("--bf-panel-bg",n.panelBackground),n.panelForeground&&s.style.setProperty("--bf-panel-fg",n.panelForeground),n.fontFamily&&s.style.setProperty("--bf-font",n.fontFamily)),document.body.appendChild(s),i(s),()=>{s.remove(),i(null);}},[t.ui?.zIndex,t.ui?.theme?.accentColor,t.ui?.theme?.panelBackground,t.ui?.theme?.panelForeground,t.ui?.theme?.fontFamily]),l?reactDom.createPortal(jsxRuntime.jsx(J,{blocfeed_id:t.blocfeed_id,...a?{config:a}:{},children:jsxRuntime.jsx(ro,{config:t})}),l):null}
503
+ exports.BlocFeedProvider=J;exports.BlocFeedWidget=io;exports.useBlocFeed=Z;
package/dist/main.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { B as BlocFeedConfig, a as BlocFeedState, b as BlocFeedController, C as CaptureConfig, S as SubmitResult } from './controller-D7kOehzb.cjs';
2
- export { c as BlocFeedError, d as BlocFeedUser, e as CaptureDiagnostics, f as CaptureResult, E as ElementDescriptor, F as FeedbackApiResponse, g as FeedbackPayload, I as ImageAsset, M as MaybePromise, h as MetadataConfig, i as MetadataContext, P as PickerConfig, R as Rect, j as ScreenshotAdapter, k as ScreenshotAdapterOptions, l as ScreenshotIntent, m as ScreenshotMime, n as SessionPhase, T as ThemeConfig, o as TransportConfig, p as TransportResult, q as TriggerStyle, W as WidgetPosition } from './controller-D7kOehzb.cjs';
1
+ import { B as BlocFeedConfig, a as BlocFeedState, b as BlocFeedController, C as CaptureConfig, S as SubmitResult } from './controller-DfhbkHXc.cjs';
2
+ export { c as BlocFeedError, d as BlocFeedStrings, e as BlocFeedUser, f as CaptureDiagnostics, g as CaptureResult, h as ConsoleEntry, D as DiagnosticsConfig, E as ElementDescriptor, F as FeedbackApiResponse, i as FeedbackPayload, I as ImageAsset, M as MaybePromise, j as MetadataConfig, k as MetadataContext, N as NetworkEntry, P as PickerConfig, R as Rect, l as ScreenshotAdapter, m as ScreenshotAdapterOptions, n as ScreenshotIntent, o as ScreenshotMime, p as SessionPhase, T as ThemeConfig, q as TransportConfig, r as TransportResult, s as TriggerStyle, W as WidgetPosition } from './controller-DfhbkHXc.cjs';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as react from 'react';
5
5
  import { ReactNode } from 'react';
package/dist/main.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { B as BlocFeedConfig, a as BlocFeedState, b as BlocFeedController, C as CaptureConfig, S as SubmitResult } from './controller-D7kOehzb.js';
2
- export { c as BlocFeedError, d as BlocFeedUser, e as CaptureDiagnostics, f as CaptureResult, E as ElementDescriptor, F as FeedbackApiResponse, g as FeedbackPayload, I as ImageAsset, M as MaybePromise, h as MetadataConfig, i as MetadataContext, P as PickerConfig, R as Rect, j as ScreenshotAdapter, k as ScreenshotAdapterOptions, l as ScreenshotIntent, m as ScreenshotMime, n as SessionPhase, T as ThemeConfig, o as TransportConfig, p as TransportResult, q as TriggerStyle, W as WidgetPosition } from './controller-D7kOehzb.js';
1
+ import { B as BlocFeedConfig, a as BlocFeedState, b as BlocFeedController, C as CaptureConfig, S as SubmitResult } from './controller-DfhbkHXc.js';
2
+ export { c as BlocFeedError, d as BlocFeedStrings, e as BlocFeedUser, f as CaptureDiagnostics, g as CaptureResult, h as ConsoleEntry, D as DiagnosticsConfig, E as ElementDescriptor, F as FeedbackApiResponse, i as FeedbackPayload, I as ImageAsset, M as MaybePromise, j as MetadataConfig, k as MetadataContext, N as NetworkEntry, P as PickerConfig, R as Rect, l as ScreenshotAdapter, m as ScreenshotAdapterOptions, n as ScreenshotIntent, o as ScreenshotMime, p as SessionPhase, T as ThemeConfig, q as TransportConfig, r as TransportResult, s as TriggerStyle, W as WidgetPosition } from './controller-DfhbkHXc.js';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as react from 'react';
5
5
  import { ReactNode } from 'react';
package/dist/main.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import {j,a,b}from'./chunk-FMFONS5S.js';import {createContext,useMemo,useState,useEffect,useContext,useCallback,useRef}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {createPortal}from'react-dom';import {AnimatePresence,motion}from'framer-motion';var k=createContext(null);function M(t){let e=useMemo(()=>j({...t.config??{},blocfeed_id:t.blocfeed_id}),[]),[i,r]=useState(()=>e.getState());return useEffect(()=>e.subscribe(r),[e]),useEffect(()=>e.setConfig({...t.config??{},blocfeed_id:t.blocfeed_id}),[e,t.config,t.blocfeed_id]),useEffect(()=>()=>e.destroy(),[e]),jsx(k.Provider,{value:{controller:e,state:i},children:t.children})}var Y="blocfeed-styles-v1",Se=`
2
+ import {j,k,l,m as m$1,a,i,b as b$1}from'./chunk-QPAFC4IL.js';import {createContext,useMemo,useState,useEffect,useContext,useRef,useCallback}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {createPortal}from'react-dom';import {AnimatePresence,motion}from'framer-motion';var $=createContext(null);function J(e){let t=useMemo(()=>j({...e.config??{},blocfeed_id:e.blocfeed_id}),[]),[l,i]=useState(()=>t.getState());return useEffect(()=>t.subscribe(i),[t]),useEffect(()=>t.setConfig({...e.config??{},blocfeed_id:e.blocfeed_id}),[t,e.config,e.blocfeed_id]),useEffect(()=>()=>t.destroy(),[t]),jsx($.Provider,{value:{controller:t,state:l},children:e.children})}var be="blocfeed-styles-v1",ct=`
3
3
  :where([data-blocfeed-ui-root]),
4
4
  :where([data-blocfeed-ui-root]) * {
5
5
  box-sizing: border-box;
@@ -386,5 +386,118 @@ import {j,a,b}from'./chunk-FMFONS5S.js';import {createContext,useMemo,useState,u
386
386
  white-space: nowrap;
387
387
  border: 0;
388
388
  }
389
- `;function J(){if(!a()||document.getElementById(Y))return;let t=document.createElement("style");t.id=Y,t.textContent=Se,document.head.appendChild(t);}function A(){let t=useContext(k);if(!t)throw new Error("useBlocFeed must be used within a <BlocFeedProvider />");return {state:t.state,controller:t.controller,start:t.controller.start,stop:t.controller.stop,clearSelection:t.controller.clearSelection,submit:t.controller.submit}}function c(t){switch(t){case "bottom-left":return "bf-trigger bf-trigger-bl";case "top-right":return "bf-trigger bf-trigger-tr";case "top-left":return "bf-trigger bf-trigger-tl";default:return "bf-trigger"}}function Q({position:t,onClick:e,isVisible:i}){return i?jsxs("button",{className:c(t),type:"button",onClick:e,"aria-label":"Give feedback",children:[jsx("span",{className:"bf-dot","aria-hidden":"true"}),"Feedback"]}):null}function ee({position:t,onClick:e,isVisible:i}){let[r,o]=useState(false);return jsx(AnimatePresence,{children:i&&jsxs(motion.button,{className:c(t),type:"button",onClick:e,onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),"aria-label":"Give feedback",initial:{scale:0,opacity:0},animate:{scale:1,opacity:1,padding:r?"10px 16px":"10px 10px"},exit:{scale:0,opacity:0},transition:{type:"spring",stiffness:500,damping:28},whileTap:{scale:.92},style:{overflow:"hidden"},children:[jsx(motion.span,{className:"bf-dot","aria-hidden":"true",animate:{scale:r?1:[1,1.2,1],boxShadow:r?"0 0 0 4px rgba(99, 102, 241, 0.18)":["0 0 0 4px rgba(99, 102, 241, 0.18)","0 0 0 8px rgba(99, 102, 241, 0.28)","0 0 0 4px rgba(99, 102, 241, 0.18)"]},transition:r?{type:"spring",stiffness:400,damping:20}:{duration:2,repeat:1/0,ease:"easeInOut"}}),jsx(AnimatePresence,{children:r&&jsx(motion.span,{initial:{opacity:0,width:0,x:-8},animate:{opacity:1,width:"auto",x:0},exit:{opacity:0,width:0,x:-8},transition:{type:"spring",stiffness:400,damping:25},style:{whiteSpace:"nowrap",overflow:"hidden"},children:"Feedback"})}),jsx(motion.span,{"aria-hidden":"true",style:{position:"absolute",inset:0,borderRadius:"inherit",border:"2px solid var(--bf-accent)",pointerEvents:"none"},initial:false,animate:{scale:1,opacity:0},whileTap:{scale:2.5,opacity:[.6,0]},transition:{duration:.4}})]})})}function te({size:t=14}){return jsx("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsx("path",{d:"M21 11.5a8.38 8.38 0 01-.9 3.8 8.5 8.5 0 01-7.6 4.7 8.38 8.38 0 01-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 01-.9-3.8 8.5 8.5 0 014.7-7.6 8.38 8.38 0 013.8-.9h.5a8.48 8.48 0 018 8v.5z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function oe({size:t=16}){return jsxs("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[jsx("path",{d:"M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),jsx("path",{d:"M22 6l-10 7L2 6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}function ie({position:t,onClick:e,isVisible:i}){let[r,o]=useState(false);return jsx(AnimatePresence,{children:i&&jsxs(motion.div,{style:{position:"fixed",zIndex:"var(--bf-z)"},className:c(t),initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{y:12,opacity:0,scale:.8},transition:{type:"spring",stiffness:400,damping:25},onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),children:[jsx(AnimatePresence,{children:r&&jsx(motion.div,{initial:{opacity:0,y:6,scale:.95},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:6,scale:.95},transition:{type:"spring",stiffness:500,damping:30},style:{position:"absolute",bottom:"calc(100% + 8px)",left:"50%",transform:"translateX(-50%)",padding:"6px 12px",borderRadius:"8px",background:"var(--bf-panel-bg)",border:"1px solid var(--bf-border)",boxShadow:"var(--bf-shadow)",whiteSpace:"nowrap",fontSize:"12px",color:"var(--bf-panel-fg)",pointerEvents:"none"},children:"Got feedback?"})}),jsx(motion.button,{type:"button",onClick:e,"aria-label":"Give feedback",style:{display:"flex",alignItems:"center",justifyContent:"center",width:"40px",height:"40px",borderRadius:"50%",border:"1px solid var(--bf-border)",background:"var(--bf-panel-bg)",color:"var(--bf-panel-fg)",boxShadow:"var(--bf-shadow)",cursor:"pointer",padding:0},animate:{y:[0,-3,0]},transition:{y:{duration:3,repeat:1/0,ease:"easeInOut"}},whileHover:{scale:1.1,borderColor:"var(--bf-accent)"},whileTap:{scale:.9},children:jsx(te,{size:16})})]})})}function ne(t){return t==="bottom-left"||t==="top-left"}function We(t){return `bf-trigger-edge ${ne(t)?"bf-trigger-edge-left":"bf-trigger-edge-right"}`}function se({position:t,onClick:e,isVisible:i}){let[r,o]=useState(false),l=ne(t);return jsx(AnimatePresence,{children:i&&jsxs(motion.button,{className:We(t),type:"button",onClick:e,onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),"aria-label":"Give feedback",initial:{opacity:0,width:0},animate:{opacity:1,width:r?140:22,height:r?40:90},exit:{width:0,opacity:0},transition:{type:"spring",stiffness:350,damping:30},whileTap:{scale:.97},style:{top:"50%",translateY:"-50%"},children:[jsxs(motion.span,{animate:{rotate:r?0:l?-90:90,opacity:r?1:.6},transition:{type:"spring",stiffness:300,damping:25},style:{display:"flex",alignItems:"center",gap:"8px",whiteSpace:"nowrap",fontSize:"12px",letterSpacing:"0.5px",textTransform:"uppercase"},children:[r&&jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:{type:"spring",stiffness:500,damping:20},style:{width:"6px",height:"6px",borderRadius:"50%",background:"var(--bf-accent)",flexShrink:0}}),"Feedback"]}),jsx(motion.span,{"aria-hidden":"true",animate:{opacity:r?1:0},style:{position:"absolute",top:0,bottom:0,[l?"left":"right"]:0,width:"2px",background:"var(--bf-accent)"}})]})})}function de({delay:t,hovered:e}){return jsx(motion.span,{"aria-hidden":"true",style:{position:"absolute",width:"12px",height:"12px",borderRadius:"50%",border:"2px solid var(--bf-accent)",pointerEvents:"none",left:"50%",top:"50%",x:"-50%",y:"-50%"},animate:e?{scale:1.3,opacity:.6}:{scale:[1,2.5],opacity:[.5,0]},transition:e?{type:"spring",stiffness:300,damping:20}:{duration:2,repeat:1/0,delay:t,ease:"easeOut"}})}function pe({position:t,onClick:e,isVisible:i}){let[r,o]=useState(false);return jsx(AnimatePresence,{children:i&&jsxs(motion.button,{className:c(t),type:"button",onClick:e,onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),"aria-label":"Give feedback",initial:{scale:0,opacity:0},animate:{scale:1,opacity:1,padding:r?"10px 16px":"10px 10px"},exit:{scale:0,opacity:0},transition:{type:"spring",stiffness:400,damping:25},whileTap:{scale:.92},style:{position:"relative",overflow:"visible"},children:[jsxs("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",pointerEvents:"none"},children:[jsx(de,{delay:0,hovered:r}),jsx(de,{delay:.7,hovered:r})]}),jsx(motion.span,{className:"bf-dot","aria-hidden":"true",style:{position:"relative",zIndex:1},animate:{scale:r?1.1:1},transition:{type:"spring",stiffness:400,damping:20}}),jsx(AnimatePresence,{children:r&&jsx(motion.span,{initial:{opacity:0,width:0,x:-12},animate:{opacity:1,width:"auto",x:0},exit:{opacity:0,width:0,x:-12},transition:{type:"spring",stiffness:400,damping:25},style:{whiteSpace:"nowrap",overflow:"hidden",position:"relative",zIndex:1},children:"Feedback"})})]})})}function Ge(t){switch(t){case "bottom-left":return "bf-trigger-minimal bf-trigger-bl";case "top-right":return "bf-trigger-minimal bf-trigger-tr";case "top-left":return "bf-trigger-minimal bf-trigger-tl";default:return "bf-trigger-minimal"}}function be({position:t,onClick:e,isVisible:i}){let[r,o]=useState(false);return jsx(AnimatePresence,{children:i&&jsxs(motion.button,{className:Ge(t),type:"button",onClick:e,onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),"aria-label":"Give feedback",initial:{opacity:0,y:5},animate:{opacity:r?1:.65,y:0},exit:{opacity:0,y:5},transition:{type:"spring",stiffness:400,damping:30},whileTap:{scale:.95},children:[jsx("span",{children:"Feedback"}),jsx(motion.span,{"aria-hidden":"true",style:{position:"absolute",bottom:4,left:4,right:4,height:"2px",background:"var(--bf-accent)",borderRadius:"1px",transformOrigin:"left"},initial:false,animate:{scaleX:r?1:0},transition:{type:"spring",stiffness:400,damping:25}})]})})}function ge({position:t,onClick:e,isVisible:i}){let[r,o]=useState(false);return jsx(AnimatePresence,{children:i&&jsxs(motion.button,{className:c(t),type:"button",onClick:e,onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),"aria-label":"Give feedback",initial:{scale:0,opacity:0,rotate:-45},animate:{scale:1,opacity:1,rotate:0,padding:r?"10px 16px":"10px 10px"},exit:{rotate:180,scale:0,opacity:0},transition:{type:"spring",stiffness:400,damping:22},whileTap:{scale:.9,rotate:360},style:{overflow:"hidden"},children:[jsx(motion.span,{style:{display:"inline-flex",flexShrink:0},animate:r?{scale:1.2,rotate:0}:{rotate:[-5,5,-5]},transition:r?{type:"spring",stiffness:500,damping:12}:{duration:3,repeat:1/0,ease:"easeInOut"},children:jsx(oe,{size:16})}),jsx(AnimatePresence,{children:r&&jsx(motion.span,{initial:{opacity:0,width:0,x:-16},animate:{opacity:1,width:"auto",x:0},exit:{opacity:0,width:0,x:-16},transition:{type:"spring",stiffness:350,damping:25,delay:.03},style:{whiteSpace:"nowrap",overflow:"hidden"},children:"Feedback"})})]})})}function me(t){switch(t){case "dot":return ee;case "bubble":return ie;case "edge-tab":return se;case "pulse-ring":return pe;case "minimal":return be;case "icon-pop":return ge;default:return Q}}function xe(t,e,i){return Math.max(e,Math.min(i,t))}function qe(t,e,i="bottom-right"){let o=window.innerWidth,l=window.innerHeight,n;n=xe(t.x,12,Math.max(12,o-e-12));let p=t.y+t.height+12,S=Math.max(12,t.y-240);return {top:p+240<=l?p:S,left:n}}function Ye(t){let{rect:e}=t,i={left:`${e.x}px`,top:`${e.y}px`,width:`${Math.max(0,e.width)}px`,height:`${Math.max(0,e.height)}px`};return jsx("div",{className:"bf-highlight",style:i,"aria-hidden":"true"})}function Je(t){let e=useRef(null);return useEffect(()=>{if(!t||!e.current)return;e.current.querySelector(".bf-textarea")?.focus();let r=o=>{if(o.key!=="Tab"||!e.current)return;let l=e.current.querySelectorAll('button:not([disabled]), textarea:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex="-1"])');if(l.length===0)return;let n=l[0],p=l[l.length-1];o.shiftKey&&document.activeElement===n?(o.preventDefault(),p.focus()):!o.shiftKey&&document.activeElement===p&&(o.preventDefault(),n.focus());};return document.addEventListener("keydown",r,{capture:true}),()=>document.removeEventListener("keydown",r,{capture:true})},[t]),e}function Qe(t){let{state:e,controller:i,start:r,stop:o,clearSelection:l,submit:n}=A(),p=t.config.ui?.position,[S,_]=useState(null),[g,D]=useState(""),[B,O]=useState(t.config.capture?.element??true),[E,G]=useState(t.config.capture?.fullPage??false),[ye,K]=useState(null),V=e.phase==="review"||e.phase==="capturing"||e.phase==="submitting"||e.phase==="error"||e.phase==="success",ve=Je(V);useEffect(()=>i.subscribeHover(_),[i]),useEffect(()=>{let s=i.__unsafeGetSelectedElement();if(!s||e.phase==="idle"||e.phase==="picking"){K(null);return}let $=()=>{K(b(s.getBoundingClientRect()));};$();let w=()=>$();return window.addEventListener("scroll",w,{capture:true,passive:true}),window.addEventListener("resize",w,{passive:true}),()=>{window.removeEventListener("scroll",w,{capture:true}),window.removeEventListener("resize",w);}},[i,e.phase,e.selection?.selector]),useEffect(()=>{e.phase==="review"&&(D(""),O(t.config.capture?.element??true),G(t.config.capture?.fullPage??false));},[e.phase,e.selection?.selector,t.config.capture?.element,t.config.capture?.fullPage]),useEffect(()=>{if(e.phase!=="success")return;let s=window.setTimeout(()=>o(),1200);return ()=>window.clearTimeout(s)},[e.phase,o]);let f=e.phase==="capturing"||e.phase==="submitting",b$1=e.phase==="picking"?S?.rect??null:ye??e.selection?.rect??null,N=useMemo(()=>b$1?qe(b$1,360,p):null,[b$1?.x,b$1?.y,b$1?.width,b$1?.height,p]),X=e.lastError?.message,z=useCallback(()=>{n(g,{capture:{element:B,fullPage:E}});},[n,g,B,E]),we=useCallback(s=>{(s.metaKey||s.ctrlKey)&&s.key==="Enter"&&g.trim().length>0&&!f&&(s.preventDefault(),z());},[z,g,f]),ke=me(t.config.ui?.triggerStyle);return jsxs(Fragment,{children:[jsx(ke,{position:p,onClick:()=>r(),isVisible:e.phase==="idle"}),e.phase!=="idle"&&jsxs("div",{className:"bf-overlay",role:"presentation",children:[e.phase!=="picking"&&jsx("div",{className:"bf-blocker",role:"presentation",onClick:()=>o()}),b$1&&jsx(Ye,{rect:b$1}),e.phase==="picking"&&jsxs("div",{className:"bf-hint",role:"status","aria-live":"polite",children:[jsxs("p",{id:"bf-hint-text",children:["Click an element to attach your feedback. Press ",jsx("strong",{children:"Esc"})," to cancel."]}),jsx("button",{type:"button",className:"bf-btn",onClick:()=>o(),"aria-label":"Cancel element selection",children:"Cancel"})]}),V&&N&&jsxs("div",{ref:ve,className:"bf-panel",style:{left:N.left,top:N.top},role:"dialog","aria-modal":"true","aria-label":"Feedback form",children:[jsxs("div",{className:"bf-panelHeader",children:[jsx("div",{className:"bf-title",id:"bf-panel-title",children:"Feedback"}),jsxs("div",{className:"bf-row",style:{justifyContent:"flex-end"},children:[jsx("button",{type:"button",className:"bf-btn",onClick:()=>l(),disabled:f,"aria-label":"Re-pick element",children:"Re-pick"}),jsx("button",{type:"button",className:"bf-btn",onClick:()=>o(),disabled:f,"aria-label":"Close feedback form",children:"Close"})]})]}),jsxs("div",{className:"bf-panelBody",children:[jsx("textarea",{className:"bf-textarea",placeholder:"What's happening? What did you expect?",value:g,onChange:s=>D(s.target.value),onKeyDown:we,disabled:f,"aria-label":"Feedback message"}),jsxs("div",{className:"bf-row",role:"group","aria-label":"Screenshot options",children:[jsxs("label",{children:[jsx("input",{type:"checkbox",checked:B,onChange:s=>O(s.target.checked),disabled:f}),"Screenshot element"]}),jsxs("label",{children:[jsx("input",{type:"checkbox",checked:E,onChange:s=>G(s.target.checked),disabled:f}),"Full page"]})]}),e.phase==="capturing"&&jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsx("span",{className:"bf-spinner","aria-hidden":"true"}),"Capturing screenshots\u2026"]}),e.phase==="submitting"&&jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsx("span",{className:"bf-spinner","aria-hidden":"true"}),"Submitting\u2026"]}),e.phase==="success"&&jsx("div",{className:"bf-status",role:"status","aria-live":"polite",children:"Sent. Thank you!"}),e.phase==="error"&&X&&jsx("div",{className:"bf-error",role:"alert",children:X}),jsxs("div",{className:"bf-actions",children:[jsx("button",{type:"button",className:"bf-btn",onClick:()=>o(),disabled:f,"aria-label":"Cancel feedback",children:"Cancel"}),jsx("button",{type:"button",className:"bf-btn bf-btnPrimary",onClick:z,disabled:f||g.trim().length===0,"aria-label":"Send feedback",children:"Send"})]})]})]})]}),e.phase==="success"&&jsx("div",{className:"bf-toast",role:"status","aria-live":"polite",children:"Feedback sent"})]})}function Ze(t){let e={...t.config??{},blocfeed_id:t.blocfeed_id},[i,r]=useState(null);return useEffect(()=>{J();let o=document.createElement("div");o.setAttribute("data-blocfeed-ui-root","true"),o.setAttribute("data-blocfeed-ui","true");let l=e.ui?.zIndex;typeof l=="number"&&o.style.setProperty("--bf-z",String(l));let n=e.ui?.theme;return n&&(n.accentColor&&o.style.setProperty("--bf-accent",n.accentColor),n.panelBackground&&o.style.setProperty("--bf-panel-bg",n.panelBackground),n.panelForeground&&o.style.setProperty("--bf-panel-fg",n.panelForeground),n.fontFamily&&o.style.setProperty("--bf-font",n.fontFamily)),document.body.appendChild(o),r(o),()=>{o.remove(),r(null);}},[e.ui?.zIndex,e.ui?.theme?.accentColor,e.ui?.theme?.panelBackground,e.ui?.theme?.panelForeground,e.ui?.theme?.fontFamily]),i?createPortal(jsx(M,{blocfeed_id:e.blocfeed_id,...t.config?{config:t.config}:{},children:jsx(Qe,{config:e})}),i):null}
390
- export{M as BlocFeedProvider,Ze as BlocFeedWidget,A as useBlocFeed};
389
+
390
+ /* ------------------------------------------------------------------ */
391
+ /* Queue badge */
392
+ /* ------------------------------------------------------------------ */
393
+
394
+ :where([data-blocfeed-ui-root]) .bf-badge {
395
+ display: inline-flex;
396
+ align-items: center;
397
+ justify-content: center;
398
+ min-width: 16px;
399
+ height: 16px;
400
+ padding: 0 4px;
401
+ border-radius: 999px;
402
+ background: var(--bf-danger);
403
+ color: white;
404
+ font-size: 10px;
405
+ font-weight: 600;
406
+ line-height: 1;
407
+ flex-shrink: 0;
408
+ }
409
+
410
+ :where([data-blocfeed-ui-root]) .bf-badge-float {
411
+ position: absolute;
412
+ top: -4px;
413
+ right: -4px;
414
+ }
415
+
416
+ /* ------------------------------------------------------------------ */
417
+ /* Typewriter cursor */
418
+ /* ------------------------------------------------------------------ */
419
+
420
+ :where([data-blocfeed-ui-root]) .bf-cursor {
421
+ display: inline-block;
422
+ width: 1px;
423
+ height: 1em;
424
+ background: var(--bf-panel-fg);
425
+ margin-left: 1px;
426
+ vertical-align: text-bottom;
427
+ animation: bf-blink 1s steps(2) infinite;
428
+ }
429
+
430
+ @keyframes bf-blink {
431
+ 0% { opacity: 1; }
432
+ 50% { opacity: 0; }
433
+ }
434
+
435
+ /* ------------------------------------------------------------------ */
436
+ /* Panel / toast / hint entrance animations */
437
+ /* ------------------------------------------------------------------ */
438
+
439
+ :where([data-blocfeed-ui-root]) .bf-panel {
440
+ animation: bf-panel-in 0.2s ease-out;
441
+ }
442
+
443
+ @keyframes bf-panel-in {
444
+ from { opacity: 0; transform: translateY(8px); }
445
+ to { opacity: 1; transform: translateY(0); }
446
+ }
447
+
448
+ :where([data-blocfeed-ui-root]) .bf-toast {
449
+ animation: bf-toast-in 0.25s ease-out;
450
+ }
451
+
452
+ @keyframes bf-toast-in {
453
+ from { opacity: 0; transform: translateX(-50%) translateY(12px); }
454
+ to { opacity: 1; transform: translateX(-50%) translateY(0); }
455
+ }
456
+
457
+ :where([data-blocfeed-ui-root]) .bf-hint {
458
+ animation: bf-hint-in 0.2s ease-out;
459
+ }
460
+
461
+ @keyframes bf-hint-in {
462
+ from { opacity: 0; transform: translateX(-50%) translateY(-10px); }
463
+ to { opacity: 1; transform: translateX(-50%) translateY(0); }
464
+ }
465
+
466
+ /* ------------------------------------------------------------------ */
467
+ /* Reduced motion */
468
+ /* ------------------------------------------------------------------ */
469
+
470
+ /* ------------------------------------------------------------------ */
471
+ /* Watermark */
472
+ /* ------------------------------------------------------------------ */
473
+
474
+ :where([data-blocfeed-ui-root]) .bf-watermark {
475
+ padding: 6px 12px;
476
+ border-top: 1px solid rgba(255, 255, 255, 0.06);
477
+ text-align: center;
478
+ }
479
+
480
+ :where([data-blocfeed-ui-root]) .bf-watermark a {
481
+ font-size: 10px;
482
+ color: rgba(243, 244, 246, 0.35);
483
+ text-decoration: none;
484
+ }
485
+
486
+ :where([data-blocfeed-ui-root]) .bf-watermark a:hover {
487
+ color: var(--bf-accent);
488
+ }
489
+
490
+ /* ------------------------------------------------------------------ */
491
+ /* Reduced motion */
492
+ /* ------------------------------------------------------------------ */
493
+
494
+ @media (prefers-reduced-motion: reduce) {
495
+ :where([data-blocfeed-ui-root]) .bf-panel,
496
+ :where([data-blocfeed-ui-root]) .bf-toast,
497
+ :where([data-blocfeed-ui-root]) .bf-hint,
498
+ :where([data-blocfeed-ui-root]) .bf-cursor {
499
+ animation: none;
500
+ }
501
+ }
502
+ `;function ge(){if(!a()||document.getElementById(be))return;let e=document.createElement("style");e.id=be,e.textContent=ct,document.head.appendChild(e);}var me={triggerLabel:"Feedback",panelTitle:"Feedback",hintText:"Click an element to attach your feedback. Press Esc to cancel.",cancelButton:"Cancel",rePickButton:"Re-pick",closeButton:"Close",textareaPlaceholder:"What's happening? What did you expect?",screenshotElement:"Screenshot element",screenshotFullPage:"Full page",capturingText:"Capturing screenshots\u2026",submittingText:"Submitting\u2026",successText:"Sent. Thank you!",toastText:"Feedback sent",sendButton:"Send"};function he(e){return e?{...me,...e}:me}function Z(){let e=useContext($);if(!e)throw new Error("useBlocFeed must be used within a <BlocFeedProvider />");return {state:e.state,controller:e.controller,start:e.controller.start,stop:e.controller.stop,clearSelection:e.controller.clearSelection,submit:e.controller.submit}}function m(e){switch(e){case "bottom-left":return "bf-trigger bf-trigger-bl";case "top-right":return "bf-trigger bf-trigger-tr";case "top-left":return "bf-trigger bf-trigger-tl";default:return "bf-trigger"}}function f({size:e=14}){return jsx("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsx("path",{d:"M20 6L9 17l-5-5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function xe({size:e=14}){return jsx("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsx("path",{d:"M21 11.5a8.38 8.38 0 01-.9 3.8 8.5 8.5 0 01-7.6 4.7 8.38 8.38 0 01-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 01-.9-3.8 8.5 8.5 0 014.7-7.6 8.38 8.38 0 013.8-.9h.5a8.48 8.48 0 018 8v.5z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function ye({size:e=16}){return jsxs("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[jsx("path",{d:"M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),jsx("path",{d:"M22 6l-10 7L2 6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}function we({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){return l?jsxs("button",{className:m(e),type:"button",onClick:t,"aria-label":i,children:[c?jsx("span",{style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})}):jsxs(Fragment,{children:[jsx("span",{className:"bf-dot","aria-hidden":"true"}),i]}),r>0&&jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]}):null}function b(){let[e,t]=useState(()=>typeof window>"u"?false:window.matchMedia("(prefers-reduced-motion: reduce)").matches);return useEffect(()=>{let l=window.matchMedia("(prefers-reduced-motion: reduce)"),i=r=>t(r.matches);return l.addEventListener("change",i),()=>l.removeEventListener("change",i)},[]),e}var mt={duration:.18,ease:"easeOut"},ht={duration:0};function Te({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=useState(false),o=b(),n=o?ht:mt;return jsx(AnimatePresence,{mode:"wait",children:l&&jsx(motion.button,{className:m(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:n,whileTap:{scale:.92},style:{overflow:"hidden"},children:c?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:n,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})},"success"):jsxs(Fragment,{children:[jsx(motion.span,{className:"bf-dot","aria-hidden":"true",animate:o?{}:{scale:a?1:[1,1.2,1],boxShadow:a?"0 0 0 4px rgba(99, 102, 241, 0.18)":["0 0 0 4px rgba(99, 102, 241, 0.18)","0 0 0 8px rgba(99, 102, 241, 0.28)","0 0 0 4px rgba(99, 102, 241, 0.18)"]},transition:a||o?n:{duration:2,repeat:1/0,ease:"easeInOut"}}),jsx(AnimatePresence,{mode:"wait",children:a&&jsx(motion.span,{initial:{opacity:0,x:o?0:-6},animate:{opacity:1,x:0},exit:{opacity:0,x:o?0:-6},transition:n,style:{whiteSpace:"nowrap"},children:i},"label")}),r>0&&jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"dot")})}var wt={duration:.18,ease:"easeOut"},Ee={duration:0};function Ce({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=useState(false),o=b(),n=o?Ee:wt;return jsx(AnimatePresence,{mode:"wait",children:l&&jsxs(motion.div,{className:m(e),initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{y:8,opacity:0},transition:n,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),style:{background:"transparent",border:"none",boxShadow:"none",padding:0},children:[jsx(AnimatePresence,{mode:"wait",children:a&&jsx(motion.div,{initial:{opacity:0,y:o?0:4},animate:{opacity:1,y:0},exit:{opacity:0,y:o?0:4},transition:n,style:{position:"absolute",bottom:"calc(100% + 8px)",left:"50%",transform:"translateX(-50%)",padding:"6px 12px",borderRadius:"8px",background:"var(--bf-panel-bg)",border:"1px solid var(--bf-border)",boxShadow:"var(--bf-shadow)",whiteSpace:"nowrap",fontSize:"12px",color:"var(--bf-panel-fg)",pointerEvents:"none"},children:i},"tooltip")}),jsxs(motion.button,{type:"button",onClick:t,"aria-label":i,style:{position:"relative",display:"flex",alignItems:"center",justifyContent:"center",width:"40px",height:"40px",borderRadius:"50%",border:"1px solid var(--bf-border)",background:"var(--bf-panel-bg)",color:"var(--bf-panel-fg)",boxShadow:"var(--bf-shadow)",cursor:"pointer",padding:0},animate:o?{}:{y:[0,-3,0]},transition:o?Ee:{y:{duration:3,repeat:1/0,ease:"easeInOut"}},whileHover:{scale:1.1,borderColor:"var(--bf-accent)"},whileTap:{scale:.9},children:[c?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:n,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:16})},"success"):jsx(xe,{size:16}),r>0&&jsx("span",{className:"bf-badge bf-badge-float","aria-label":`${r} queued`,children:r})]})]},"bubble")})}var Pt={duration:.2,ease:"easeOut"},Et={duration:0};function Be(e){return e==="bottom-left"||e==="top-left"}function St(e){return `bf-trigger-edge ${Be(e)?"bf-trigger-edge-left":"bf-trigger-edge-right"}`}function Fe({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=useState(false),o=Be(e),n=b(),u=n?Et:Pt;return jsx(AnimatePresence,{mode:"wait",children:l&&jsx(motion.button,{className:St(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{opacity:0,width:0},animate:{opacity:1,width:a?140:22,height:a?40:90},exit:{width:0,opacity:0},transition:u,whileTap:{scale:.97},style:{top:"50%",translateY:"-50%"},children:c?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:u,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})},"success"):jsxs(Fragment,{children:[jsxs(motion.span,{animate:{rotate:n||a?0:o?-90:90,opacity:a?1:.6},transition:u,style:{display:"flex",alignItems:"center",gap:"8px",whiteSpace:"nowrap",fontSize:"12px",letterSpacing:"0.5px",textTransform:"uppercase"},children:[a&&jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:{duration:.12},style:{width:"6px",height:"6px",borderRadius:"50%",background:"var(--bf-accent)",flexShrink:0}}),i]}),jsx(motion.span,{"aria-hidden":"true",animate:{opacity:a?1:0},transition:{duration:.12},style:{position:"absolute",top:0,bottom:0,[o?"left":"right"]:0,width:"2px",background:"var(--bf-accent)"}}),r>0&&jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"edge-tab")})}var Bt={duration:.18,ease:"easeOut"},Ft={duration:0};function Me({delay:e,hovered:t,reduced:l}){return l?null:jsx(motion.span,{"aria-hidden":"true",style:{position:"absolute",width:"10px",height:"10px",borderRadius:"50%",border:"2px solid var(--bf-accent)",pointerEvents:"none"},animate:t?{scale:1,opacity:0}:{scale:[1,1.8],opacity:[.5,0]},transition:t?{duration:.15}:{duration:2,repeat:1/0,delay:e,ease:"easeOut"}})}function ze({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=useState(false),o=b(),n=o?Ft:Bt;return jsx(AnimatePresence,{mode:"wait",children:l&&jsx(motion.button,{className:m(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:n,whileTap:{scale:.92},style:{overflow:"hidden"},children:c?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:n,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})},"success"):jsxs(Fragment,{children:[jsxs("span",{style:{position:"relative",display:"flex",alignItems:"center",justifyContent:"center",width:"10px",height:"10px",flexShrink:0},children:[jsx(Me,{delay:0,hovered:a,reduced:o}),jsx(Me,{delay:.7,hovered:a,reduced:o}),jsx(motion.span,{className:"bf-dot","aria-hidden":"true",style:{position:"relative",zIndex:1}})]}),jsx(AnimatePresence,{mode:"wait",children:a&&jsx(motion.span,{initial:{opacity:0,x:o?0:-6},animate:{opacity:1,x:0},exit:{opacity:0,x:o?0:-6},transition:n,style:{whiteSpace:"nowrap"},children:i},"label")}),r>0&&jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"pulse-ring")})}var zt={duration:.18,ease:"easeOut"},It={duration:0};function At(e){switch(e){case "bottom-left":return "bf-trigger-minimal bf-trigger-bl";case "top-right":return "bf-trigger-minimal bf-trigger-tr";case "top-left":return "bf-trigger-minimal bf-trigger-tl";default:return "bf-trigger-minimal"}}function We({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=useState(false),o=b(),n=o?It:zt;return jsx(AnimatePresence,{mode:"wait",children:l&&jsxs(motion.button,{className:At(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{opacity:0,y:o?0:5},animate:{opacity:a?1:.65,y:0},exit:{opacity:0,y:o?0:5},transition:n,whileTap:{scale:.95},children:[c?jsx("span",{style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})}):jsxs(Fragment,{children:[jsx("span",{children:i}),r>0&&jsx("span",{className:"bf-badge",style:{marginLeft:"4px"},"aria-label":`${r} queued`,children:r})]}),!o&&jsx(motion.span,{"aria-hidden":"true",style:{position:"absolute",bottom:4,left:4,right:4,height:"2px",background:"var(--bf-accent)",borderRadius:"1px",transformOrigin:"left"},initial:false,animate:{scaleX:a?1:0},transition:n})]},"minimal")})}var Ot={duration:.18,ease:"easeOut"},Ht={duration:0};function Oe({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=useState(false),o=b(),n=o?Ht:Ot;return jsx(AnimatePresence,{mode:"wait",children:l&&jsx(motion.button,{className:m(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:n,whileTap:{scale:.9},style:{overflow:"hidden"},children:c?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:n,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})},"success"):jsxs(Fragment,{children:[jsx(motion.span,{style:{display:"inline-flex",flexShrink:0},animate:o?{}:a?{scale:1.2,rotate:0}:{rotate:[-5,5,-5]},transition:a||o?n:{duration:3,repeat:1/0,ease:"easeInOut"},children:jsx(ye,{size:16})}),jsx(AnimatePresence,{mode:"wait",children:a&&jsx(motion.span,{initial:{opacity:0,x:o?0:-8},animate:{opacity:1,x:0},exit:{opacity:0,x:o?0:-8},transition:n,style:{whiteSpace:"nowrap"},children:i},"label")}),r>0&&jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"icon-pop")})}var Xt={duration:.18,ease:"easeOut"},Yt={duration:0};function Ke({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=useState(false),o=b(),n=o?Yt:Xt;return jsx(AnimatePresence,{mode:"wait",children:l&&jsx(motion.button,{className:m(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:n,whileTap:{scale:.92},style:{overflow:"hidden"},children:c?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:n,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})},"success"):jsxs(Fragment,{children:[jsxs("span",{style:{position:"relative",display:"inline-flex",alignItems:"center",justifyContent:"center",width:"10px",height:"10px",flexShrink:0},children:[jsx(motion.span,{"aria-hidden":"true",style:{width:"10px",height:"10px",borderRadius:"50%",background:"var(--bf-accent)",position:"relative",zIndex:1},animate:o?{}:{opacity:a?1:[.5,1,.5],boxShadow:a?"0 0 8px 2px var(--bf-accent)":["0 0 4px 1px var(--bf-accent)","0 0 12px 4px var(--bf-accent)","0 0 4px 1px var(--bf-accent)"]},transition:a||o?n:{duration:2,repeat:1/0,ease:"easeInOut"}}),!a&&!o&&jsx(motion.span,{"aria-hidden":"true",style:{position:"absolute",width:"18px",height:"2px",background:"linear-gradient(90deg, var(--bf-accent), transparent)",transformOrigin:"left center",left:"5px",top:"4px"},animate:{rotate:[0,360]},transition:{duration:4,repeat:1/0,ease:"linear"}})]}),jsx(AnimatePresence,{mode:"wait",children:a&&jsx(motion.span,{initial:{opacity:0,x:o?0:-6},animate:{opacity:1,x:0},exit:{opacity:0,x:o?0:-6},transition:n,style:{whiteSpace:"nowrap"},children:i},"label")}),r>0&&jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"beacon")})}var Gt={duration:.18,ease:"easeOut"},Jt={duration:0};function Ue({position:e,onClick:t,isVisible:l,label:i,queueCount:r,showSuccess:c}){let[a,s]=useState(false),[o,n]=useState(0),u=b(),H=u?Jt:Gt,g=useRef(null);useEffect(()=>{if(g.current&&(clearInterval(g.current),g.current=null),!l||a||u){n(a||u?i.length:0);return}let E=8,K=i.length*2+E*2,x=0;return g.current=setInterval(()=>{x=(x+1)%K,x<=i.length?n(x):x<=i.length+E?n(i.length):x<=i.length*2+E?n(i.length*2+E-x):n(0);},100),()=>{g.current&&(clearInterval(g.current),g.current=null);}},[l,a,u,i]);let D=i.slice(0,o);return jsx(AnimatePresence,{mode:"wait",children:l&&jsx(motion.button,{className:m(e),type:"button",onClick:t,onMouseEnter:()=>s(true),onMouseLeave:()=>s(false),"aria-label":i,initial:{opacity:0,y:u?0:5},animate:{opacity:1,y:0},exit:{opacity:0,y:u?0:5},transition:H,whileTap:{scale:.95},style:{minWidth:"44px"},children:c?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:H,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})},"success"):jsxs(Fragment,{children:[jsx("span",{className:"bf-dot","aria-hidden":"true"}),jsxs("span",{style:{whiteSpace:"nowrap",minWidth:"1ch"},children:[D,jsx("span",{className:"bf-cursor","aria-hidden":"true"})]}),r>0&&jsx("span",{className:"bf-badge","aria-label":`${r} queued`,children:r})]})},"typewriter")})}function je(e){switch(e){case "dot":return Te;case "bubble":return Ce;case "edge-tab":return Fe;case "pulse-ring":return ze;case "minimal":return We;case "icon-pop":return Oe;case "beacon":return Ke;case "typewriter":return Ue;default:return we}}function Ve(e,t,l){return Math.max(t,Math.min(l,e))}function eo(e,t,l="bottom-right"){let r=window.innerWidth,c=window.innerHeight,a;a=Ve(e.x,12,Math.max(12,r-t-12));let s=e.y+e.height+12,o=Math.max(12,e.y-240);return {top:s+240<=c?s:o,left:a}}function to(e){let{rect:t}=e,l={left:`${t.x}px`,top:`${t.y}px`,width:`${Math.max(0,t.width)}px`,height:`${Math.max(0,t.height)}px`};return jsx("div",{className:"bf-highlight",style:l,"aria-hidden":"true"})}function oo(e){let t=useRef(null);return useEffect(()=>{if(!e||!t.current)return;t.current.querySelector(".bf-textarea")?.focus();let i=r=>{if(r.key!=="Tab"||!t.current)return;let c=t.current.querySelectorAll('button:not([disabled]), textarea:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex="-1"])');if(c.length===0)return;let a=c[0],s=c[c.length-1];r.shiftKey&&document.activeElement===a?(r.preventDefault(),s.focus()):!r.shiftKey&&document.activeElement===s&&(r.preventDefault(),a.focus());};return document.addEventListener("keydown",i,{capture:true}),()=>document.removeEventListener("keydown",i,{capture:true})},[e]),t}function ro(e){let{state:t,controller:l,start:i$1,stop:r,clearSelection:c,submit:a}=Z(),s=e.config.ui?.position,o=he(e.config.ui?.strings),n=e.config.ui?.branding!==false,[u,H]=useState(null),[g,D]=useState(""),[E,K]=useState(e.config.capture?.element??true),[x,ee]=useState(e.config.capture?.fullPage??false),[Je,te]=useState(null),oe=t.phase==="review"||t.phase==="capturing"||t.phase==="submitting"||t.phase==="error"||t.phase==="success",Ze=oo(oe),[qe,et]=useState(0);useEffect(()=>{t.phase==="idle"&&et(i());},[t.phase]);let[tt,re]=useState(false),ie=useRef(t.phase);useEffect(()=>{if(ie.current==="success"&&t.phase==="idle"){re(true);let p=window.setTimeout(()=>re(false),1500);return ()=>window.clearTimeout(p)}ie.current=t.phase;},[t.phase]),useEffect(()=>{let p=e.config.ui?.shortcut;if(!p)return;let L=p.toLowerCase().split("+").map(v=>v.trim()),z=L[L.length-1]||"",B=new Set(L.slice(0,-1)),ae=v=>{let it=/Mac|iPod|iPhone|iPad/.test(navigator.platform);if(B.has("mod")){if(it?!v.metaKey:!v.ctrlKey)return}else if(B.has("ctrl")&&!v.ctrlKey||(B.has("meta")||B.has("cmd"))&&!v.metaKey)return;B.has("shift")&&!v.shiftKey||(B.has("alt")||B.has("option"))&&!v.altKey||v.key.toLowerCase()===z&&(v.preventDefault(),t.phase==="idle"?i$1():r());};return document.addEventListener("keydown",ae),()=>document.removeEventListener("keydown",ae)},[e.config.ui?.shortcut,t.phase,i$1,r]),useEffect(()=>l.subscribeHover(H),[l]),useEffect(()=>{let p=l.__unsafeGetSelectedElement();if(!p||t.phase==="idle"||t.phase==="picking"){te(null);return}let L=()=>{te(b$1(p.getBoundingClientRect()));};L();let z=()=>L();return window.addEventListener("scroll",z,{capture:true,passive:true}),window.addEventListener("resize",z,{passive:true}),()=>{window.removeEventListener("scroll",z,{capture:true}),window.removeEventListener("resize",z);}},[l,t.phase,t.selection?.selector]),useEffect(()=>{t.phase==="review"&&(D(""),K(e.config.capture?.element??true),ee(e.config.capture?.fullPage??false));},[t.phase,t.selection?.selector,e.config.capture?.element,e.config.capture?.fullPage]),useEffect(()=>{if(t.phase!=="success")return;let p=window.setTimeout(()=>r(),1200);return ()=>window.clearTimeout(p)},[t.phase,r]);let k=t.phase==="capturing"||t.phase==="submitting",S=t.phase==="picking"?u?.rect??null:Je??t.selection?.rect??null,Q=useMemo(()=>S?eo(S,360,s):null,[S?.x,S?.y,S?.width,S?.height,s]),ne=t.lastError?.message,V=useCallback(()=>{a(g,{capture:{element:E,fullPage:x}});},[a,g,E,x]),ot=useCallback(p=>{(p.metaKey||p.ctrlKey)&&p.key==="Enter"&&g.trim().length>0&&!k&&(p.preventDefault(),V());},[V,g,k]),rt=je(e.config.ui?.triggerStyle);return jsxs(Fragment,{children:[jsx(rt,{position:s,onClick:()=>i$1(),isVisible:t.phase==="idle",label:e.config.ui?.triggerLabel??o.triggerLabel,queueCount:qe,showSuccess:tt}),t.phase!=="idle"&&jsxs("div",{className:"bf-overlay",role:"presentation",children:[t.phase!=="picking"&&jsx("div",{className:"bf-blocker",role:"presentation",onClick:()=>r()}),S&&jsx(to,{rect:S}),t.phase==="picking"&&jsxs("div",{className:"bf-hint",role:"status","aria-live":"polite",children:[jsx("p",{id:"bf-hint-text",children:o.hintText}),jsx("button",{type:"button",className:"bf-btn",onClick:()=>r(),"aria-label":o.cancelButton,children:o.cancelButton})]}),oe&&Q&&jsxs("div",{ref:Ze,className:"bf-panel",style:{left:Q.left,top:Q.top},role:"dialog","aria-modal":"true","aria-label":"Feedback form",children:[jsxs("div",{className:"bf-panelHeader",children:[jsx("div",{className:"bf-title",id:"bf-panel-title",children:o.panelTitle}),jsxs("div",{className:"bf-row",style:{justifyContent:"flex-end"},children:[jsx("button",{type:"button",className:"bf-btn",onClick:()=>c(),disabled:k,"aria-label":o.rePickButton,children:o.rePickButton}),jsx("button",{type:"button",className:"bf-btn",onClick:()=>r(),disabled:k,"aria-label":o.closeButton,children:o.closeButton})]})]}),jsxs("div",{className:"bf-panelBody",children:[jsx("textarea",{className:"bf-textarea",placeholder:o.textareaPlaceholder,value:g,onChange:p=>D(p.target.value),onKeyDown:ot,disabled:k,"aria-label":o.panelTitle}),jsxs("div",{className:"bf-row",role:"group","aria-label":o.screenshotElement,children:[jsxs("label",{children:[jsx("input",{type:"checkbox",checked:E,onChange:p=>K(p.target.checked),disabled:k}),o.screenshotElement]}),jsxs("label",{children:[jsx("input",{type:"checkbox",checked:x,onChange:p=>ee(p.target.checked),disabled:k}),o.screenshotFullPage]})]}),t.phase==="capturing"&&jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsx("span",{className:"bf-spinner","aria-hidden":"true"}),o.capturingText]}),t.phase==="submitting"&&jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsx("span",{className:"bf-spinner","aria-hidden":"true"}),o.submittingText]}),t.phase==="success"&&jsx("div",{className:"bf-status",role:"status","aria-live":"polite",children:o.successText}),t.phase==="error"&&ne&&jsx("div",{className:"bf-error",role:"alert",children:ne}),jsxs("div",{className:"bf-actions",children:[jsx("button",{type:"button",className:"bf-btn",onClick:()=>r(),disabled:k,"aria-label":o.cancelButton,children:o.cancelButton}),jsx("button",{type:"button",className:"bf-btn bf-btnPrimary",onClick:V,disabled:k||g.trim().length===0,"aria-label":o.sendButton,children:o.sendButton})]})]}),n&&jsx("div",{className:"bf-watermark",children:jsx("a",{href:"https://blocfeed.com",target:"_blank",rel:"noopener noreferrer",children:"Powered by BlocFeed"})})]})]}),t.phase==="success"&&jsx("div",{className:"bf-toast",role:"status","aria-live":"polite",children:o.toastText})]})}function io(e){let t={...e.config??{},blocfeed_id:e.blocfeed_id},[l$1,i]=useState(null),r=!!t.diagnostics;useEffect(()=>{if(r)return k(t.diagnostics),()=>l()},[r]);let c=useRef(e.config?.metadata?.enrich);c.current=e.config?.metadata?.enrich;let a=useMemo(()=>{if(e.config)return {...e.config,metadata:{...e.config.metadata,enrich:async s=>{let o=c.current,n=o?await o(s):{},u=m$1();return {...n,...u.consoleLogs.length>0?{_consoleLogs:u.consoleLogs}:{},...u.networkErrors.length>0?{_networkErrors:u.networkErrors}:{}}}}}},[]);return useEffect(()=>{ge();let s=document.createElement("div");s.setAttribute("data-blocfeed-ui-root","true"),s.setAttribute("data-blocfeed-ui","true");let o=t.ui?.zIndex;typeof o=="number"&&s.style.setProperty("--bf-z",String(o));let n=t.ui?.theme;return n&&(n.accentColor&&s.style.setProperty("--bf-accent",n.accentColor),n.panelBackground&&s.style.setProperty("--bf-panel-bg",n.panelBackground),n.panelForeground&&s.style.setProperty("--bf-panel-fg",n.panelForeground),n.fontFamily&&s.style.setProperty("--bf-font",n.fontFamily)),document.body.appendChild(s),i(s),()=>{s.remove(),i(null);}},[t.ui?.zIndex,t.ui?.theme?.accentColor,t.ui?.theme?.panelBackground,t.ui?.theme?.panelForeground,t.ui?.theme?.fontFamily]),l$1?createPortal(jsx(J,{blocfeed_id:t.blocfeed_id,...a?{config:a}:{},children:jsx(ro,{config:t})}),l$1):null}
503
+ export{J as BlocFeedProvider,io as BlocFeedWidget,Z as useBlocFeed};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blocfeed",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Drop-in feedback + screenshot widget for React.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,2 +0,0 @@
1
- function h(){return typeof window<"u"&&typeof document<"u"}function X(t){let e=globalThis.CSS;return typeof e?.escape=="function"?e.escape(t):t.replace(/[^a-zA-Z0-9_-]/g,n=>{let r=n.codePointAt(0);return r===void 0?"":`\\${r.toString(16)} `})}function O(t){return {x:t.x,y:t.y,width:t.width,height:t.height}}function ye(t){return {x:t.x+window.scrollX,y:t.y+window.scrollY,width:t.width,height:t.height}}function Ee(t){return t.replace(/\s+/g," ").trim()}function Se(t,e=140){let n=t.textContent;if(!n)return;let r=Ee(n);if(r)return r.length<=e?r:`${r.slice(0,e-1)}\u2026`}function ke(t){let e=1;for(let n=t.previousElementSibling;n;n=n.previousElementSibling)n.tagName===t.tagName&&(e+=1);return e}var V=["data-testid","data-test-id","data-test","data-qa","data-cy"],G="data-blocfeed-component";function ve(t){let e=t.closest(`[${G}]`);if(!e)return;let r=e.getAttribute(G)?.trim();return r||void 0}function Pe(t){for(let e of V){let n=t.closest(`[${e}]`);if(!n)continue;let o=n.getAttribute(e)?.trim();if(o)return o}}function xe(t){try{let e=t,n=Object.getOwnPropertyNames(e);for(let r of n)if(r.startsWith("__reactFiber$")||r.startsWith("__reactInternalInstance$")){let o=e[r];if(o&&typeof o=="object")return o}}catch{}return null}function B(t){if(t&&typeof t!="string"){if(typeof t=="function"){let e=t;return typeof e.displayName=="string"&&e.displayName?e.displayName:typeof e.name=="string"&&e.name?e.name:void 0}if(typeof t=="object"){let e=t,n=e.displayName;if(typeof n=="string"&&n)return n;let r=e.render;if(typeof r=="function"){let i=r;if(typeof i.displayName=="string"&&i.displayName)return i.displayName;if(typeof i.name=="string"&&i.name)return i.name}let o=e.type;return B(o)}}}function Fe(t){let e=xe(t);if(!e)return;let n=e._debugOwner!==void 0;if(n){let i=e._debugOwner;for(let s=0;i&&s<50;s+=1){let l=B(i.type)??B(i.elementType);if(l)return l;i=i._debugOwner;}}let r=e,o=n?80:10;for(let i=0;r&&i<o;i+=1){let s=B(r.type)??B(r.elementType);if(s)return s;r=r.return;}}function Ae(t){let e=t.tagName.toLowerCase(),n=t.getAttribute("id");if(n)return `#${X(n)}`;for(let r of V){let o=t.getAttribute(r);if(o)return `${e}[${r}="${X(o)}"]`}return `${e}:nth-of-type(${ke(t)})`}function Te(t,e=10){let n=[],r=t;for(;r&&n.length<e;){let o=Ae(r);if(n.unshift(o),o.startsWith("#"))break;r=r.parentElement;}return n.join(" > ")}function Z(t,e){if(!e||e.length===0)return false;for(let n of e)if(t.closest(n))return true;return false}function H(t,e){if(!t||Z(t,e.ignoreSelectors))return null;let n=t;for(;n;){if(Z(n,e.ignoreSelectors))return null;if(e.isSelectable?.(n)??Re(n))return n;n=n.parentElement;}return null}function Re(t){let e=t.tagName;return !(e==="HTML"||e==="BODY")}function ee(t){let e=t.getBoundingClientRect(),n={selector:Te(t),tagName:t.tagName.toLowerCase(),rect:O(e),pageRect:ye(e)},r=t.getAttribute("id");r&&(n.id=r);let o=t.className;typeof o=="string"&&o.trim()&&(n.className=o);let i=Se(t);i&&(n.textSnippet=i);let s=ve(t)??Fe(t);s&&(n.componentName=s);let l=Pe(t);return l&&(n.testId=l),n}var q=null;async function te(){return q||(q=import('html-to-image')),q}async function Ce(t){return await new Promise((e,n)=>{let r=new Image;r.onload=()=>e({width:r.naturalWidth,height:r.naturalHeight}),r.onerror=()=>n(new Error("Failed to load generated screenshot")),r.src=t;})}async function ne(t,e){let{width:n,height:r}=await Ce(t);return {dataUrl:t,mime:e,width:n,height:r}}function R(t){if(t?.aborted)throw new Error("Aborted")}function re(){return {async captureElement(t,e){if(!h())throw new Error("captureElement can only run in the browser");R(e.signal);let n=await te();R(e.signal);let r=e.mime==="image/jpeg"?await n.toJpeg(t,{quality:e.quality??.92,pixelRatio:e.pixelRatio}):await n.toPng(t,{pixelRatio:e.pixelRatio});return R(e.signal),await ne(r,e.mime)},async captureFullPage(t){if(!h())throw new Error("captureFullPage can only run in the browser");R(t.signal);let e=document.documentElement,n=Math.max(e.scrollWidth,e.clientWidth),r=Math.max(e.scrollHeight,e.clientHeight),o=Math.min(1,t.maxDimension/Math.max(n,r)),i=Math.max(1,Math.round(n*o)),s=Math.max(1,Math.round(r*o)),l=await te();R(t.signal);let f=t.mime==="image/jpeg"?await l.toJpeg(e,{width:i,height:s,quality:t.quality??.92,pixelRatio:t.pixelRatio}):await l.toPng(e,{width:i,height:s,pixelRatio:t.pixelRatio});return R(t.signal),await ne(f,t.mime)}}}function Me(t){if(t instanceof Error)return t.message;if(typeof t=="string")return t;try{return JSON.stringify(t)}catch{return "Unknown error"}}function m(t,e,n){let r={kind:t,message:Me(e)};return n&&(r.detail=n),r}var Be=12e3,_e=2048,Ie=.92;function oe(){return Date.now()}function Le(t){return new Promise((e,n)=>{let r=()=>n(new Error("Aborted"));if(t.aborted){r();return}t.addEventListener("abort",r,{once:true});})}async function ie(t,e,n){let r=new Promise((i,s)=>{let l=setTimeout(()=>s(new Error("Timeout")),e);typeof l.unref=="function"&&l.unref();}),o=[t,r];return n&&o.push(Le(n)),await Promise.race(o)}function De(t){if(!h())return 1;let e=window.devicePixelRatio||1,n=t?.pixelRatio??Math.min(e,2);return Math.max(.1,n)}function Ne(t){return !!(t?.element||t?.fullPage)}function ae(t){let e={mime:t.mime,pixelRatio:t.pixelRatio,maxDimension:t.maxDimension};return t.includeQuality&&(e.quality=t.quality),t.signal&&(e.signal=t.signal),e}async function se(t){let{selectionElement:e,capture:n,signal:r}=t;if(!h()||!Ne(n))return;let o=oe(),i=[],s=n?.timeoutMs??Be,l=n?.maxDimension??_e,f=n?.mime??"image/png",p=n?.quality??Ie,w=n?.adapter??re(),y={},E=De(n);if(n?.element&&e)try{let c=e.getBoundingClientRect(),u=Math.min(1,l/Math.max(c.width,c.height)),v=Math.min(E,E*u),x=await ie(Promise.resolve(w.captureElement(e,{...ae({mime:f,quality:p,pixelRatio:v,maxDimension:l,includeQuality:f==="image/jpeg",...r?{signal:r}:{}})})),s,r);y.element=x;}catch(c){if(r?.aborted)throw c;i.push(m("capture_failed",c,{target:"element"}));}if(n?.fullPage)try{let c=await ie(Promise.resolve(w.captureFullPage(ae({mime:f,quality:p,pixelRatio:E,maxDimension:l,includeQuality:f==="image/jpeg",...r?{signal:r}:{}}))),s,r);y.fullPage=c;}catch(c){if(r?.aborted)throw c;i.push(m("capture_failed",c,{target:"fullPage"}));}let g=oe(),a={startedAt:o,finishedAt:g,durationMs:Math.max(0,g-o)};return i.length>0&&(a.errors=i),{...y,diagnostics:a}}function Ue(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return}}function Oe(){return h()?{url:window.location.href,title:document.title,referrer:document.referrer||void 0,userAgent:navigator.userAgent,language:navigator.language,platform:navigator.platform,viewport:{width:window.innerWidth,height:window.innerHeight},screen:{width:window.screen.width,height:window.screen.height},scroll:{x:window.scrollX,y:window.scrollY},devicePixelRatio:window.devicePixelRatio||1,timezone:Ue()}:{}}function He(t){if(!t)return {};let e={};return t.id&&(e.userId=t.id),t.email&&(e.userEmail=t.email),t.name&&(e.userName=t.name),e}async function le(t){let{config:e,context:n,user:r}=t;if(e?.enabled===false)return {};let o={...Oe(),...He(r)},i=e?.enrich;if(!i)return o;try{let s=await i(n);return {...o,...s}}catch(s){let l=m("unknown",s);return {...o,blocfeedMetadataError:l.message}}}var $="blocfeed-queue",qe=50;function j(){if(!h())return [];try{let t=localStorage.getItem($);if(!t)return [];let e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return []}}function Q(t){if(h())try{t.length===0?localStorage.removeItem($):localStorage.setItem($,JSON.stringify(t));}catch{}}function $e(t){let e={...t};if(e.screenshots){let n={...e.screenshots};n.element&&(n.element={...n.element,dataUrl:""}),n.fullPage&&(n.fullPage={...n.fullPage,dataUrl:""}),e.screenshots=n;}return e}function W(t){let e=j(),n=$e(t);for(n.metadata={...n.metadata,_queued:true},e.push({payload:n,timestamp:Date.now()});e.length>qe;)e.shift();Q(e);}function ce(){let t=j();return t.length===0?[]:(Q([]),t.map(e=>e.payload))}function mt(){Q([]);}function pt(){return j().length}function z(t){let e=null,n=null,r=(...o)=>{n=o,e===null&&(e=requestAnimationFrame(()=>{if(e=null,!n)return;let i=n;n=null,t(...i);}));};return r.cancel=()=>{e!==null&&cancelAnimationFrame(e),e=null,n=null;},r}function I(t){return t instanceof Element?!!t.closest("[data-blocfeed-ui]"):false}function L(t){t.stopPropagation(),t.stopImmediatePropagation?.();}function ue(t,e){if(!h())throw new Error("BlocFeed picker can only run in a browser environment.");let n=t.ignoreSelectors,r=t.isSelectable,o={};n&&n.length>0&&(o.ignoreSelectors=n),r&&(o.isSelectable=r);let i=null,s=null,l=(a,c=false)=>{if(!a){i=null,s=null,e.onHover(null);return}let u=O(a.getBoundingClientRect()),v=`${Math.round(u.x)}:${Math.round(u.y)}:${Math.round(u.width)}:${Math.round(u.height)}`;!c&&a===i&&v===s||(i=a,s=v,e.onHover({element:a,rect:u}));},f=z(a=>{if(I(a.target))return;let c=document.elementFromPoint(a.clientX,a.clientY),u=H(c,o);l(u);}),p=z(()=>{i&&l(i,true);}),w=a=>{I(a.target)||(L(a),a.pointerType==="mouse"&&a.preventDefault());},y=a=>{I(a.target)||(L(a),a.pointerType==="mouse"&&a.preventDefault());},E=a=>{if(I(a.target))return;L(a),a.preventDefault();let c=document.elementFromPoint(a.clientX,a.clientY),u=H(c,o);u&&e.onSelect({element:u,descriptor:ee(u)});},g=a=>{a.key==="Escape"&&(L(a),a.preventDefault(),e.onCancel());};return window.addEventListener("pointermove",f,{capture:true,passive:true}),window.addEventListener("pointerdown",w,{capture:true}),window.addEventListener("pointerup",y,{capture:true}),window.addEventListener("click",E,{capture:true}),window.addEventListener("keydown",g,{capture:true}),window.addEventListener("scroll",p,{capture:true,passive:true}),window.addEventListener("resize",p,{passive:true}),{stop(){window.removeEventListener("pointermove",f,{capture:true}),window.removeEventListener("pointerdown",w,{capture:true}),window.removeEventListener("pointerup",y,{capture:true}),window.removeEventListener("click",E,{capture:true}),window.removeEventListener("keydown",g,{capture:true}),window.removeEventListener("scroll",p,{capture:true}),window.removeEventListener("resize",p),f.cancel(),p.cancel(),e.onHover(null);}}}var je=12e3,Qe=2,We=500,ze=2e3,pe="https://blocfeed.com/api/feedback",de=0;function fe(t,e){return new Promise((n,r)=>{if(e?.aborted){r(new Error("Aborted"));return}let o=setTimeout(n,t),i=()=>{clearTimeout(o),r(new Error("Aborted"));};e?.addEventListener("abort",i,{once:true});})}function Je(t){return t>=500&&t<=599}function Ye(t){let[e,n]=t.split(",",2);if(!e||!n)throw new Error("Invalid data URL");let o=/data:(.*?);base64/.exec(e)?.[1]||"application/octet-stream",i=atob(n),s=new Uint8Array(i.length);for(let l=0;l<i.length;l+=1)s[l]=i.charCodeAt(l);return new Blob([s],{type:o})}function Ke(t){let e={},n={...t};if(n.screenshots){let r={},o={...n.screenshots};o.element&&(e.element=o.element.dataUrl,r.element={mime:o.element.mime,width:o.element.width,height:o.element.height},o.element={...o.element,dataUrl:""}),o.fullPage&&(e.fullPage=o.fullPage.dataUrl,r.fullPage={mime:o.fullPage.mime,width:o.fullPage.width,height:o.fullPage.height},o.fullPage={...o.fullPage,dataUrl:""}),n.screenshots=o,(r.element||r.fullPage)&&(n.screenshot_intent=r);}return {lean:n,extracted:e}}async function me(t,e,n){let r=Ye(e);await fetch(t,{method:"PUT",body:r,headers:{"content-type":r.type},...n?{signal:n}:{}});}async function Xe(t){let{feedbackId:e,extracted:n,screenshots:r,signal:o}=t,i={};n.element&&r?.element&&(i.element={dataUrl:n.element,mime:r.element.mime,width:r.element.width,height:r.element.height}),n.fullPage&&r?.fullPage&&(i.fullPage={dataUrl:n.fullPage,mime:r.fullPage.mime,width:r.fullPage.width,height:r.fullPage.height}),Object.keys(i).length!==0&&await fetch(`${pe}/${e}/screenshots`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(i),...o?{signal:o}:{}});}async function ge(t){let{signal:e,transport:n}=t;if(Date.now()-de<ze)return {ok:false,error:m("configuration",new Error("Please wait before submitting again"))};let o=n?.timeoutMs??je,i=n?.maxAttempts??Qe,s=n?.backoffMs??We,l=!!(t.payload.screenshots?.element?.dataUrl||t.payload.screenshots?.fullPage?.dataUrl),{lean:f,extracted:p}=l?Ke(t.payload):{lean:t.payload,extracted:{}},w={...p,...t.screenshotDataUrls};for(let y=1;y<=i;y+=1){let E=new AbortController,g=setTimeout(()=>E.abort(),o),a=()=>E.abort();e&&e.addEventListener("abort",a,{once:true});try{let c=await fetch(pe,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(f),signal:E.signal});if(c.ok){de=Date.now();let u;try{u=await c.json();}catch{}if((w.element||w.fullPage)&&u){let d=u.upload_urls;if(d){let k=[];w.element&&d.element&&k.push(me(d.element,w.element,e)),w.fullPage&&d.fullPage&&k.push(me(d.fullPage,w.fullPage,e));try{await Promise.all(k);}catch{}}else if(u.feedback_id)try{await Xe({feedbackId:u.feedback_id,extracted:w,screenshots:t.payload.screenshots,...e?{signal:e}:{}});}catch{}}let x={ok:!0,status:c.status};return u&&(x.apiResponse=u),x}if(y<i&&Je(c.status)){let u=.85+Math.random()*.3,v=Math.round(s*2**(y-1)*u);await fe(v,e);continue}return {ok:!1,status:c.status,error:m("api_failed",new Error(`HTTP ${c.status}`))}}catch(c){if(E.signal.aborted||e?.aborted)return {ok:false,error:m("aborted",c)};if(y<i){let u=.85+Math.random()*.3,v=Math.round(s*2**(y-1)*u);await fe(v,e);continue}return {ok:false,error:m("api_failed",c)}}finally{clearTimeout(g),e&&e.removeEventListener("abort",a);}}return {ok:false,error:m("api_failed",new Error("Failed"))}}async function J(t){let{signal:e,transport:n}=t,r={ok:false};try{let o={payload:t.payload,...e?{signal:e}:{},...n?{transport:n}:{}};r.api=await ge(o),r.ok=!!r.api?.ok;}catch(o){r.api={ok:false,error:m("api_failed",o)},r.ok=false;}return {payload:t.payload,result:r}}var Ge=["[data-blocfeed-ui]","[data-blocfeed-ignore]"];function Ze(t){let e=[...Ge,...t?.ignoreSelectors??[]],n=Array.from(new Set(e));return {...t,ignoreSelectors:n}}function he(){return {phase:"idle"}}function Ve(t){if(t.ok)return false;let e=t.api;return e?e.status&&e.status>=400&&e.status<500||e.error?.kind==="aborted"||e.error?.kind==="configuration"?false:!e.ok:true}function Bt(t){let e=t,n=he(),r=new Set,o=new Set,i=null,s=null,l=null,f=null,p=0,w=null,y=()=>{for(let d of r)d(n);},E=d=>{for(let k of o)k(d);},g=d=>{n=d,y();},a=()=>{p+=1,f?.abort(),f=null;},c=()=>{i?.stop(),i=null,E(null),l!==null&&h()&&(document.documentElement.style.cursor=l,l=null);},u=()=>{a(),c(),s=null,g(he());},v=()=>{if(!h())return;c(),s=null;let d=Ze(e.picker);l=document.documentElement.style.cursor,document.documentElement.style.cursor="crosshair",g({phase:"picking"}),i=ue(d,{onHover:E,onSelect:({element:k,descriptor:_})=>{s=k,c(),g({phase:"review",selection:_});},onCancel:()=>{u();}});},x=()=>{let d=ce();if(d.length!==0)for(let k of d)J({payload:k,...e.transport?{transport:e.transport}:{}}).catch(()=>{W(k);});};if(h()){setTimeout(x,1e3);let d=()=>x();window.addEventListener("online",d),w=()=>window.removeEventListener("online",d);}return {getState:()=>n,subscribe(d){return r.add(d),()=>r.delete(d)},subscribeHover(d){return o.add(d),()=>o.delete(d)},start(){n.phase==="capturing"||n.phase==="submitting"||n.phase!=="picking"&&v();},stop(){u();},clearSelection(){n.phase==="capturing"||n.phase==="submitting"||v();},setConfig(d){e=d;},async submit(d,k){if(!h()){let b=m("configuration",new Error("BlocFeed submit can only run in the browser"));return g({phase:"error",lastError:b}),{ok:false}}let _=e.blocfeed_id?.trim?.()??"";if(!_){let F={phase:"error",lastError:m("configuration",new Error("Missing blocfeed_id. Create a project in BlocFeed and pass its blocfeed_id."))};return n.selection&&(F.selection=n.selection),g(F),{ok:false}}if(n.phase==="capturing"||n.phase==="submitting")return {ok:false};let C=p+1;p=C,f?.abort(),f=new AbortController;let A=f.signal,S=n.selection,D=k?.capture?{...e.capture,...k.capture}:e.capture,Y=!!(D?.element||D?.fullPage),K={phase:Y?"capturing":"submitting"};S&&(K.selection=S),g(K);try{let b=Y?await se({selectionElement:s,capture:D,signal:A}):void 0;if(A.aborted||p!==C)return {ok:!1};let F={phase:"submitting"};S&&(F.selection=S),b&&(F.capture=b),g(F);let T={};S&&(T.selection=S),b&&(T.capture=b);let we=await le({config:e.metadata,context:T,...e.user?{user:e.user}:{}}),M={version:1,createdAt:new Date().toISOString(),blocfeed_id:_,message:d,metadata:we};e.user&&(M.user=e.user),S&&(M.selection=S),b&&(M.screenshots=b);let{result:P}=await J({payload:M,signal:A,...e.transport?{transport:e.transport}:{}});if(A.aborted||p!==C)return P;if(P.ok){let U={phase:"success",lastSubmit:P};return S&&(U.selection=S),b&&(U.capture=b),g(U),P}Ve(P)&&W(M);let be=P.api?.error??m("unknown",new Error("Submission failed")),N={phase:"error",lastSubmit:P,lastError:be};return S&&(N.selection=S),b&&(N.capture=b),g(N),P}catch(b){if(A.aborted||p!==C)return {ok:false};let T={phase:"error",lastError:A.aborted?m("aborted",b):m("unknown",b)};return S&&(T.selection=S),g(T),{ok:false}}finally{p===C&&(f=null);}},__unsafeGetSelectedElement(){return s},destroy(){u(),r.clear(),o.clear(),w?.(),w=null;}}}
2
- export{h as a,O as b,re as c,se as d,le as e,W as f,ce as g,mt as h,pt as i,Bt as j};
@@ -1,2 +0,0 @@
1
- 'use strict';function h(){return typeof window<"u"&&typeof document<"u"}function X(t){let e=globalThis.CSS;return typeof e?.escape=="function"?e.escape(t):t.replace(/[^a-zA-Z0-9_-]/g,n=>{let r=n.codePointAt(0);return r===void 0?"":`\\${r.toString(16)} `})}function O(t){return {x:t.x,y:t.y,width:t.width,height:t.height}}function ye(t){return {x:t.x+window.scrollX,y:t.y+window.scrollY,width:t.width,height:t.height}}function Ee(t){return t.replace(/\s+/g," ").trim()}function Se(t,e=140){let n=t.textContent;if(!n)return;let r=Ee(n);if(r)return r.length<=e?r:`${r.slice(0,e-1)}\u2026`}function ke(t){let e=1;for(let n=t.previousElementSibling;n;n=n.previousElementSibling)n.tagName===t.tagName&&(e+=1);return e}var V=["data-testid","data-test-id","data-test","data-qa","data-cy"],G="data-blocfeed-component";function ve(t){let e=t.closest(`[${G}]`);if(!e)return;let r=e.getAttribute(G)?.trim();return r||void 0}function Pe(t){for(let e of V){let n=t.closest(`[${e}]`);if(!n)continue;let o=n.getAttribute(e)?.trim();if(o)return o}}function xe(t){try{let e=t,n=Object.getOwnPropertyNames(e);for(let r of n)if(r.startsWith("__reactFiber$")||r.startsWith("__reactInternalInstance$")){let o=e[r];if(o&&typeof o=="object")return o}}catch{}return null}function B(t){if(t&&typeof t!="string"){if(typeof t=="function"){let e=t;return typeof e.displayName=="string"&&e.displayName?e.displayName:typeof e.name=="string"&&e.name?e.name:void 0}if(typeof t=="object"){let e=t,n=e.displayName;if(typeof n=="string"&&n)return n;let r=e.render;if(typeof r=="function"){let i=r;if(typeof i.displayName=="string"&&i.displayName)return i.displayName;if(typeof i.name=="string"&&i.name)return i.name}let o=e.type;return B(o)}}}function Fe(t){let e=xe(t);if(!e)return;let n=e._debugOwner!==void 0;if(n){let i=e._debugOwner;for(let s=0;i&&s<50;s+=1){let l=B(i.type)??B(i.elementType);if(l)return l;i=i._debugOwner;}}let r=e,o=n?80:10;for(let i=0;r&&i<o;i+=1){let s=B(r.type)??B(r.elementType);if(s)return s;r=r.return;}}function Ae(t){let e=t.tagName.toLowerCase(),n=t.getAttribute("id");if(n)return `#${X(n)}`;for(let r of V){let o=t.getAttribute(r);if(o)return `${e}[${r}="${X(o)}"]`}return `${e}:nth-of-type(${ke(t)})`}function Te(t,e=10){let n=[],r=t;for(;r&&n.length<e;){let o=Ae(r);if(n.unshift(o),o.startsWith("#"))break;r=r.parentElement;}return n.join(" > ")}function Z(t,e){if(!e||e.length===0)return false;for(let n of e)if(t.closest(n))return true;return false}function H(t,e){if(!t||Z(t,e.ignoreSelectors))return null;let n=t;for(;n;){if(Z(n,e.ignoreSelectors))return null;if(e.isSelectable?.(n)??Re(n))return n;n=n.parentElement;}return null}function Re(t){let e=t.tagName;return !(e==="HTML"||e==="BODY")}function ee(t){let e=t.getBoundingClientRect(),n={selector:Te(t),tagName:t.tagName.toLowerCase(),rect:O(e),pageRect:ye(e)},r=t.getAttribute("id");r&&(n.id=r);let o=t.className;typeof o=="string"&&o.trim()&&(n.className=o);let i=Se(t);i&&(n.textSnippet=i);let s=ve(t)??Fe(t);s&&(n.componentName=s);let l=Pe(t);return l&&(n.testId=l),n}var q=null;async function te(){return q||(q=import('html-to-image')),q}async function Ce(t){return await new Promise((e,n)=>{let r=new Image;r.onload=()=>e({width:r.naturalWidth,height:r.naturalHeight}),r.onerror=()=>n(new Error("Failed to load generated screenshot")),r.src=t;})}async function ne(t,e){let{width:n,height:r}=await Ce(t);return {dataUrl:t,mime:e,width:n,height:r}}function R(t){if(t?.aborted)throw new Error("Aborted")}function re(){return {async captureElement(t,e){if(!h())throw new Error("captureElement can only run in the browser");R(e.signal);let n=await te();R(e.signal);let r=e.mime==="image/jpeg"?await n.toJpeg(t,{quality:e.quality??.92,pixelRatio:e.pixelRatio}):await n.toPng(t,{pixelRatio:e.pixelRatio});return R(e.signal),await ne(r,e.mime)},async captureFullPage(t){if(!h())throw new Error("captureFullPage can only run in the browser");R(t.signal);let e=document.documentElement,n=Math.max(e.scrollWidth,e.clientWidth),r=Math.max(e.scrollHeight,e.clientHeight),o=Math.min(1,t.maxDimension/Math.max(n,r)),i=Math.max(1,Math.round(n*o)),s=Math.max(1,Math.round(r*o)),l=await te();R(t.signal);let f=t.mime==="image/jpeg"?await l.toJpeg(e,{width:i,height:s,quality:t.quality??.92,pixelRatio:t.pixelRatio}):await l.toPng(e,{width:i,height:s,pixelRatio:t.pixelRatio});return R(t.signal),await ne(f,t.mime)}}}function Me(t){if(t instanceof Error)return t.message;if(typeof t=="string")return t;try{return JSON.stringify(t)}catch{return "Unknown error"}}function m(t,e,n){let r={kind:t,message:Me(e)};return n&&(r.detail=n),r}var Be=12e3,_e=2048,Ie=.92;function oe(){return Date.now()}function Le(t){return new Promise((e,n)=>{let r=()=>n(new Error("Aborted"));if(t.aborted){r();return}t.addEventListener("abort",r,{once:true});})}async function ie(t,e,n){let r=new Promise((i,s)=>{let l=setTimeout(()=>s(new Error("Timeout")),e);typeof l.unref=="function"&&l.unref();}),o=[t,r];return n&&o.push(Le(n)),await Promise.race(o)}function De(t){if(!h())return 1;let e=window.devicePixelRatio||1,n=t?.pixelRatio??Math.min(e,2);return Math.max(.1,n)}function Ne(t){return !!(t?.element||t?.fullPage)}function ae(t){let e={mime:t.mime,pixelRatio:t.pixelRatio,maxDimension:t.maxDimension};return t.includeQuality&&(e.quality=t.quality),t.signal&&(e.signal=t.signal),e}async function se(t){let{selectionElement:e,capture:n,signal:r}=t;if(!h()||!Ne(n))return;let o=oe(),i=[],s=n?.timeoutMs??Be,l=n?.maxDimension??_e,f=n?.mime??"image/png",p=n?.quality??Ie,w=n?.adapter??re(),y={},E=De(n);if(n?.element&&e)try{let c=e.getBoundingClientRect(),u=Math.min(1,l/Math.max(c.width,c.height)),v=Math.min(E,E*u),x=await ie(Promise.resolve(w.captureElement(e,{...ae({mime:f,quality:p,pixelRatio:v,maxDimension:l,includeQuality:f==="image/jpeg",...r?{signal:r}:{}})})),s,r);y.element=x;}catch(c){if(r?.aborted)throw c;i.push(m("capture_failed",c,{target:"element"}));}if(n?.fullPage)try{let c=await ie(Promise.resolve(w.captureFullPage(ae({mime:f,quality:p,pixelRatio:E,maxDimension:l,includeQuality:f==="image/jpeg",...r?{signal:r}:{}}))),s,r);y.fullPage=c;}catch(c){if(r?.aborted)throw c;i.push(m("capture_failed",c,{target:"fullPage"}));}let g=oe(),a={startedAt:o,finishedAt:g,durationMs:Math.max(0,g-o)};return i.length>0&&(a.errors=i),{...y,diagnostics:a}}function Ue(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return}}function Oe(){return h()?{url:window.location.href,title:document.title,referrer:document.referrer||void 0,userAgent:navigator.userAgent,language:navigator.language,platform:navigator.platform,viewport:{width:window.innerWidth,height:window.innerHeight},screen:{width:window.screen.width,height:window.screen.height},scroll:{x:window.scrollX,y:window.scrollY},devicePixelRatio:window.devicePixelRatio||1,timezone:Ue()}:{}}function He(t){if(!t)return {};let e={};return t.id&&(e.userId=t.id),t.email&&(e.userEmail=t.email),t.name&&(e.userName=t.name),e}async function le(t){let{config:e,context:n,user:r}=t;if(e?.enabled===false)return {};let o={...Oe(),...He(r)},i=e?.enrich;if(!i)return o;try{let s=await i(n);return {...o,...s}}catch(s){let l=m("unknown",s);return {...o,blocfeedMetadataError:l.message}}}var $="blocfeed-queue",qe=50;function j(){if(!h())return [];try{let t=localStorage.getItem($);if(!t)return [];let e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return []}}function Q(t){if(h())try{t.length===0?localStorage.removeItem($):localStorage.setItem($,JSON.stringify(t));}catch{}}function $e(t){let e={...t};if(e.screenshots){let n={...e.screenshots};n.element&&(n.element={...n.element,dataUrl:""}),n.fullPage&&(n.fullPage={...n.fullPage,dataUrl:""}),e.screenshots=n;}return e}function W(t){let e=j(),n=$e(t);for(n.metadata={...n.metadata,_queued:true},e.push({payload:n,timestamp:Date.now()});e.length>qe;)e.shift();Q(e);}function ce(){let t=j();return t.length===0?[]:(Q([]),t.map(e=>e.payload))}function mt(){Q([]);}function pt(){return j().length}function z(t){let e=null,n=null,r=(...o)=>{n=o,e===null&&(e=requestAnimationFrame(()=>{if(e=null,!n)return;let i=n;n=null,t(...i);}));};return r.cancel=()=>{e!==null&&cancelAnimationFrame(e),e=null,n=null;},r}function I(t){return t instanceof Element?!!t.closest("[data-blocfeed-ui]"):false}function L(t){t.stopPropagation(),t.stopImmediatePropagation?.();}function ue(t,e){if(!h())throw new Error("BlocFeed picker can only run in a browser environment.");let n=t.ignoreSelectors,r=t.isSelectable,o={};n&&n.length>0&&(o.ignoreSelectors=n),r&&(o.isSelectable=r);let i=null,s=null,l=(a,c=false)=>{if(!a){i=null,s=null,e.onHover(null);return}let u=O(a.getBoundingClientRect()),v=`${Math.round(u.x)}:${Math.round(u.y)}:${Math.round(u.width)}:${Math.round(u.height)}`;!c&&a===i&&v===s||(i=a,s=v,e.onHover({element:a,rect:u}));},f=z(a=>{if(I(a.target))return;let c=document.elementFromPoint(a.clientX,a.clientY),u=H(c,o);l(u);}),p=z(()=>{i&&l(i,true);}),w=a=>{I(a.target)||(L(a),a.pointerType==="mouse"&&a.preventDefault());},y=a=>{I(a.target)||(L(a),a.pointerType==="mouse"&&a.preventDefault());},E=a=>{if(I(a.target))return;L(a),a.preventDefault();let c=document.elementFromPoint(a.clientX,a.clientY),u=H(c,o);u&&e.onSelect({element:u,descriptor:ee(u)});},g=a=>{a.key==="Escape"&&(L(a),a.preventDefault(),e.onCancel());};return window.addEventListener("pointermove",f,{capture:true,passive:true}),window.addEventListener("pointerdown",w,{capture:true}),window.addEventListener("pointerup",y,{capture:true}),window.addEventListener("click",E,{capture:true}),window.addEventListener("keydown",g,{capture:true}),window.addEventListener("scroll",p,{capture:true,passive:true}),window.addEventListener("resize",p,{passive:true}),{stop(){window.removeEventListener("pointermove",f,{capture:true}),window.removeEventListener("pointerdown",w,{capture:true}),window.removeEventListener("pointerup",y,{capture:true}),window.removeEventListener("click",E,{capture:true}),window.removeEventListener("keydown",g,{capture:true}),window.removeEventListener("scroll",p,{capture:true}),window.removeEventListener("resize",p),f.cancel(),p.cancel(),e.onHover(null);}}}var je=12e3,Qe=2,We=500,ze=2e3,pe="https://blocfeed.com/api/feedback",de=0;function fe(t,e){return new Promise((n,r)=>{if(e?.aborted){r(new Error("Aborted"));return}let o=setTimeout(n,t),i=()=>{clearTimeout(o),r(new Error("Aborted"));};e?.addEventListener("abort",i,{once:true});})}function Je(t){return t>=500&&t<=599}function Ye(t){let[e,n]=t.split(",",2);if(!e||!n)throw new Error("Invalid data URL");let o=/data:(.*?);base64/.exec(e)?.[1]||"application/octet-stream",i=atob(n),s=new Uint8Array(i.length);for(let l=0;l<i.length;l+=1)s[l]=i.charCodeAt(l);return new Blob([s],{type:o})}function Ke(t){let e={},n={...t};if(n.screenshots){let r={},o={...n.screenshots};o.element&&(e.element=o.element.dataUrl,r.element={mime:o.element.mime,width:o.element.width,height:o.element.height},o.element={...o.element,dataUrl:""}),o.fullPage&&(e.fullPage=o.fullPage.dataUrl,r.fullPage={mime:o.fullPage.mime,width:o.fullPage.width,height:o.fullPage.height},o.fullPage={...o.fullPage,dataUrl:""}),n.screenshots=o,(r.element||r.fullPage)&&(n.screenshot_intent=r);}return {lean:n,extracted:e}}async function me(t,e,n){let r=Ye(e);await fetch(t,{method:"PUT",body:r,headers:{"content-type":r.type},...n?{signal:n}:{}});}async function Xe(t){let{feedbackId:e,extracted:n,screenshots:r,signal:o}=t,i={};n.element&&r?.element&&(i.element={dataUrl:n.element,mime:r.element.mime,width:r.element.width,height:r.element.height}),n.fullPage&&r?.fullPage&&(i.fullPage={dataUrl:n.fullPage,mime:r.fullPage.mime,width:r.fullPage.width,height:r.fullPage.height}),Object.keys(i).length!==0&&await fetch(`${pe}/${e}/screenshots`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(i),...o?{signal:o}:{}});}async function ge(t){let{signal:e,transport:n}=t;if(Date.now()-de<ze)return {ok:false,error:m("configuration",new Error("Please wait before submitting again"))};let o=n?.timeoutMs??je,i=n?.maxAttempts??Qe,s=n?.backoffMs??We,l=!!(t.payload.screenshots?.element?.dataUrl||t.payload.screenshots?.fullPage?.dataUrl),{lean:f,extracted:p}=l?Ke(t.payload):{lean:t.payload,extracted:{}},w={...p,...t.screenshotDataUrls};for(let y=1;y<=i;y+=1){let E=new AbortController,g=setTimeout(()=>E.abort(),o),a=()=>E.abort();e&&e.addEventListener("abort",a,{once:true});try{let c=await fetch(pe,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(f),signal:E.signal});if(c.ok){de=Date.now();let u;try{u=await c.json();}catch{}if((w.element||w.fullPage)&&u){let d=u.upload_urls;if(d){let k=[];w.element&&d.element&&k.push(me(d.element,w.element,e)),w.fullPage&&d.fullPage&&k.push(me(d.fullPage,w.fullPage,e));try{await Promise.all(k);}catch{}}else if(u.feedback_id)try{await Xe({feedbackId:u.feedback_id,extracted:w,screenshots:t.payload.screenshots,...e?{signal:e}:{}});}catch{}}let x={ok:!0,status:c.status};return u&&(x.apiResponse=u),x}if(y<i&&Je(c.status)){let u=.85+Math.random()*.3,v=Math.round(s*2**(y-1)*u);await fe(v,e);continue}return {ok:!1,status:c.status,error:m("api_failed",new Error(`HTTP ${c.status}`))}}catch(c){if(E.signal.aborted||e?.aborted)return {ok:false,error:m("aborted",c)};if(y<i){let u=.85+Math.random()*.3,v=Math.round(s*2**(y-1)*u);await fe(v,e);continue}return {ok:false,error:m("api_failed",c)}}finally{clearTimeout(g),e&&e.removeEventListener("abort",a);}}return {ok:false,error:m("api_failed",new Error("Failed"))}}async function J(t){let{signal:e,transport:n}=t,r={ok:false};try{let o={payload:t.payload,...e?{signal:e}:{},...n?{transport:n}:{}};r.api=await ge(o),r.ok=!!r.api?.ok;}catch(o){r.api={ok:false,error:m("api_failed",o)},r.ok=false;}return {payload:t.payload,result:r}}var Ge=["[data-blocfeed-ui]","[data-blocfeed-ignore]"];function Ze(t){let e=[...Ge,...t?.ignoreSelectors??[]],n=Array.from(new Set(e));return {...t,ignoreSelectors:n}}function he(){return {phase:"idle"}}function Ve(t){if(t.ok)return false;let e=t.api;return e?e.status&&e.status>=400&&e.status<500||e.error?.kind==="aborted"||e.error?.kind==="configuration"?false:!e.ok:true}function Bt(t){let e=t,n=he(),r=new Set,o=new Set,i=null,s=null,l=null,f=null,p=0,w=null,y=()=>{for(let d of r)d(n);},E=d=>{for(let k of o)k(d);},g=d=>{n=d,y();},a=()=>{p+=1,f?.abort(),f=null;},c=()=>{i?.stop(),i=null,E(null),l!==null&&h()&&(document.documentElement.style.cursor=l,l=null);},u=()=>{a(),c(),s=null,g(he());},v=()=>{if(!h())return;c(),s=null;let d=Ze(e.picker);l=document.documentElement.style.cursor,document.documentElement.style.cursor="crosshair",g({phase:"picking"}),i=ue(d,{onHover:E,onSelect:({element:k,descriptor:_})=>{s=k,c(),g({phase:"review",selection:_});},onCancel:()=>{u();}});},x=()=>{let d=ce();if(d.length!==0)for(let k of d)J({payload:k,...e.transport?{transport:e.transport}:{}}).catch(()=>{W(k);});};if(h()){setTimeout(x,1e3);let d=()=>x();window.addEventListener("online",d),w=()=>window.removeEventListener("online",d);}return {getState:()=>n,subscribe(d){return r.add(d),()=>r.delete(d)},subscribeHover(d){return o.add(d),()=>o.delete(d)},start(){n.phase==="capturing"||n.phase==="submitting"||n.phase!=="picking"&&v();},stop(){u();},clearSelection(){n.phase==="capturing"||n.phase==="submitting"||v();},setConfig(d){e=d;},async submit(d,k){if(!h()){let b=m("configuration",new Error("BlocFeed submit can only run in the browser"));return g({phase:"error",lastError:b}),{ok:false}}let _=e.blocfeed_id?.trim?.()??"";if(!_){let F={phase:"error",lastError:m("configuration",new Error("Missing blocfeed_id. Create a project in BlocFeed and pass its blocfeed_id."))};return n.selection&&(F.selection=n.selection),g(F),{ok:false}}if(n.phase==="capturing"||n.phase==="submitting")return {ok:false};let C=p+1;p=C,f?.abort(),f=new AbortController;let A=f.signal,S=n.selection,D=k?.capture?{...e.capture,...k.capture}:e.capture,Y=!!(D?.element||D?.fullPage),K={phase:Y?"capturing":"submitting"};S&&(K.selection=S),g(K);try{let b=Y?await se({selectionElement:s,capture:D,signal:A}):void 0;if(A.aborted||p!==C)return {ok:!1};let F={phase:"submitting"};S&&(F.selection=S),b&&(F.capture=b),g(F);let T={};S&&(T.selection=S),b&&(T.capture=b);let we=await le({config:e.metadata,context:T,...e.user?{user:e.user}:{}}),M={version:1,createdAt:new Date().toISOString(),blocfeed_id:_,message:d,metadata:we};e.user&&(M.user=e.user),S&&(M.selection=S),b&&(M.screenshots=b);let{result:P}=await J({payload:M,signal:A,...e.transport?{transport:e.transport}:{}});if(A.aborted||p!==C)return P;if(P.ok){let U={phase:"success",lastSubmit:P};return S&&(U.selection=S),b&&(U.capture=b),g(U),P}Ve(P)&&W(M);let be=P.api?.error??m("unknown",new Error("Submission failed")),N={phase:"error",lastSubmit:P,lastError:be};return S&&(N.selection=S),b&&(N.capture=b),g(N),P}catch(b){if(A.aborted||p!==C)return {ok:false};let T={phase:"error",lastError:A.aborted?m("aborted",b):m("unknown",b)};return S&&(T.selection=S),g(T),{ok:false}}finally{p===C&&(f=null);}},__unsafeGetSelectedElement(){return s},destroy(){u(),r.clear(),o.clear(),w?.(),w=null;}}}
2
- exports.a=h;exports.b=O;exports.c=re;exports.d=se;exports.e=le;exports.f=W;exports.g=ce;exports.h=mt;exports.i=pt;exports.j=Bt;