@feedclip/sdk 0.1.1 → 0.1.3

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.
@@ -12,11 +12,13 @@ The currently sold Paid version enables:
12
12
  - removal of FeedClip branding;
13
13
  - thumbnails, trimming, and upload progress;
14
14
  - Supabase and S3 uploader helpers;
15
+ - access to FeedClip server-side transcription and structured AI analysis for
16
+ the licensed project.
15
17
 
16
18
  Screen recording, diagnostics, privacy redaction, resumable uploads, managed
17
- storage, hosted AI, issue integrations, dashboards, SSO, RBAC, audit logs, data
18
- residency, and SLA products are roadmap items and are not included in the
19
- current purchase.
19
+ storage, issue integrations, dashboards, SSO, RBAC, audit logs, data residency,
20
+ and SLA products are roadmap items and are not included in the current
21
+ purchase.
20
22
 
21
23
  Official Paid capabilities require a valid project-bound FeedClip license
22
24
  token. Tokens are signed by the FeedClip licensing service and may not be
@@ -24,9 +26,10 @@ shared between projects or customers.
24
26
 
25
27
  ## Pricing
26
28
 
27
- The current Indie license is a one-time USD 49 purchase valid for one year. It
28
- does not renew automatically and does not include third-party storage or AI
29
- provider usage.
29
+ Feedclip Pro is a one-time USD 49 lifetime license for one project. It does not
30
+ expire or renew automatically. Third-party storage is not included. Server-side
31
+ AI processing provided by FeedClip is included for the licensed project and is
32
+ subject to the service's published acceptable-use and technical limits.
30
33
 
31
34
  Unauthorized activation of the implemented FeedClip Paid feature gates is
32
35
  prohibited.
package/README.md CHANGED
@@ -28,13 +28,14 @@ The repository currently includes:
28
28
  - legacy file-only upload support;
29
29
  - Supabase and S3 uploader helpers;
30
30
  - localization for 10 languages;
31
- - React implementation with Vue 3 and Angular 19 lifecycle adapters;
31
+ - React implementation with Vue 3 and Angular 19–21 lifecycle adapters;
32
32
  - ESM, CommonJS, CSS, and TypeScript declaration builds;
33
- - 106 automated tests.
33
+ - automated SDK, licensing, and adapter tests.
34
34
 
35
- The hosted ingestion service, production transcription worker, persistent
36
- dashboard, deduplication, and native issue-tracker connectors are the next
37
- platform layer. The SDK contracts required by that layer are already included.
35
+ Feedclip Pro includes the server-side ingestion, transcription, and structured
36
+ analysis path. Durable production workers, a persistent dashboard,
37
+ deduplication, and native issue-tracker connectors remain separate platform
38
+ work.
38
39
 
39
40
  ## Installation
40
41
 
@@ -50,7 +51,7 @@ Vue 3:
50
51
  npm install @feedclip/sdk vue react react-dom
51
52
  ```
52
53
 
53
- Angular 19:
54
+ Angular 19–21:
54
55
 
55
56
  ```bash
56
57
  npm install @feedclip/sdk @angular/core react react-dom
@@ -444,16 +445,18 @@ including commercial use, is free under the terms of [LICENSE](./LICENSE).
444
445
  | Pause and preview | Yes | Yes |
445
446
  | Trimming, thumbnails, upload progress | No | Yes |
446
447
  | Supabase/S3 uploader helpers | No | Yes |
448
+ | FeedClip-hosted transcription and AI analysis | No | Yes |
447
449
  | Screen recording, console and network capture | Roadmap | Roadmap |
448
450
  | Privacy redaction and resumable uploads | Roadmap | Roadmap |
449
451
  | Custom branding and UI themes | Roadmap | Roadmap |
450
- | Managed storage and hosted transcription | Roadmap | Roadmap |
452
+ | Managed storage | Roadmap | Roadmap |
451
453
  | Native issue generation | Roadmap | Roadmap |
452
454
  | Dashboard, search, deduplication, webhooks | Roadmap | Roadmap |
453
455
  | SSO, RBAC, audit logs, data residency, SLA | Roadmap | Roadmap |
454
456
 
455
- The repository includes a self-hosted transcription and structured-analysis
456
- reference API. It is not a hosted service included with the Paid license.
457
+ Feedclip Pro includes access to the FeedClip server-side feedback pipeline for
458
+ transcription and structured analysis. The repository also contains the API
459
+ implementation for local development and private deployments.
457
460
 
458
461
  The Paid version uses a compact ECDSA P-256 signed license token. The private key stays
459
462
  on the FeedClip licensing server; the SDK receives only the token and public
@@ -512,10 +515,12 @@ npm run license:issue -- \
512
515
  --project project_123 \
513
516
  --plan paid \
514
517
  --issuer https://feedclip.dev \
515
- --audience @feedclip/sdk \
516
- --days 365
518
+ --audience @feedclip/sdk
517
519
  ```
518
520
 
521
+ Licenses are lifetime by default. Pass `--days <number>` only when a temporary
522
+ token is intentionally required.
523
+
519
524
  Optional feature overrides are signed into the token for development and
520
525
  future product rollout:
521
526
 
@@ -657,9 +662,8 @@ dist/types/
657
662
 
658
663
  ## Roadmap
659
664
 
660
- - hosted multi-tenant ingestion API;
661
665
  - secure direct uploads and resumable large-file support;
662
- - production transcription pipeline;
666
+ - durable production processing workers;
663
667
  - native GitHub, Linear, and Jira connectors;
664
668
  - semantic deduplication and feedback clustering;
665
669
  - dashboard, search, status tracking, and release linkage;
@@ -0,0 +1,6 @@
1
+ var e=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports);let t=require("react"),n=require("jotai"),r=require("jotai/react");var i=(0,n.atom)(!1);(0,n.atom)(!1);var a=(0,n.atom)(null),o=e((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),s=e((e=>{process.env.NODE_ENV!==`production`&&(function(){function t(e){if(e==null)return null;if(typeof e==`function`)return e.$$typeof===O?null:e.displayName||e.name||null;if(typeof e==`string`)return e;switch(e){case _:return`Fragment`;case y:return`Profiler`;case v:return`StrictMode`;case C:return`Suspense`;case w:return`SuspenseList`;case D:return`Activity`}if(typeof e==`object`)switch(typeof e.tag==`number`&&console.error(`Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.`),e.$$typeof){case g:return`Portal`;case x:return e.displayName||`Context`;case b:return(e._context.displayName||`Context`)+`.Consumer`;case S:var n=e.render;return e=e.displayName,e||=(e=n.displayName||n.name||``,e===``?`ForwardRef`:`ForwardRef(`+e+`)`),e;case T:return n=e.displayName||null,n===null?t(e.type)||`Memo`:n;case E:n=e._payload,e=e._init;try{return t(e(n))}catch{}}return null}function n(e){return``+e}function r(e){try{n(e);var t=!1}catch{t=!0}if(t){t=console;var r=t.error,i=typeof Symbol==`function`&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||`Object`;return r.call(t,`The provided key is an unsupported type %s. This value must be coerced to a string before using it here.`,i),n(e)}}function i(e){if(e===_)return`<>`;if(typeof e==`object`&&e&&e.$$typeof===E)return`<...>`;try{var n=t(e);return n?`<`+n+`>`:`<...>`}catch{return`<...>`}}function a(){var e=k.A;return e===null?null:e.getOwner()}function o(){return Error(`react-stack-top-frame`)}function s(e){if(A.call(e,`key`)){var t=Object.getOwnPropertyDescriptor(e,`key`).get;if(t&&t.isReactWarning)return!1}return e.key!==void 0}function c(e,t){function n(){N||(N=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",t))}n.isReactWarning=!0,Object.defineProperty(e,"key",{get:n,configurable:!0})}function l(){var e=t(this.type);return P[e]||(P[e]=!0,console.error(`Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.`)),e=this.props.ref,e===void 0?null:e}function u(e,t,n,r,i,a){var o=n.ref;return e={$$typeof:h,type:e,key:t,props:n,_owner:r},(o===void 0?null:o)===null?Object.defineProperty(e,"ref",{enumerable:!1,value:null}):Object.defineProperty(e,"ref",{enumerable:!1,get:l}),e._store={},Object.defineProperty(e._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:i}),Object.defineProperty(e,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:a}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function d(e,n,i,o,l,d){var p=n.children;if(p!==void 0)if(o)if(j(p)){for(o=0;o<p.length;o++)f(p[o]);Object.freeze&&Object.freeze(p)}else console.error(`React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.`);else f(p);if(A.call(n,`key`)){p=t(e);var m=Object.keys(n).filter(function(e){return e!==`key`});o=0<m.length?`{key: someKey, `+m.join(`: ..., `)+`: ...}`:`{key: someKey}`,L[p+o]||(m=0<m.length?`{`+m.join(`: ..., `)+`: ...}`:`{}`,console.error(`A props object containing a "key" prop is being spread into JSX:
2
+ let props = %s;
3
+ <%s {...props} />
4
+ React keys must be passed directly to JSX without using spread:
5
+ let props = %s;
6
+ <%s key={someKey} {...props} />`,o,p,m,p),L[p+o]=!0)}if(p=null,i!==void 0&&(r(i),p=``+i),s(n)&&(r(n.key),p=``+n.key),`key`in n)for(var h in i={},n)h!==`key`&&(i[h]=n[h]);else i=n;return p&&c(i,typeof e==`function`?e.displayName||e.name||`Unknown`:e),u(e,p,i,a(),l,d)}function f(e){p(e)?e._store&&(e._store.validated=1):typeof e==`object`&&e&&e.$$typeof===E&&(e._payload.status===`fulfilled`?p(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function p(e){return typeof e==`object`&&!!e&&e.$$typeof===h}var m=require("react"),h=Symbol.for(`react.transitional.element`),g=Symbol.for(`react.portal`),_=Symbol.for(`react.fragment`),v=Symbol.for(`react.strict_mode`),y=Symbol.for(`react.profiler`),b=Symbol.for(`react.consumer`),x=Symbol.for(`react.context`),S=Symbol.for(`react.forward_ref`),C=Symbol.for(`react.suspense`),w=Symbol.for(`react.suspense_list`),T=Symbol.for(`react.memo`),E=Symbol.for(`react.lazy`),D=Symbol.for(`react.activity`),O=Symbol.for(`react.client.reference`),k=m.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,A=Object.prototype.hasOwnProperty,j=Array.isArray,M=console.createTask?console.createTask:function(){return null};m={react_stack_bottom_frame:function(e){return e()}};var N,P={},F=m.react_stack_bottom_frame.bind(m,o)(),I=M(i(o)),L={};e.Fragment=_,e.jsx=function(e,t,n){var r=1e4>k.recentlyCreatedOwnerStacks++;return d(e,t,n,!1,r?Error(`react-stack-top-frame`):F,r?M(i(e)):I)},e.jsxs=function(e,t,n){var r=1e4>k.recentlyCreatedOwnerStacks++;return d(e,t,n,!0,r?Error(`react-stack-top-frame`):F,r?M(i(e)):I)}})()})),c=e(((e,t)=>{process.env.NODE_ENV===`production`?t.exports=o():t.exports=s()}))(),l=e=>{let{videoRef:n,removeBranding:o=!1,thumbnailsEnabled:s=!1}=e,l=(0,r.useAtomValue)(i),u=(0,r.useAtomValue)(a),[d,f]=(0,t.useState)(!1);return(0,c.jsxs)(`div`,{className:`feedclip-video-frame`,children:[(0,c.jsx)(`video`,{ref:n,className:`feedclip-video`,controls:l,poster:l&&s&&u?u:void 0,onPlaying:()=>f(!0),onEmptied:()=>f(!1)}),!l&&!d&&(0,c.jsx)(`div`,{className:`feedclip-video-idle`,"aria-hidden":`true`,children:(0,c.jsx)(`span`,{className:`feedclip-video-idle-icon`,children:(0,c.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,children:[(0,c.jsx)(`path`,{d:`M8 8.5h5A2.5 2.5 0 0 1 15.5 11v2A2.5 2.5 0 0 1 13 15.5H8A2.5 2.5 0 0 1 5.5 13v-2A2.5 2.5 0 0 1 8 8.5Z`}),(0,c.jsx)(`path`,{d:`m15.5 11 2.7-1.5a.55.55 0 0 1 .8.48v4.04a.55.55 0 0 1-.8.48L15.5 13`})]})})}),!o&&(0,c.jsx)(`div`,{className:`feedclip-watermark`,children:`Powered by FeedClip`})]})},u=(0,t.createContext)(void 0),d=e=>{try{let t=document.createElement(`canvas`);return t.width=e.videoWidth||640,t.height=e.videoHeight||480,t.getContext(`2d`)?.drawImage(e,0,0),t.toDataURL(`image/jpeg`,.8)}catch{return null}},f=(e,t,n,r)=>new Promise((i,a)=>{let o=document.createElement(`video`),s=URL.createObjectURL(e);o.src=s,o.muted=!0,o.addEventListener(`loadedmetadata`,()=>{let e=o.duration,c=n>0&&n<=e?n:e,l=t>=0&&t<c?t:0,u=document.createElement(`canvas`);u.width=o.videoWidth||640,u.height=o.videoHeight||480;let d=u.getContext(`2d`);if(!d){URL.revokeObjectURL(s),a(Error(`Canvas 2D context unavailable`));return}let f=u.captureStream(),p=new MediaRecorder(f),m=[];p.ondataavailable=e=>{e.data.size>0&&m.push(e.data)},p.onstop=()=>{URL.revokeObjectURL(s),i(new Blob(m,{type:`video/${r}`}))},o.currentTime=l,o.addEventListener(`seeked`,function e(){o.removeEventListener(`seeked`,e),p.start(),o.play();let t,n=()=>{d.drawImage(o,0,0),o.currentTime>=c?(cancelAnimationFrame(t),p.stop(),o.pause()):t=requestAnimationFrame(n)};t=requestAnimationFrame(n)})}),o.addEventListener(`error`,()=>{URL.revokeObjectURL(s),a(Error(`Failed to load video for trimming`))})}),p=(e,t)=>{switch(e){case`UnixTimestamp`:return`${Date.now()}.${t}`;case`ISO 8601`:return`${new Date().toISOString().replace(/[:.]/g,`-`)}.${t}`;case`Custom`:return`recording.${t}`;default:return`${Date.now()}.${t}`}},m={webm:[`video/webm;codecs=vp9,opus`,`video/webm;codecs=vp8,opus`,`video/webm`],mp4:[`video/mp4;codecs=h264,aac`,`video/mp4`,`video/webm;codecs=h264`,`video/webm`],mov:[`video/mp4`,`video/webm`],avi:[`video/webm;codecs=vp9,opus`,`video/webm;codecs=vp8,opus`,`video/webm`],mkv:[`video/x-matroska;codecs=avc1`,`video/webm`]},h=e=>{let t=m[e]??[`video/webm`];for(let e of t)if(typeof MediaRecorder<`u`&&MediaRecorder.isTypeSupported(e))return e;return`video/webm`},g={"en-US":{startRecordingError:`Unable to access camera and microphone. Please check your permissions.`,browserNotSupported:`Your browser does not support video recording. Please use a modern browser.`,uploading:`Uploading...`,uploadSuccess:`Video uploaded successfully!`,uploadError:`Error uploading video.`,fileSizeError:`File size exceeds the maximum allowed size.`,startRecording:`Start recording`,stopRecording:`Stop recording`,pauseRecording:`Pause recording`,resumeRecording:`Resume recording`,uploadVideo:`Upload video`,resetRecording:`Discard and reset`},"ru-RU":{startRecordingError:`Не удалось получить доступ к камере и микрофону. Пожалуйста, проверьте разрешения.`,browserNotSupported:`Ваш браузер не поддерживает запись видео. Пожалуйста, используйте современный браузер.`,uploading:`Загрузка...`,uploadSuccess:`Видео успешно загружено!`,uploadError:`Ошибка при загрузке видео.`,fileSizeError:`Размер файла превышает максимально допустимый.`,startRecording:`Начать запись`,stopRecording:`Остановить запись`,pauseRecording:`Пауза записи`,resumeRecording:`Возобновить запись`,uploadVideo:`Загрузить видео`,resetRecording:`Отменить и сбросить`},"es-ES":{startRecordingError:`No se puede acceder a la cámara y al micrófono. Por favor, comprueba tus permisos.`,browserNotSupported:`Tu navegador no admite la grabación de vídeo. Por favor, usa un navegador moderno.`,uploading:`Subiendo...`,uploadSuccess:`¡Vídeo subido correctamente!`,uploadError:`Error al subir el vídeo.`,fileSizeError:`El tamaño del archivo supera el máximo permitido.`,startRecording:`Iniciar grabación`,stopRecording:`Detener grabación`,pauseRecording:`Pausar grabación`,resumeRecording:`Reanudar grabación`,uploadVideo:`Subir vídeo`,resetRecording:`Descartar y restablecer`},"fr-FR":{startRecordingError:`Impossible d'accéder à la caméra et au microphone. Veuillez vérifier vos autorisations.`,browserNotSupported:`Votre navigateur ne prend pas en charge l'enregistrement vidéo. Veuillez utiliser un navigateur moderne.`,uploading:`Téléversement...`,uploadSuccess:`Vidéo téléversée avec succès !`,uploadError:`Erreur lors du téléversement de la vidéo.`,fileSizeError:`La taille du fichier dépasse la taille maximale autorisée.`,startRecording:`Démarrer l'enregistrement`,stopRecording:`Arrêter l'enregistrement`,pauseRecording:`Mettre en pause`,resumeRecording:`Reprendre l'enregistrement`,uploadVideo:`Téléverser la vidéo`,resetRecording:`Annuler et réinitialiser`},"de-DE":{startRecordingError:`Kamera und Mikrofon sind nicht zugänglich. Bitte überprüfen Sie Ihre Berechtigungen.`,browserNotSupported:`Ihr Browser unterstützt keine Videoaufnahme. Bitte verwenden Sie einen modernen Browser.`,uploading:`Wird hochgeladen...`,uploadSuccess:`Video erfolgreich hochgeladen!`,uploadError:`Fehler beim Hochladen des Videos.`,fileSizeError:`Die Dateigröße überschreitet die maximal zulässige Größe.`,startRecording:`Aufnahme starten`,stopRecording:`Aufnahme stoppen`,pauseRecording:`Aufnahme pausieren`,resumeRecording:`Aufnahme fortsetzen`,uploadVideo:`Video hochladen`,resetRecording:`Verwerfen und zurücksetzen`},"it-IT":{startRecordingError:`Impossibile accedere alla fotocamera e al microfono. Controlla le tue autorizzazioni.`,browserNotSupported:`Il tuo browser non supporta la registrazione video. Utilizza un browser moderno.`,uploading:`Caricamento...`,uploadSuccess:`Video caricato con successo!`,uploadError:`Errore durante il caricamento del video.`,fileSizeError:`La dimensione del file supera la dimensione massima consentita.`,startRecording:`Avvia registrazione`,stopRecording:`Interrompi registrazione`,pauseRecording:`Metti in pausa la registrazione`,resumeRecording:`Riprendi registrazione`,uploadVideo:`Carica video`,resetRecording:`Annulla e ripristina`},"pt-PT":{startRecordingError:`Não foi possível aceder à câmara e ao microfone. Por favor, verifique as suas permissões.`,browserNotSupported:`O seu navegador não suporta gravação de vídeo. Por favor, utilize um navegador moderno.`,uploading:`A carregar...`,uploadSuccess:`Vídeo carregado com sucesso!`,uploadError:`Erro ao carregar o vídeo.`,fileSizeError:`O tamanho do ficheiro excede o tamanho máximo permitido.`,startRecording:`Iniciar gravação`,stopRecording:`Parar gravação`,pauseRecording:`Pausar gravação`,resumeRecording:`Retomar gravação`,uploadVideo:`Carregar vídeo`,resetRecording:`Descartar e repor`},"zh-CN":{startRecordingError:`无法访问摄像头和麦克风。请检查您的权限。`,browserNotSupported:`您的浏览器不支持视频录制。请使用现代浏览器。`,uploading:`上传中...`,uploadSuccess:`视频上传成功!`,uploadError:`视频上传失败。`,fileSizeError:`文件大小超过允许的最大值。`,startRecording:`开始录制`,stopRecording:`停止录制`,pauseRecording:`暂停录制`,resumeRecording:`恢复录制`,uploadVideo:`上传视频`,resetRecording:`放弃并重置`},"ja-JP":{startRecordingError:`カメラとマイクにアクセスできません。権限を確認してください。`,browserNotSupported:`お使いのブラウザは動画録画に対応していません。最新のブラウザをご利用ください。`,uploading:`アップロード中...`,uploadSuccess:`動画のアップロードに成功しました!`,uploadError:`動画のアップロードに失敗しました。`,fileSizeError:`ファイルサイズが許可される最大サイズを超えています。`,startRecording:`録画を開始`,stopRecording:`録画を停止`,pauseRecording:`録画を一時停止`,resumeRecording:`録画を再開`,uploadVideo:`動画をアップロード`,resetRecording:`破棄してリセット`},"ko-KR":{startRecordingError:`카메라와 마이크에 접근할 수 없습니다. 권한을 확인해 주세요.`,browserNotSupported:`브라우저가 동영상 녹화를 지원하지 않습니다. 최신 브라우저를 사용해 주세요.`,uploading:`업로드 중...`,uploadSuccess:`동영상이 성공적으로 업로드되었습니다!`,uploadError:`동영상 업로드 중 오류가 발생했습니다.`,fileSizeError:`파일 크기가 허용된 최대 크기를 초과합니다.`,startRecording:`녹화 시작`,stopRecording:`녹화 중지`,pauseRecording:`녹화 일시정지`,resumeRecording:`녹화 재개`,uploadVideo:`동영상 업로드`,resetRecording:`취소 및 초기화`}},_={"en-US":{feedbackType:`Feedback type`,feedbackBug:`Bug`,feedbackIdea:`Idea`,feedbackQuestion:`Question`,feedbackOther:`Other`,feedbackDescription:`What happened?`,feedbackPlaceholder:`Describe the problem or idea. The recording adds the context.`,attachScreenshot:`Attach screenshot`,recorderTitle:`Record your feedback`,recorderSubtitle:`Show what happened and tell us what you expected.`,recorderPrivacy:`Camera and microphone are used only while recording`,recordingActive:`Recording in progress`,recordingPaused:`Recording paused`,reviewTitle:`Review and send`,reviewReady:`Your recording is ready`},"ru-RU":{feedbackType:`Тип обращения`,feedbackBug:`Ошибка`,feedbackIdea:`Идея`,feedbackQuestion:`Вопрос`,feedbackOther:`Другое`,feedbackDescription:`Что произошло?`,feedbackPlaceholder:`Опишите проблему или идею. Запись добавит контекст.`,attachScreenshot:`Прикрепить скриншот`,recorderTitle:`Запишите отзыв`,recorderSubtitle:`Покажите, что произошло, и расскажите, чего вы ожидали.`,recorderPrivacy:`Камера и микрофон используются только во время записи`,recordingActive:`Идёт запись`,recordingPaused:`Запись приостановлена`,reviewTitle:`Проверьте и отправьте`,reviewReady:`Запись готова`}},v=e=>({...g[e]??g[`en-US`],..._[e]??_[`en-US`]}),y=e=>{let t=new URL(window.location.href);return t.username=``,t.password=``,t.hash=``,e||(t.search=``),t.toString()},b=()=>{if(document.referrer)try{let e=new URL(document.referrer);return e.username=``,e.password=``,e.search=``,e.hash=``,e.toString()}catch{return}},x=(e={})=>({url:y(e.includeQueryString===!0),title:document.title,userAgent:navigator.userAgent,language:navigator.language,viewport:{width:window.innerWidth,height:window.innerHeight,devicePixelRatio:window.devicePixelRatio},timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,referrer:e.includeReferrer?b():void 0}),S=()=>typeof crypto<`u`&&`randomUUID`in crypto?crypto.randomUUID():`feedback_${Date.now()}_${Math.random().toString(36).slice(2,10)}`,C=e=>{let{recordedBlob:n,uploading:r,uploadProgress:i,setUploading:a,setUploadProgress:o,setAlert:s,onComplete:l,trimStart:d=0,trimEnd:m=0,trimmingEnabled:h=!1,uploadProgressEnabled:g=!1,kind:_,description:y,screenshot:b}=e,C=(0,t.useContext)(u),w=v(C?.locale??`en-US`);return(0,c.jsxs)(`div`,{className:`feedclip-upload`,children:[r&&g&&(0,c.jsx)(`div`,{className:`feedclip-progress`,role:`progressbar`,"aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":i,children:(0,c.jsx)(`div`,{className:`feedclip-progress-value`,style:{width:`${i}%`}})}),(0,c.jsxs)(`button`,{onClick:async()=>{if(!n)return;let e=C?.defaultVideoFileExtension??`webm`,t=n;if(h&&(d>0||m>0))try{t=await f(n,d,m,e)}catch{s({type:`error`,message:w.uploadError});return}if(C?.maxFileSize&&t.size>C.maxFileSize){s({type:`error`,message:w.fileSizeError});return}a(!0),o(0);let r=p(C?.defaultVideoFileNameStyle??`UnixTimestamp`,e),i=new File([t],r,{type:t.type||`video/${e}`});try{let e=await C?.getContext?.(),t={id:S(),createdAt:new Date().toISOString(),kind:_,description:y.trim(),video:i,screenshot:b??void 0,context:x(C?.browserContext),customContext:e},n;if(C?.onSubmit)n=await C.onSubmit(t,e=>o(e));else if(C?.onUpload)await C.onUpload(i,e=>o(e));else throw Error(`FeedClip requires onSubmit or onUpload`);s({type:`success`,message:w.uploadSuccess}),l(n??void 0)}catch{s({type:`error`,message:w.uploadError})}finally{a(!1),o(0)}},disabled:r,"aria-label":r?w.uploading:w.uploadVideo,className:`feedclip-button feedclip-button-primary`,children:[r?w.uploading:(0,c.jsx)(`svg`,{className:`feedclip-button-icon`,"aria-hidden":`true`,xmlns:`http://www.w3.org/2000/svg`,width:`24`,height:`24`,fill:`currentColor`,viewBox:`0 0 24 24`,children:(0,c.jsx)(`path`,{fillRule:`evenodd`,d:`M12 3a1 1 0 0 1 .78.375l4 5a1 1 0 1 1-1.56 1.25L13 6.85V14a1 1 0 1 1-2 0V6.85L8.78 9.626a1 1 0 1 1-1.56-1.25l4-5A1 1 0 0 1 12 3ZM9 14v-1H5a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-4a2 2 0 0 0-2-2h-4v1a3 3 0 1 1-6 0Zm8 2a1 1 0 1 0 0 2h.01a1 1 0 1 0 0-2H17Z`,clipRule:`evenodd`})}),!r&&(0,c.jsx)(`span`,{children:w.uploadVideo})]})]})},w=e=>{let{setIsRecording:r,setRecordedBlob:a,mediaRecorderRef:o,streamRef:s,chunksRef:l,videoRef:d}=e,f=(0,n.useSetAtom)(i),p=v((0,t.useContext)(u)?.locale??`en-US`),m=()=>{if(d.current){let e=d.current.src;e&&e.startsWith(`blob:`)&&URL.revokeObjectURL(e),d.current.src=``,d.current.load()}r(!1),f(!1),a(null),o.current=null,s.current=null,l.current=[]};return(0,c.jsxs)(`button`,{type:`button`,"data-tooltip-target":`tooltip-default`,"aria-label":p.resetRecording,onClick:()=>m(),className:`feedclip-button feedclip-button-ghost`,children:[(0,c.jsx)(`svg`,{className:`feedclip-button-icon`,"aria-hidden":`true`,xmlns:`http://www.w3.org/2000/svg`,width:`24`,height:`24`,fill:`none`,viewBox:`0 0 24 24`,children:(0,c.jsx)(`path`,{stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`2`,d:`M21 9H8a5 5 0 0 0 0 10h9m4-10-4-4m4 4-4 4`})}),(0,c.jsx)(`span`,{children:p.resetRecording})]})},T=e=>{let{streamRef:n,chunksRef:o,videoRef:s,mediaRecorderRef:l,setIsRecording:f,setIsPaused:p,setRecordedBlob:m,setAlert:g,thumbnailsEnabled:_=!1}=e,y=(0,t.useContext)(u),[,b]=(0,r.useAtom)(i),[,x]=(0,r.useAtom)(a),S=v(y?.locale??`en-US`);return(0,c.jsxs)(`button`,{onClick:async()=>{if(!navigator.mediaDevices?.getUserMedia||typeof MediaRecorder>`u`){g({type:`error`,message:S.browserNotSupported});return}p(!1);try{let e=await navigator.mediaDevices.getUserMedia({video:!0,audio:!0});n.current=e,s.current&&(s.current.srcObject=e,s.current.muted=!0,s.current.play()),o.current=[];let t=h(y?.defaultVideoFileExtension??`webm`),r=new MediaRecorder(e,{mimeType:t});r.ondataavailable=e=>o.current.push(e.data),r.onstop=()=>{let n=r.mimeType||t,i=new Blob(o.current,{type:n});_&&s.current&&x(d(s.current)),e.getTracks().forEach(e=>e.stop()),s.current&&(s.current.srcObject=null,s.current.src=URL.createObjectURL(i),s.current.muted=!1),m(i),b(!0)},l.current=r,r.start()}catch{g({type:`error`,message:S.startRecordingError});return}f(!0),setTimeout(()=>{l.current&&(l.current.state===`recording`||l.current.state===`paused`)&&(l.current.stop(),f(!1),p(!1))},y?.maxDurationMilliSeconds??6e4)},"aria-label":S.startRecording,className:`feedclip-button feedclip-button-primary feedclip-button-start`,children:[(0,c.jsx)(`svg`,{className:`feedclip-button-icon`,"aria-hidden":`true`,xmlns:`http://www.w3.org/2000/svg`,width:`24`,height:`24`,fill:`currentColor`,viewBox:`0 0 24 24`,children:(0,c.jsx)(`path`,{fillRule:`evenodd`,d:`M14 7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V7Zm2 9.387 4.684 1.562A1 1 0 0 0 22 17V7a1 1 0 0 0-1.316-.949L16 7.613v8.774Z`,clipRule:`evenodd`})}),(0,c.jsx)(`span`,{children:S.startRecording})]})},E=e=>{let{setIsRecording:n,mediaRecorderRef:r}=e,i=v((0,t.useContext)(u)?.locale??`en-US`);return(0,c.jsxs)(`button`,{className:`feedclip-button feedclip-button-danger`,"aria-label":i.stopRecording,onClick:()=>{r.current&&r.current.state===`recording`&&(r.current.stop(),n(!1))},children:[(0,c.jsx)(`svg`,{className:`feedclip-button-icon`,"aria-hidden":`true`,xmlns:`http://www.w3.org/2000/svg`,width:`24`,height:`24`,fill:`currentColor`,viewBox:`0 0 24 24`,children:(0,c.jsx)(`path`,{d:`M7 5a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2H7Z`})}),(0,c.jsx)(`span`,{children:i.stopRecording})]})},D=e=>{let{mediaRecorderRef:n,isPaused:r,setIsPaused:i}=e,a=v((0,t.useContext)(u)?.locale??`en-US`);return(0,c.jsxs)(`button`,{onClick:()=>{let e=n.current;e&&(r?(e.resume(),i(!1)):(e.pause(),i(!0)))},"aria-label":r?a.resumeRecording:a.pauseRecording,className:`feedclip-button feedclip-button-secondary`,children:[r?(0,c.jsx)(`svg`,{className:`feedclip-button-icon`,"aria-hidden":`true`,xmlns:`http://www.w3.org/2000/svg`,width:`24`,height:`24`,fill:`currentColor`,viewBox:`0 0 24 24`,children:(0,c.jsx)(`path`,{fillRule:`evenodd`,d:`M8.6 5.2A1 1 0 0 0 7 6v12a1 1 0 0 0 1.6.8l8-6a1 1 0 0 0 0-1.6l-8-6Z`,clipRule:`evenodd`})}):(0,c.jsx)(`svg`,{className:`feedclip-button-icon`,"aria-hidden":`true`,xmlns:`http://www.w3.org/2000/svg`,width:`24`,height:`24`,fill:`currentColor`,viewBox:`0 0 24 24`,children:(0,c.jsx)(`path`,{fillRule:`evenodd`,d:`M8 5a2 2 0 0 0-2 2v10a2 2 0 0 0 4 0V7a2 2 0 0 0-2-2Zm8 0a2 2 0 0 0-2 2v10a2 2 0 0 0 4 0V7a2 2 0 0 0-2-2Z`,clipRule:`evenodd`})}),(0,c.jsx)(`span`,{children:r?a.resumeRecording:a.pauseRecording})]})},O=e=>{let{videoRef:n,trimStart:r,trimEnd:i,setTrimStart:a,setTrimEnd:o}=e,[s,l]=(0,t.useState)(0);if((0,t.useEffect)(()=>{let e=n.current;if(!e)return;let t=()=>{let t=e.duration||0;l(t),i===0&&o(t)};if(e.readyState>=1)t();else return e.addEventListener(`loadedmetadata`,t),()=>e.removeEventListener(`loadedmetadata`,t)},[n,i,o]),s===0)return null;let u=e=>`${Math.floor(e/60)}:${String(Math.floor(e%60)).padStart(2,`0`)}`;return(0,c.jsxs)(`div`,{className:`w-full px-2 mt-2 mb-1`,children:[(0,c.jsxs)(`div`,{className:`flex justify-between text-xs text-gray-500 mb-1`,children:[(0,c.jsx)(`span`,{children:`✂️ Trim`}),(0,c.jsxs)(`span`,{children:[u(r),` – `,u(i)]})]}),(0,c.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,c.jsxs)(`label`,{className:`text-xs text-gray-500`,children:[`Start`,(0,c.jsx)(`input`,{type:`range`,min:0,max:s,step:.1,value:r,onChange:e=>{let t=parseFloat(e.target.value);t<i&&a(t)},className:`w-full accent-blue-600`})]}),(0,c.jsxs)(`label`,{className:`text-xs text-gray-500`,children:[`End`,(0,c.jsx)(`input`,{type:`range`,min:0,max:s,step:.1,value:i,onChange:e=>{let t=parseFloat(e.target.value);t>r&&o(t)},className:`w-full accent-blue-600`})]})]})]})},k=({locale:e,kind:t,description:n,screenshot:r,setKind:i,setDescription:a,setScreenshot:o})=>{let s=v(e);return(0,c.jsxs)(`div`,{className:`feedclip-form`,children:[(0,c.jsxs)(`label`,{className:`feedclip-field`,children:[(0,c.jsx)(`span`,{children:s.feedbackType}),(0,c.jsxs)(`select`,{value:t,onChange:e=>i(e.target.value),className:`feedclip-input`,children:[(0,c.jsx)(`option`,{value:`bug`,children:s.feedbackBug}),(0,c.jsx)(`option`,{value:`idea`,children:s.feedbackIdea}),(0,c.jsx)(`option`,{value:`question`,children:s.feedbackQuestion}),(0,c.jsx)(`option`,{value:`other`,children:s.feedbackOther})]})]}),(0,c.jsxs)(`label`,{className:`feedclip-field`,children:[(0,c.jsx)(`span`,{children:s.feedbackDescription}),(0,c.jsx)(`textarea`,{value:n,onChange:e=>a(e.target.value),placeholder:s.feedbackPlaceholder,rows:3,className:`feedclip-input feedclip-textarea`})]}),(0,c.jsxs)(`label`,{className:`feedclip-field`,children:[(0,c.jsx)(`span`,{children:s.attachScreenshot}),(0,c.jsx)(`input`,{type:`file`,accept:`image/*`,onChange:e=>{o(e.target.files?.[0]??null)},className:`feedclip-file-input`}),r&&(0,c.jsx)(`span`,{className:`feedclip-file-name`,children:r.name})]})]})},A=({receipt:e})=>{if(!e.analysis&&!e.issue)return null;let t=e.issue,n=(()=>{if(t?.url)try{let e=new URL(t.url);return[`http:`,`https:`].includes(e.protocol)?e.toString():void 0}catch{return}})();return(0,c.jsxs)(`section`,{className:`feedclip-result`,children:[(0,c.jsxs)(`div`,{className:`feedclip-result-heading`,children:[(0,c.jsx)(`strong`,{children:e.analysis?.title??`Feedback received`}),e.analysis?.priority&&(0,c.jsx)(`span`,{className:`feedclip-result-priority`,children:e.analysis.priority})]}),e.analysis?.summary&&(0,c.jsx)(`p`,{children:e.analysis.summary}),n?(0,c.jsxs)(`a`,{href:n,target:`_blank`,rel:`noreferrer`,className:`feedclip-result-link`,children:[t?.provider,`: `,t?.id]}):t?(0,c.jsxs)(`span`,{className:`feedclip-result-link`,children:[t.provider,`: `,t.id]}):null]})},j=e=>{let{videoRef:n,setAlert:a,entitlements:o}=e,s=(0,r.useAtomValue)(i),l=(0,t.useContext)(u),d=v(l?.locale??`en-US`),f=(()=>{if(l?.privacyNotice?.url)try{let e=new URL(l.privacyNotice.url,window.location.href);return[`http:`,`https:`].includes(e.protocol)?e.toString():void 0}catch{return}})(),[p,m]=(0,t.useState)(!1),[h,g]=(0,t.useState)(!1),[_,y]=(0,t.useState)(null),[b,x]=(0,t.useState)(!1),[S,j]=(0,t.useState)(0),[M,N]=(0,t.useState)(0),[P,F]=(0,t.useState)(0),[I,L]=(0,t.useState)(`bug`),[R,z]=(0,t.useState)(``),[B,V]=(0,t.useState)(null),[H,U]=(0,t.useState)(null),W=(0,t.useRef)(null),G=(0,t.useRef)(null),K=(0,t.useRef)([]);return(0,c.jsxs)(c.Fragment,{children:[!p&&!s&&(0,c.jsxs)(`div`,{className:`feedclip-start-panel`,children:[(0,c.jsxs)(`div`,{children:[(0,c.jsx)(`h2`,{children:d.recorderTitle}),(0,c.jsx)(`p`,{children:d.recorderSubtitle})]}),(0,c.jsx)(T,{streamRef:G,chunksRef:K,videoRef:n,mediaRecorderRef:W,setIsRecording:m,setIsPaused:g,setRecordedBlob:y,setAlert:a,thumbnailsEnabled:o?.thumbnails}),(0,c.jsxs)(`p`,{className:`feedclip-privacy`,children:[(0,c.jsx)(`svg`,{viewBox:`0 0 20 20`,fill:`none`,"aria-hidden":`true`,children:(0,c.jsx)(`path`,{d:`M6.5 8V6.5a3.5 3.5 0 1 1 7 0V8m-8 0h9a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1h-9a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1Z`})}),d.recorderPrivacy,f&&(0,c.jsxs)(c.Fragment,{children:[` `,(0,c.jsx)(`a`,{href:f,target:`_blank`,rel:`noreferrer`,children:l?.privacyNotice?.label})]})]})]}),p&&(0,c.jsxs)(`div`,{className:`feedclip-recording-panel`,children:[(0,c.jsxs)(`div`,{className:`feedclip-recording-status`,role:`status`,"aria-live":`polite`,children:[(0,c.jsx)(`span`,{}),h?d.recordingPaused:d.recordingActive]}),(0,c.jsxs)(`div`,{className:`feedclip-recording-actions`,children:[(0,c.jsx)(D,{mediaRecorderRef:W,isPaused:h,setIsPaused:g}),(0,c.jsx)(E,{setIsRecording:m,mediaRecorderRef:W})]})]}),s&&(0,c.jsxs)(`div`,{className:`feedclip-review`,children:[(0,c.jsxs)(`div`,{className:`feedclip-section-heading`,children:[(0,c.jsx)(`span`,{children:d.reviewTitle}),(0,c.jsx)(`small`,{children:d.reviewReady})]}),(0,c.jsx)(k,{locale:l?.locale??`en-US`,kind:I,description:R,screenshot:B,setKind:L,setDescription:z,setScreenshot:V}),o?.trimming&&(0,c.jsx)(O,{videoRef:n,trimStart:M,trimEnd:P,setTrimStart:N,setTrimEnd:F}),(0,c.jsxs)(`div`,{className:`feedclip-submit-actions`,children:[(0,c.jsx)(C,{recordedBlob:_,uploading:b,uploadProgress:S,setUploading:x,setUploadProgress:j,onComplete:e=>{U(e??null)},setAlert:a,trimStart:M,trimEnd:P,trimmingEnabled:o?.trimming,uploadProgressEnabled:o?.uploadProgress,kind:I,description:R,screenshot:B}),(0,c.jsx)(w,{setIsRecording:m,streamRef:G,chunksRef:K,mediaRecorderRef:W,setRecordedBlob:y,videoRef:n})]})]}),H&&(0,c.jsx)(A,{receipt:H})]})},M=e=>{let{alert:t,setAlert:n}=e;return(0,c.jsxs)(`div`,{id:`alert`,className:`feedclip-alert feedclip-alert-${t?.type??`info`}`,role:`alert`,children:[(0,c.jsx)(`svg`,{"aria-hidden":`true`,xmlns:`http://www.w3.org/2000/svg`,fill:`currentColor`,viewBox:`0 0 20 20`,children:(0,c.jsx)(`path`,{d:`M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z`})}),(0,c.jsx)(`span`,{className:`sr-only`,children:`Info`}),(0,c.jsx)(`div`,{children:t?.message}),(0,c.jsxs)(`button`,{type:`button`,className:`feedclip-alert-close`,"data-dismiss-target":`#alert`,"aria-label":`Close`,onClick:()=>n(null),children:[(0,c.jsx)(`span`,{className:`sr-only`,children:`Close`}),(0,c.jsx)(`svg`,{"aria-hidden":`true`,xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 14 14`,children:(0,c.jsx)(`path`,{stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`2`,d:`m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6`})})]})]})},N=[`videoCapture`,`voiceCapture`,`feedbackDetails`,`screenshotAttachment`,`browserContext`,`customContext`,`selfHostedTransport`,`indexedDbStorage`,`pauseRecording`,`preview`],P=[...N,`removeBranding`,`thumbnails`,`trimming`,`uploadProgress`,`cloudUploaders`,`transcription`,`aiAnalysis`],F=[...P,`screenRecording`,`diagnostics`,`privacyRedaction`,`customBranding`,`resumableUploads`,`managedStorage`,`issueIntegrations`,`dashboard`,`deduplication`,`webhooks`,`sso`,`rbac`,`auditLogs`,`dataResidency`,`sla`],I=e=>{let t=new Set(e);return Object.freeze(Object.fromEntries(F.map(e=>[e,t.has(e)])))},L=Object.freeze({free:I(N),paid:I(P)}),R=L.free,z=(e,t={})=>Object.freeze({...L[e],...t}),B=16384,V=new WeakSet,H=e=>{let t=e.replace(/-/g,`+`).replace(/_/g,`/`),n=t.padEnd(Math.ceil(t.length/4)*4,`=`),r=atob(n);return Uint8Array.from(r,e=>e.charCodeAt(0))},U=e=>{let t=new TextDecoder().decode(H(e));return JSON.parse(t)},W=e=>({valid:!1,plan:`free`,entitlements:R,reason:e}),G=(e,t)=>Array.isArray(e)?e.includes(t):e===t,K=async({token:e,publicKey:t,issuer:n,audience:r,projectId:i,clockToleranceSeconds:a=30})=>{try{if(!globalThis.crypto?.subtle)return W(`Web Crypto is unavailable`);if(e.length>B)return W(`License token is too large`);let o=e.split(`.`);if(o.length!==3)return W(`License token has an invalid format`);let[s,c,l]=o,u=U(s),d=U(c);if(u.alg!==`ES256`||u.typ!==`FCL`)return W(`License token uses an unsupported algorithm`);if(![`free`,`paid`].includes(d.plan))return W(`License token contains an unknown plan`);if(d.iss!==n)return W(`License token issuer does not match`);if(!G(d.aud,r))return W(`License token audience does not match`);if(d.projectId!==i)return W(`License token project does not match`);let f=Math.floor(Date.now()/1e3);if(typeof d.exp==`number`&&d.exp+a<f)return W(`License token has expired`);if(d.iat-a>f)return W(`License token is not active yet`);let p=await crypto.subtle.importKey(`jwk`,t,{name:`ECDSA`,namedCurve:`P-256`},!1,[`verify`]),m=new TextEncoder().encode(`${s}.${c}`),h=new Uint8Array(H(l));if(!await crypto.subtle.verify({name:`ECDSA`,hash:`SHA-256`},p,h,m))return W(`License token signature is invalid`);let g={valid:!0,plan:d.plan,claims:d,entitlements:z(d.plan,d.features??{})};return V.add(g),g}catch{return W(`License token could not be verified`)}},q=(e,t)=>e.entitlements[t]===!0,J=(e,t)=>{if(!e||!V.has(e)||!q(e,t))throw Error(`A verified FeedClip license is required for ${t}`)},Y=()=>({valid:!0,plan:`free`,entitlements:R}),X=e=>{let{config:n}=e,[r,i]=(0,t.useState)(null),[a,o]=(0,t.useState)(Y),s=(0,t.useRef)(null),d=n?.license,f=n?.onLicenseError;(0,t.useEffect)(()=>{let e=!0;return d&&K(d).then(t=>{e&&(o(t),t.valid||f?.(t.reason??`License validation failed`))}),()=>{e=!1}},[d,f]);let p=d?a:Y(),m=p.entitlements,h=p.plan===`paid`?`Paid`:`Free`;return(0,c.jsx)(`section`,{className:`feedclip-shell`,children:(0,c.jsxs)(u.Provider,{value:n,children:[(0,c.jsxs)(`header`,{className:`feedclip-header`,children:[(0,c.jsxs)(`div`,{className:`feedclip-brand`,children:[(0,c.jsx)(`span`,{className:`feedclip-brand-mark`,"aria-hidden":`true`,children:(0,c.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,children:[(0,c.jsx)(`path`,{d:`M8.5 7.5h5A2.5 2.5 0 0 1 16 10v4a2.5 2.5 0 0 1-2.5 2.5h-5A2.5 2.5 0 0 1 6 14v-4a2.5 2.5 0 0 1 2.5-2.5Z`}),(0,c.jsx)(`path`,{d:`m16 10.4 2.6-1.55a.6.6 0 0 1 .9.52v5.26a.6.6 0 0 1-.9.52L16 13.6`})]})}),(0,c.jsxs)(`span`,{children:[(0,c.jsx)(`strong`,{children:`FeedClip`}),(0,c.jsx)(`small`,{children:`Customer feedback`})]})]}),(0,c.jsx)(`span`,{className:`feedclip-plan`,children:h})]}),(0,c.jsxs)(`div`,{className:`feedclip-content`,children:[r&&(0,c.jsx)(M,{alert:r,setAlert:i}),(0,c.jsx)(l,{videoRef:s,removeBranding:m?.removeBranding,thumbnailsEnabled:m?.thumbnails}),(0,c.jsx)(j,{videoRef:s,setAlert:i,entitlements:m})]})]})})};Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return K}}),Object.defineProperty(exports,"c",{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return q}}),Object.defineProperty(exports,"l",{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return J}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return Y}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return L}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return X}}),Object.defineProperty(exports,"u",{enumerable:!0,get:function(){return S}});