@01.works/visual-review 0.1.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.
@@ -0,0 +1 @@
1
+ function e(e){if(typeof e!=`string`||e.length===0||e.length>8192||e.trim()!==e)return null;let n=/^[A-Za-z]:[\\/]/u.test(e),a=n?e.replaceAll(`\\`,`/`):e;if(!n&&a.includes(`\\`)||a.startsWith(`///`)||!a||u.test(a))return null;let o;try{if(a.startsWith(`//`)){let e=new URL(`https:${a}`);if(e.username||e.password||r(i(a,2))===null)return null;o=r(e.pathname)??``}else if(/^https?:\/\//iu.test(a)){let e=new URL(a);if(e.username||e.password||r(i(a,a.indexOf(`://`)+3))===null)return null;o=r(e.pathname)??``}else if(/^file:\/\//iu.test(a)){let e=new URL(a);if(e.hostname&&e.hostname!==`localhost`||r(i(a,a.indexOf(`://`)+3))===null)return null;o=t(r(e.pathname)??``)??``}else if(/^[A-Za-z]:\//u.test(a)){let e=r(a.split(/[?#]/u,1)[0]??``);if(e===null)return null;o=t(e)??``}else{let e=/^[a-z][a-z0-9+.-]*:/iu.exec(a)?.[0];if(e){if(!c.has(e.toLowerCase()))return null;let n=r(a.slice(e.length).split(/[?#]/u,1)[0]??``,!0);if(n===null)return null;o=t(n)??``}else{let e=r(a.split(/[?#]/u,1)[0]??``);if(e===null)return null;let n=e.startsWith(`/`);o=n?e:`/${e}`,n||(o=t(o)??o)}}}catch{return null}s.test(o)&&(o=t(o)??o);let l=r(o);return!o||o===`/`||o.length>4096||l===null?null:l.startsWith(`/`)?l:`/${l}`}function t(e){let t=e.replaceAll(`\\`,`/`);for(let e of a){let n=t.lastIndexOf(e);if(n>=0)return t.slice(n)}return n(t,o)}function n(e,t){let n=e.replaceAll(`\\`,`/`),r=-1;for(let e of t){let t=n.indexOf(e);t>=0&&(r<0||t<r)&&(r=t)}return r<0?null:n.slice(r)}function r(e,t=!1){let n=e;for(let e=0;e<4&&l.test(n);e+=1)try{n=decodeURIComponent(n)}catch{return null}return n=n.normalize(`NFC`),l.test(n)||u.test(n)||n.includes(`\\`)||n.includes(`?`)||n.includes(`#`)||!t&&n.startsWith(`//`)||n.split(`/`).some(e=>e===`.`||e===`..`)?null:n}function i(e,t){let n=e.indexOf(`/`,t);return n<0?`/`:e.slice(n).split(/[?#]/u,1)[0]??`/`}const a=[`/.next/`,`/_next/`],o=[`/dist/`,`/build/`],s=/^\/(?:Users\/[^/]+|home\/[^/]+|github\/workspace|vercel\/path\d+|opt\/build\/repo|workspace|workspaces|private\/(?:var|tmp)|tmp)(?:\/|$)/u,c=new Set([`webpack:`,`webpack-internal:`,`turbopack:`]),l=/%[0-9a-f]{2}/iu,u=/[\u0000-\u001F\u007F-\u009F\u061C\u200B-\u200F\u2028-\u202E\u2060-\u206F\uFEFF]/u;export{e as t};
@@ -0,0 +1 @@
1
+ import{t as e}from"./generated-frame-CkUKpj5U.js";function t(e){let t=new Map,r=e.sourceIndexBaseUrl;return{unavailableProvenance:()=>f(e,`unavailable`),async resolve(i,a){let o=a?.signal;p(o);let s=i.closest(`[data-visual-review-source]`),c=s?await n(s,t,o,r):null;return p(o),{source:c,componentStack:c?[c]:[],provenance:f(e,c?`fallback`:`unavailable`)}}}}async function n(e,t,n,i){let o=e.getAttribute(`data-visual-review-source`),c=e.getAttribute(`data-visual-review-source-index`);if(!o||!/^vr1_[0-9a-f]{32}$/u.test(o)||!c)return null;let l=r(c,e.ownerDocument,i);if(!l||typeof globalThis.fetch!=`function`)return null;let d=t.get(l);if(!d){if(t.size>=v)return null;d=a(l),t.set(l,d)}let f;try{f=await m(d,n)}catch{return null}let p=s(f,o);return p?u(p):null}function r(e,t,n){if(e.length>2048||e.trim()!==e||e.includes(`\\`)||/[\u0000-\u001f\u007f\u202a-\u202e\u2066-\u2069]/u.test(e))return null;try{let r=new URL(e,n??t.baseURI);return r.origin!==t.location.origin||r.username||r.password||r.search||r.hash||!i(r.pathname)?null:r.href}catch{return null}}function i(e){return x.test(e)||S.test(e)}async function a(e){let t=await globalThis.fetch(e,{cache:`force-cache`,credentials:`same-origin`});if(!t.ok)throw Error(`Visual Review source index returned HTTP ${t.status}`);let n=t.headers.get(`content-length`),r=n===null?null:Number(n);if(r!==null&&(!Number.isSafeInteger(r)||r<0||r>_))throw Error(`Visual Review source index exceeds 8 MiB`);let i=await o(t);return JSON.parse(i)}async function o(e){let t=e.body?.getReader();if(!t)return``;let n=new TextDecoder(`utf-8`,{fatal:!0}),r=[],i=0;try{for(;;){let{done:e,value:a}=await t.read();if(e)break;if(i+=a.byteLength,i>_)throw await t.cancel(`Visual Review source index exceeds 8 MiB`),Error(`Visual Review source index exceeds 8 MiB`);r.push(n.decode(a,{stream:!0}))}return r.push(n.decode()),r.join(``)}finally{t.releaseLock()}}function s(t,n){if(!l(t)||t.schemaVersion!==1||!l(t.entries))return;let r=t.entries[n];if(!(!Array.isArray(r)||r.length===0||r.length>y))for(let t of r){if(!l(t)||!c(t.runtime))continue;let n=e(t.assetPath),r=d(t.line1,1,h),i=d(t.column0,0,g);if(!(!n||r===null||i===null))return{assetPath:n,line1:r,column0:i,runtime:t.runtime}}}function c(e){return e===`browser`||e===`server-node`||e===`server-edge`}function l(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function u(e){return{filePath:e.assetPath,lineNumber:e.line1,columnNumber:e.column0+1,componentName:null,origin:`generated`,generated:e}}function d(e,t,n){return typeof e==`number`&&Number.isSafeInteger(e)&&e>=t&&e<=n?e:null}function f(e,t){return{provider:`embedded`,build:e.build,resolvedAt:e.now?.()??Date.now(),sourceMapStatus:t}}function p(e){if(e?.aborted)throw e.reason??Error(`Source context resolution aborted`)}function m(e,t){return t?t.aborted?Promise.reject(t.reason??Error(`Source context resolution aborted`)):new Promise((n,r)=>{let i=()=>r(t.reason??Error(`Source context resolution aborted`));t.addEventListener(`abort`,i,{once:!0}),e.then(e=>{t.removeEventListener(`abort`,i),n(e)},e=>{t.removeEventListener(`abort`,i),r(e)})}):e}const h=1e7,g=1e7,_=8*1024*1024,v=16,y=64,b=`visual-review-sources-[0-9a-f]{16}\\.json`,x=RegExp(`^/(?:[^/]+/)*\\.visual-review/${b}$`,`u`),S=RegExp(`^/(?:[^/]+/)*_next/static/${b}$`,`u`);export{t as createGeneratedSourceContextResolver};
@@ -0,0 +1,13 @@
1
+ import{r as e}from"./install-BN5uBP-5.js";import{t}from"./generated-frame-CkUKpj5U.js";import{i as n,init as r}from"@instantdb/core";const i=n.schema({entities:{$users:n.entity({email:n.string().unique().indexed()}),projects:n.entity({name:n.string(),slug:n.string().unique().indexed(),createdAt:n.number().indexed(),updatedAt:n.number()}),reviewPages:n.entity({projectId:n.string().indexed(),name:n.string(),pathname:n.string(),stagingOrigin:n.string(),createdAt:n.number().indexed(),updatedAt:n.number()}),reviewPageBuilds:n.entity({projectId:n.string().indexed(),pageId:n.string().unique().indexed(),buildId:n.string(),gitCommit:n.string().optional(),generatedAt:n.number().optional(),mode:n.string(),updatedAt:n.number().indexed()}),sourceMapUploadTokens:n.entity({projectId:n.string().indexed(),tokenHash:n.string().unique().indexed(),tokenPrefix:n.string(),scope:n.string(),expiresAt:n.number().indexed(),revokedAt:n.number().optional(),createdAt:n.number().indexed()}),sourceMapReleases:n.entity({projectId:n.string().indexed(),buildId:n.string().indexed(),gitCommit:n.string().optional(),mode:n.string(),framework:n.string(),frameworkVersion:n.string().optional(),status:n.string().indexed(),expiresAt:n.number().indexed(),createdAt:n.number().indexed(),updatedAt:n.number(),completedAt:n.number().optional()}),sourceMapArtifacts:n.entity({releaseId:n.string().indexed(),generatedPath:n.string().indexed(),runtime:n.string().indexed(),objectKey:n.string().unique().indexed(),mapSha256:n.string().indexed(),generatedSha256:n.string(),debugId:n.string().optional(),byteSize:n.number(),createdAt:n.number().indexed()}),reviewers:n.entity({authUserId:n.string().indexed(),projectId:n.string().indexed(),email:n.string().indexed(),displayName:n.string(),role:n.string(),createdAt:n.number()}),reviewerIdentityClaims:n.entity({reviewerId:n.string().unique().indexed(),projectId:n.string().indexed(),authUserId:n.string().indexed(),email:n.string(),displayName:n.string(),role:n.string(),createdAt:n.number()}),invitations:n.entity({projectId:n.string().indexed(),reviewerId:n.string().indexed().optional(),email:n.string().indexed(),status:n.string().indexed(),claimRevision:n.number(),claimedByAuthUserId:n.string().indexed().optional(),expiresAt:n.number().indexed(),createdAt:n.number(),acceptedAt:n.number().optional(),revokedAt:n.number().optional()}),comments:n.entity({pageId:n.string().indexed(),authorId:n.string().indexed(),authorAuthUserId:n.string().indexed(),authorName:n.string(),body:n.string(),bodyContentMarker:n.string().optional(),anchorSelector:n.string().optional(),anchorOffsetX:n.number().optional(),anchorOffsetY:n.number().optional(),anchorViewportX:n.number().optional(),anchorViewportY:n.number().optional(),targetKind:n.string().optional(),targetPageX:n.number().optional(),targetPageY:n.number().optional(),targetWidth:n.number().optional(),targetHeight:n.number().optional(),targetViewportX:n.number().optional(),targetViewportY:n.number().optional(),targetViewportWidth:n.number().optional(),targetViewportHeight:n.number().optional(),targetPageOrigin:n.string().optional(),targetPagePathname:n.string().optional(),targetPageSearch:n.string().optional(),targetPageHash:n.string().optional(),targetPageTitle:n.string().optional(),targetCapturedAt:n.number().optional(),status:n.string().indexed(),workflowRevision:n.number(),createdAt:n.number().indexed(),updatedAt:n.number().indexed(),resolvedAt:n.number().optional(),resolvedById:n.string().optional()}),commentTargetElements:n.entity({commentId:n.string().indexed(),slotKey:n.string().unique().indexed().optional(),ordinal:n.number(),selector:n.string(),tagName:n.string(),textPreview:n.string(),pageX:n.number(),pageY:n.number(),width:n.number(),height:n.number(),viewportX:n.number(),viewportY:n.number(),viewportWidth:n.number(),viewportHeight:n.number(),authorAuthUserId:n.string().indexed()}),commentScopeEntries:n.entity({commentId:n.string().indexed(),slotKey:n.string().unique().indexed().optional(),ordinal:n.number(),key:n.string(),valueType:n.string(),stringValue:n.string().optional(),numberValue:n.number().optional(),booleanValue:n.boolean().optional(),authorAuthUserId:n.string().indexed()}),commentSourceContexts:n.entity({commentId:n.string().unique().indexed(),pageId:n.string().indexed(),authorAuthUserId:n.string().indexed(),contextJson:n.string(),createdAt:n.number().indexed()}),replies:n.entity({pageId:n.string().indexed(),commentId:n.string().indexed(),authorId:n.string().indexed(),authorAuthUserId:n.string().indexed(),authorName:n.string(),body:n.string(),bodyContentMarker:n.string().optional(),createdAt:n.number().indexed(),updatedAt:n.number().indexed()})},links:{projectOwners:{forward:{on:`projects`,has:`many`,label:`owners`},reverse:{on:`$users`,has:`many`,label:`ownedProjects`}},projectPages:{forward:{on:`projects`,has:`many`,label:`pages`},reverse:{on:`reviewPages`,has:`one`,label:`project`}},pageCurrentBuild:{forward:{on:`reviewPageBuilds`,has:`one`,label:`page`,required:!0,onDelete:`cascade`},reverse:{on:`reviewPages`,has:`one`,label:`currentBuild`}},projectSourceMapUploadTokens:{forward:{on:`projects`,has:`many`,label:`uploadTokens`},reverse:{on:`sourceMapUploadTokens`,has:`one`,label:`project`,required:!0,onDelete:`cascade`}},projectSourceMapReleases:{forward:{on:`projects`,has:`many`,label:`sourceMapReleases`},reverse:{on:`sourceMapReleases`,has:`one`,label:`project`,required:!0,onDelete:`cascade`}},sourceMapReleaseArtifacts:{forward:{on:`sourceMapReleases`,has:`many`,label:`artifacts`},reverse:{on:`sourceMapArtifacts`,has:`one`,label:`release`,required:!0,onDelete:`cascade`}},projectReviewers:{forward:{on:`projects`,has:`many`,label:`reviewers`},reverse:{on:`reviewers`,has:`one`,label:`project`}},reviewerUser:{forward:{on:`reviewers`,has:`one`,label:`$user`},reverse:{on:`$users`,has:`many`,label:`reviewerMemberships`}},projectInvitations:{forward:{on:`projects`,has:`many`,label:`invitations`},reverse:{on:`invitations`,has:`one`,label:`project`}},invitationReviewer:{forward:{on:`invitations`,has:`one`,label:`reviewer`},reverse:{on:`reviewers`,has:`many`,label:`acceptedInvitations`}},invitationActiveUser:{forward:{on:`invitations`,has:`one`,label:`activeUser`},reverse:{on:`$users`,has:`one`,label:`activeReviewInvitation`}},pageComments:{forward:{on:`reviewPages`,has:`many`,label:`comments`},reverse:{on:`comments`,has:`one`,label:`page`}},commentReplies:{forward:{on:`comments`,has:`many`,label:`replies`},reverse:{on:`replies`,has:`one`,label:`comment`}},commentTargetElements:{forward:{on:`commentTargetElements`,has:`one`,label:`comment`,required:!0,onDelete:`cascade`},reverse:{on:`comments`,has:`many`,label:`targetElements`}},commentScopeEntries:{forward:{on:`commentScopeEntries`,has:`one`,label:`comment`,required:!0,onDelete:`cascade`},reverse:{on:`comments`,has:`many`,label:`scopeEntries`}},commentSourceContext:{forward:{on:`commentSourceContexts`,has:`one`,label:`comment`,required:!0,onDelete:`cascade`},reverse:{on:`comments`,has:`one`,label:`sourceContext`}},pageSourceContexts:{forward:{on:`commentSourceContexts`,has:`one`,label:`page`,required:!0},reverse:{on:`reviewPages`,has:`many`,label:`sourceContexts`}},sourceContextAuthor:{forward:{on:`commentSourceContexts`,has:`one`,label:`author`,required:!0},reverse:{on:`reviewers`,has:`many`,label:`sourceContexts`}},commentAuthor:{forward:{on:`comments`,has:`one`,label:`author`},reverse:{on:`reviewers`,has:`many`,label:`comments`}},replyAuthor:{forward:{on:`replies`,has:`one`,label:`author`},reverse:{on:`reviewers`,has:`many`,label:`replies`}}}}),a=new Uint8Array([107,167,184,17,157,173,17,209,128,180,0,192,79,212,48,200]);function o(e,t,n){return u(e,n),`${e}:${t}:${n}`}async function s(e,t,n){return l(o(e,t,n))}async function c(e){if(!e.trim())throw Error(`Comment ID is required for source context`);return l(`${e}:source-context`)}async function l(e){let t=globalThis.crypto?.subtle;if(!t)throw Error(`Web Crypto is required to persist review capture context`);let n=new TextEncoder().encode(`01works.visual-review/v1/${e}`),r=new Uint8Array(a.length+n.length);r.set(a),r.set(n,a.length);let i=new Uint8Array(await t.digest(`SHA-1`,r)).slice(0,16);i[6]=i[6]&15|80,i[8]=i[8]&63|128;let o=[...i].map(e=>e.toString(16).padStart(2,`0`)).join(``);return`${o.slice(0,8)}-${o.slice(8,12)}-${o.slice(12,16)}-${o.slice(16,20)}-${o.slice(20)}`}function u(e,t){if(!e.trim())throw Error(`Comment ID is required for capture context`);if(!Number.isSafeInteger(t)||t<0)throw Error(`Capture child ordinal must be a non-negative integer`)}const d=131072,f=32768,p=4096,m=1e3;var h=class extends Error{constructor(e,t){super(e,t),this.name=`InstantCaptureIntegrityError`}};function g(e){let t=ie(e,`comment target`,!0),n={kind:t.kind,anchor:de(t.anchor),region:me(t.region),elements:t.elements.map(e=>({selector:e.selector,tagName:e.tagName,textPreview:e.textPreview,rect:me(e.rect),source:null,componentStack:[]})),pageUrl:t.pageUrl,pageTitle:t.pageTitle,capturedAt:t.capturedAt},r={elements:t.elements.map(e=>({selector:e.selector,source:e.source?he(e.source):null,componentStack:e.componentStack.map(he)})),...t.sourceProvenance?{sourceProvenance:ge(t.sourceProvenance)}:{}};A(n,d,`Public target`);let i=Ce(r,65536,`Source context`);return{publicTarget:n,commentFields:b(n),targetElements:n.elements.map(x),sourceContextJson:i}}function _(e,t,n){let r=w(e,n),i={selector:T(r.anchorSelector,`${n} anchor selector`,p),offsetX:k(r.anchorOffsetX,`${n} anchor offsetX`),offsetY:k(r.anchorOffsetY,`${n} anchor offsetY`),viewportX:k(r.anchorViewportX,`${n} anchor viewportX`),viewportY:k(r.anchorViewportY,`${n} anchor viewportY`)},a=te({kind:r.targetKind,anchor:i,region:{pageX:r.targetPageX,pageY:r.targetPageY,width:r.targetWidth,height:r.targetHeight,viewportX:r.targetViewportX,viewportY:r.targetViewportY,viewportWidth:r.targetViewportWidth,viewportHeight:r.targetViewportHeight},elements:[],pageUrl:pe({origin:E(r.targetPageOrigin,`${n} page origin`,1024),pathname:E(r.targetPagePathname,`${n} page pathname`,4096),search:T(r.targetPageSearch,`${n} page search`,1024),hash:T(r.targetPageHash,`${n} page hash`,1024)}),pageTitle:r.targetPageTitle,capturedAt:r.targetCapturedAt},n),o=ee(t,`${n} elements`),s=a;for(let e of o)try{s=te({...a,elements:[...s.elements,e]},n)}catch{}return s}function v(e){let t=re(e);return t?Object.entries(t).map(([e,t],n)=>typeof t==`string`?{ordinal:n,key:e,valueType:`string`,stringValue:t}:typeof t==`number`?{ordinal:n,key:e,valueType:`number`,numberValue:t}:typeof t==`boolean`?{ordinal:n,key:e,valueType:`boolean`,booleanValue:t}:{ordinal:n,key:e,valueType:`null`}):[]}function y(e){if(!Array.isArray(e)||e.length===0)return;let t=[...e].map(e=>{try{let t=w(e,`Comment scope entry`);return{row:t,ordinal:O(t.ordinal,`Comment scope entry ordinal`,0,19),id:typeof t.id==`string`?t.id:``}}catch{return null}}).filter(e=>e!==null).sort((e,t)=>e.ordinal-t.ordinal||e.id.localeCompare(t.id)),n={},r=new Set;for(let{row:e,ordinal:i}of t)if(!r.has(i)){r.add(i);try{let t=E(e.key,`Comment scope key`,256);if(Object.hasOwn(n,t))continue;switch(e.valueType){case`string`:n[t]=T(e.stringValue,`Comment scope ${t}`,m);break;case`number`:n[t]=D(e.numberValue,`Comment scope ${t}`);break;case`boolean`:if(typeof e.booleanValue!=`boolean`)throw j(`Comment scope ${t} is invalid`);n[t]=e.booleanValue;break;case`null`:n[t]=null;break;default:throw j(`Comment scope ${t} is invalid`)}}catch{}}if(Object.keys(n).length!==0)try{return A(n,f,`Comment scope`),n}catch{return}}function b(e){let t=new URL(e.pageUrl);return{anchorSelector:e.anchor.selector,anchorOffsetX:e.anchor.offsetX,anchorOffsetY:e.anchor.offsetY,anchorViewportX:e.anchor.viewportX,anchorViewportY:e.anchor.viewportY,targetKind:e.kind,targetPageX:e.region.pageX,targetPageY:e.region.pageY,targetWidth:e.region.width,targetHeight:e.region.height,targetViewportX:e.region.viewportX,targetViewportY:e.region.viewportY,targetViewportWidth:e.region.viewportWidth,targetViewportHeight:e.region.viewportHeight,targetPageOrigin:t.origin,targetPagePathname:fe(t.pathname),targetPageSearch:t.search.slice(1),targetPageHash:t.hash.slice(1),targetPageTitle:e.pageTitle,targetCapturedAt:e.capturedAt}}function x(e,t){return{ordinal:t,selector:e.selector,tagName:e.tagName,textPreview:e.textPreview,pageX:e.rect.pageX,pageY:e.rect.pageY,width:e.rect.width,height:e.rect.height,viewportX:e.rect.viewportX,viewportY:e.rect.viewportY,viewportWidth:e.rect.viewportWidth,viewportHeight:e.rect.viewportHeight}}function ee(e,t){if(!Array.isArray(e)||e.length===0)return[];let n=[...e].map(e=>{try{let n=w(e,t);return{row:n,ordinal:O(n.ordinal,`${t} ordinal`,0,7),id:typeof n.id==`string`?n.id:``}}catch{return null}}).filter(e=>e!==null).sort((e,t)=>e.ordinal-t.ordinal||e.id.localeCompare(t.id)),r=[],i=new Set;for(let{row:e,ordinal:a}of n)if(!i.has(a)){i.add(a);try{r.push(ae({selector:e.selector,tagName:e.tagName,textPreview:e.textPreview,rect:{pageX:e.pageX,pageY:e.pageY,width:e.width,height:e.height,viewportX:e.viewportX,viewportY:e.viewportY,viewportWidth:e.viewportWidth,viewportHeight:e.viewportHeight},source:null,componentStack:[]},`${t}[${a}]`,!1))}catch{}}return r}function te(e,t){return ie(e,t,!1)}function S(e,t=`Comment body`){return E(e,t,2e4)}function ne(e,t=`Comment body`){let n=S(e,t);for(let e of n)if(e.trim())return e;throw j(`${t} is empty`)}function re(e){if(e==null)return;let t=w(e,`Comment scope`);if(Object.keys(t).length>20)throw j(`Comment scope has too many fields`);let n={};for(let[e,r]of Object.entries(t)){if(!e.trim()||e.length>256)throw j(`Comment scope has an invalid key`);if(typeof r==`string`){if(r.length>m)throw j(`Comment scope ${e} is too long`);n[e]=r}else if(typeof r==`number`)n[e]=D(r,`Comment scope ${e}`);else if(typeof r==`boolean`||r===null)n[e]=r;else throw j(`Comment scope ${e} is invalid`)}return A(n,f,`Comment scope`),n}function ie(e,t,n){let r=C(e,t,[`kind`,`anchor`,`region`,`elements`,`pageUrl`,`pageTitle`,`capturedAt`,`sourceProvenance`],[`sourceProvenance`]),i=r.kind;if(i!==`element`&&i!==`region`&&i!==`viewport`)throw j(`${t} kind is invalid`);let a=_e(r.elements,`${t} elements`);if(a.length>8)throw j(`${t} contains too many elements`);if(!n&&r.sourceProvenance!=null)throw j(`${t} exposes source provenance`);let o=E(r.pageUrl,`${t} pageUrl`,8192);Se(o,`${t} pageUrl`);let s={kind:i,anchor:oe(r.anchor,`${t} anchor`),region:se(r.region,`${t} region`),elements:a.map((e,r)=>ae(e,`${t} elements[${r}]`,n)),pageUrl:o,pageTitle:T(r.pageTitle,`${t} pageTitle`,m),capturedAt:be(r.capturedAt,`${t} capturedAt`),...n&&r.sourceProvenance!=null?{sourceProvenance:ue(r.sourceProvenance,`${t} provenance`)}:{}};return A(s,n?196608:d,t),s}function ae(e,t,n){let r=C(e,t,[`selector`,`tagName`,`textPreview`,`rect`,`source`,`componentStack`]),i=_e(r.componentStack,`${t} componentStack`);if(i.length>32)throw j(`${t} componentStack is too large`);if(!n&&(r.source!=null||i.length>0))throw j(`${t} exposes source metadata`);return{selector:E(r.selector,`${t} selector`,p),tagName:E(r.tagName,`${t} tagName`,128),textPreview:T(r.textPreview,`${t} textPreview`,m),rect:se(r.rect,`${t} rect`),source:n&&r.source!=null?ce(r.source,`${t} source`):null,componentStack:n?i.map((e,n)=>ce(e,`${t} stack[${n}]`)):[]}}function oe(e,t){let n=C(e,t,[`selector`,`offsetX`,`offsetY`,`viewportX`,`viewportY`]);return{selector:T(n.selector,`${t} selector`,p),offsetX:k(n.offsetX,`${t} offsetX`),offsetY:k(n.offsetY,`${t} offsetY`),viewportX:k(n.viewportX,`${t} viewportX`),viewportY:k(n.viewportY,`${t} viewportY`)}}function se(e,t){let n=C(e,t,[`pageX`,`pageY`,`width`,`height`,`viewportX`,`viewportY`,`viewportWidth`,`viewportHeight`]),r={pageX:D(n.pageX,`${t} pageX`),pageY:D(n.pageY,`${t} pageY`),width:D(n.width,`${t} width`),height:D(n.height,`${t} height`),viewportX:D(n.viewportX,`${t} viewportX`),viewportY:D(n.viewportY,`${t} viewportY`),viewportWidth:D(n.viewportWidth,`${t} viewportWidth`),viewportHeight:D(n.viewportHeight,`${t} viewportHeight`)};if(r.width<0||r.height<0||r.viewportWidth<0||r.viewportHeight<0)throw j(`${t} has a negative dimension`);return r}function ce(e,t){let n=C(e,t,[`filePath`,`lineNumber`,`columnNumber`,`componentName`,`origin`,`generated`],[`generated`]),r=n.origin;if(r!==`app`&&r!==`shared-ui`&&r!==`dependency`&&r!==`generated`&&r!==`unknown`)throw j(`${t} origin is invalid`);return{filePath:E(n.filePath,`${t} filePath`,p),lineNumber:xe(n.lineNumber,`${t} lineNumber`),columnNumber:xe(n.columnNumber,`${t} columnNumber`),componentName:n.componentName==null?null:E(n.componentName,`${t} componentName`,512),origin:r,...n.generated===void 0?{}:{generated:le(n.generated,`${t} generated`)}}}function le(e,n){let r=C(e,n,[`assetPath`,`line1`,`column0`,`runtime`,`debugId`],[`debugId`]),i=t(r.assetPath);if(!i)throw j(`${n} assetPath is invalid`);let a=r.runtime;if(a!==`browser`&&a!==`server-node`&&a!==`server-edge`&&a!==`unknown`)throw j(`${n} runtime is invalid`);return{assetPath:i,line1:O(r.line1,`${n} line1`,1,1e7),column0:O(r.column0,`${n} column0`,0,1e7),runtime:a,...r.debugId===void 0?{}:{debugId:ye(r.debugId,`${n} debugId`)}}}function ue(e,t){let n=C(e,t,[`provider`,`build`,`resolvedAt`,`sourceMapStatus`]),r=n.provider;if(r!==`react-grab`&&r!==`embedded`&&r!==`custom`)throw j(`${t} provider is invalid`);let i=n.sourceMapStatus;if(i!==`resolved`&&i!==`fallback`&&i!==`unavailable`)throw j(`${t} sourceMapStatus is invalid`);let a=C(n.build,`${t} build`,[`buildId`,`gitCommit`,`generatedAt`,`mode`],[`generatedAt`]),o=a.mode;if(o!==`development`&&o!==`preview`&&o!==`production`)throw j(`${t} build mode is invalid`);return{provider:r,build:{buildId:E(a.buildId,`${t} buildId`,512),gitCommit:a.gitCommit==null?null:E(a.gitCommit,`${t} gitCommit`,256),...a.generatedAt==null?{}:{generatedAt:be(a.generatedAt,`${t} generatedAt`)},mode:o},resolvedAt:be(n.resolvedAt,`${t} resolvedAt`),sourceMapStatus:i}}function de(e){return{...e}}function fe(e){return e.replace(/\/+$/,``)||`/`}function pe(e){return`${e.origin}${e.pathname}${e.search?`?${e.search}`:``}${e.hash?`#${e.hash}`:``}`}function me(e){return{...e}}function he(e){return{...e,...e.generated?{generated:{...e.generated}}:{}}}function ge(e){return{...e,build:{...e.build}}}function C(e,t,n,r=[]){let i=w(e,t);if(Object.keys(i).some(e=>!n.includes(e)))throw j(`${t} contains unknown fields`);for(let e of n)if(!r.includes(e)&&!Object.hasOwn(i,e))throw j(`${t} is missing ${e}`);return i}function w(e,t){if(!e||typeof e!=`object`||Array.isArray(e))throw j(`${t} is missing or invalid`);return e}function _e(e,t){if(!Array.isArray(e))throw j(`${t} is missing or invalid`);return e}function T(e,t,n){if(typeof e!=`string`||ve(e,n)>n)throw j(`${t} is invalid or too long`);return e}function ve(e,t){let n=0;for(let r of e)if(n+=1,n>t)return n;return n}function E(e,t,n){let r=T(e,t,n);if(!r.trim())throw j(`${t} is empty`);return r}function D(e,t){if(typeof e!=`number`||!Number.isFinite(e))throw j(`${t} is invalid`);return e}function O(e,t,n,r){if(typeof e!=`number`||!Number.isSafeInteger(e)||e<n||e>r)throw j(`${t} is invalid`);return e}function ye(e,t){let n=E(e,t,256);if(!/^[A-Za-z0-9._:-]+$/u.test(n))throw j(`${t} is invalid`);return n}function k(e,t){let n=D(e,t);if(n<0||n>1)throw j(`${t} is outside 0..1`);return n}function be(e,t){if(typeof e!=`number`||!Number.isSafeInteger(e)||e<0||e>0xe677d21fdbff)throw j(`${t} is invalid`);return e}function xe(e,t){if(e===null)return null;if(typeof e!=`number`||!Number.isSafeInteger(e)||e<0)throw j(`${t} is invalid`);return e}function Se(e,t){let n;try{n=new URL(e)}catch(e){throw j(`${t} is invalid`,e)}if(n.protocol!==`http:`&&n.protocol!==`https:`)throw j(`${t} must use HTTP or HTTPS`)}function A(e,t,n){Ce(e,t,n)}function Ce(e,t,n){let r;try{r=JSON.stringify(e)}catch(e){throw j(`${n} cannot be serialized`,e)}if(r.length>t)throw j(`${n} is too large`);return r}function j(e,t){return new h(e,{cause:t instanceof Error?t:void 0})}function we(e){if(!e.trim())throw Error(`InstantDB app ID is required`);return r({appId:e,schema:i})}var Te=class{db;session;constructor(e,t){this.db=e,this.session=t}async getSnapshot(e){let{data:t}=await this.db.queryOnce(Ee(e,this.session.authUserId));return De(e,t.comments,t.replies)}subscribe(e,t,n){return this.db.subscribeQuery(Ee(e,this.session.authUserId),r=>{if(r.error){n?.(Pe(r.error));return}if(r.data)try{t(De(e,r.data.comments,r.data.replies))}catch{n?.({type:`error`,code:`data-integrity`,recovery:`retry`,clearSnapshot:!0})}})}async mutate(e,t){switch(t.type){case`comment.upsert`:{if(t.comment.pageId!==e)throw Error(`Comment page mismatch`);let n=t.comment;if(n.authorId!==this.session.reviewerId)throw Error(`Comment author mismatch`);let r=S(n.body).trim(),i=ne(r),a=F(n.createdAt,`Comment createdAt`),l=F(n.updatedAt,`Comment updatedAt`);if(l<a)throw new h(`Comment updatedAt precedes createdAt`);if(n.createdAt!==n.updatedAt){await this.db.transact(this.db.tx.comments[n.id].update({body:r,bodyContentMarker:i,updatedAt:l},{upsert:!1}));return}if(n.status!==`open`||n.resolvedAt!==void 0||n.resolvedById!==void 0)throw new h(`New comments must start open`);let u=g(n.target);if(!je(n.anchor,u.publicTarget.anchor))throw new h(`Comment anchor does not match its target`);let d=v(n.scope),f=await Promise.all(u.targetElements.map(async e=>({element:e,id:await s(n.id,`element`,e.ordinal),slotKey:o(n.id,`element`,e.ordinal)}))),p=await Promise.all(d.map(async e=>({entry:e,id:await s(n.id,`scope`,e.ordinal),slotKey:o(n.id,`scope`,e.ordinal)}))),m=await c(n.id);await this.db.transact([this.db.tx.comments[n.id].update({pageId:e,authorId:this.session.reviewerId,authorAuthUserId:this.session.authUserId,authorName:this.session.displayName,body:r,bodyContentMarker:i,...u.commentFields,status:n.status,workflowRevision:0,createdAt:a,updatedAt:l}).link({page:e,author:this.session.reviewerId}),...f.map(({element:e,id:t,slotKey:r})=>this.db.tx.commentTargetElements[t].update({commentId:n.id,slotKey:r,authorAuthUserId:this.session.authUserId,...e}).link({comment:n.id})),...p.map(({entry:e,id:t,slotKey:r})=>this.db.tx.commentScopeEntries[t].update({commentId:n.id,slotKey:r,authorAuthUserId:this.session.authUserId,...e}).link({comment:n.id})),this.db.tx.commentSourceContexts[m].update({commentId:n.id,pageId:e,authorAuthUserId:this.session.authUserId,contextJson:u.sourceContextJson,createdAt:a}).link({comment:n.id,page:e,author:this.session.reviewerId})]);return}case`comment.delete`:await this.db.transact(this.db.tx.comments[t.commentId].delete());return;case`reply.upsert`:{let n=t.reply;if(n.authorId!==this.session.reviewerId)throw Error(`Reply author mismatch`);let r=S(n.body,`Reply body`).trim(),i=ne(r,`Reply body`),a=F(n.createdAt,`Reply createdAt`),o=F(n.updatedAt,`Reply updatedAt`);if(o<a)throw new h(`Reply updatedAt precedes createdAt`);if(n.createdAt!==n.updatedAt){await this.db.transact(this.db.tx.replies[n.id].update({body:r,bodyContentMarker:i,updatedAt:o},{upsert:!1}));return}await this.db.transact(this.db.tx.replies[n.id].update({pageId:e,commentId:n.commentId,authorId:this.session.reviewerId,authorAuthUserId:this.session.authUserId,authorName:this.session.displayName,body:r,bodyContentMarker:i,createdAt:a,updatedAt:o}).link({comment:n.commentId,author:this.session.reviewerId}));return}case`reply.delete`:await this.db.transact(this.db.tx.replies[t.replyId].delete())}}};function Ee(e,t){return{comments:{$:{where:{pageId:e},order:{createdAt:`asc`}},targetElements:{},scopeEntries:{}},replies:{$:{where:{pageId:e},order:{createdAt:`asc`}}},$users:{$:{where:{id:t}},activeReviewInvitation:{project:{}}}}}function De(e,t,n){let r=t.map(t=>Oe(t,e));Ne(r,`comment`);let i=new Set(r.map(({id:e})=>e)),a=n.map(t=>ke(t,e));Ne(a,`reply`);for(let e of a)if(!i.has(e.commentId))throw new h(`Reply ${e.id} references a comment outside the page snapshot`);return{pageId:e,comments:r,replies:a}}function Oe(e,t){let n=M(e,`comment`),r=N(n.id,`comment id`);if(N(n.pageId,`comment ${r} pageId`)!==t)throw new h(`Comment ${r} escaped its page scope`);N(n.authorAuthUserId,`comment ${r} authorAuthUserId`);let i=!(Object.hasOwn(n,`anchor`)&&Object.hasOwn(n,`target`)),a=i?_(n,n.targetElements,`comment ${r} target`):te(n.target,`comment ${r} target`),o=i?{...a.anchor}:Ae(n.anchor,`comment ${r} anchor`);if(!je(o,a.anchor))throw new h(`Comment ${r} has inconsistent anchors`);let s=n.status;if(s!==`open`&&s!==`resolved`)throw new h(`Comment ${r} has an invalid status`);let c=F(n.createdAt,`comment ${r} createdAt`),l=F(n.updatedAt,`comment ${r} updatedAt`);if(l<c)throw new h(`Comment ${r} updatedAt precedes createdAt`);let u=Re(n.resolvedAt,`comment ${r} resolvedAt`),d=ze(n.resolvedById,`comment ${r} resolvedById`);if(s===`open`&&(u!==void 0||d!==void 0))throw new h(`Open comment ${r} contains resolution metadata`);if(s===`resolved`&&(u===void 0||d===void 0||u!==l))throw new h(`Resolved comment ${r} has invalid workflow metadata`);return{id:r,pageId:t,authorId:N(n.authorId,`comment ${r} authorId`),authorName:N(n.authorName,`comment ${r} authorName`),body:S(n.body,`comment ${r} body`),anchor:o,target:a,...i?Me(y(n.scopeEntries)):n.scope==null?{}:{scope:re(n.scope)},status:s,workflowRevision:Le(n.workflowRevision,`comment ${r} workflowRevision`),createdAt:c,updatedAt:l,...u===void 0?{}:{resolvedAt:u},...d===void 0?{}:{resolvedById:d}}}function ke(e,t){let n=M(e,`reply`),r=N(n.id,`reply id`);if(N(n.pageId,`reply ${r} pageId`)!==t)throw new h(`Reply ${r} escaped its page scope`);N(n.authorAuthUserId,`reply ${r} authorAuthUserId`);let i=F(n.createdAt,`reply ${r} createdAt`),a=F(n.updatedAt,`reply ${r} updatedAt`);if(a<i)throw new h(`Reply ${r} updatedAt precedes createdAt`);return{id:r,commentId:N(n.commentId,`reply ${r} commentId`),authorId:N(n.authorId,`reply ${r} authorId`),authorName:N(n.authorName,`reply ${r} authorName`),body:S(n.body,`reply ${r} body`),createdAt:i,updatedAt:a}}function Ae(e,t){let n=M(e,t);if(Object.keys(n).length!==5||!Object.hasOwn(n,`selector`)||!Object.hasOwn(n,`offsetX`)||!Object.hasOwn(n,`offsetY`)||!Object.hasOwn(n,`viewportX`)||!Object.hasOwn(n,`viewportY`))throw new h(`${t} has invalid fields`);return{selector:Ie(n.selector,`${t} selector`),offsetX:P(n.offsetX,`${t} offsetX`),offsetY:P(n.offsetY,`${t} offsetY`),viewportX:P(n.viewportX,`${t} viewportX`),viewportY:P(n.viewportY,`${t} viewportY`)}}function je(e,t){return e.selector===t.selector&&e.offsetX===t.offsetX&&e.offsetY===t.offsetY&&e.viewportX===t.viewportX&&e.viewportY===t.viewportY}function Me(e){return e===void 0?{}:{scope:e}}function Ne(e,t){let n=new Set;for(let r of e){if(n.has(r.id))throw new h(`Duplicate ${t} ${r.id}`);n.add(r.id)}}function Pe(e){let t=Fe(e).toLowerCase();return t.includes(`expired`)||t.includes(`token`)?{type:`access-lost`,code:`session-expired`,recovery:`reauthenticate`,clearSnapshot:!0}:t.includes(`permission`)||t.includes(`forbidden`)||t.includes(`unauthorized`)?{type:`access-lost`,code:`permission-denied`,recovery:`reauthenticate`,clearSnapshot:!0}:{type:`error`,code:`transport`,recovery:`retry`,clearSnapshot:!0}}function Fe(e){return e instanceof Error?e.message:e&&typeof e==`object`&&`message`in e?String(e.message):``}function M(e,t){if(!e||typeof e!=`object`||Array.isArray(e))throw new h(`${t} is missing or invalid`);return e}function Ie(e,t){if(typeof e!=`string`)throw new h(`${t} is invalid`);return e}function N(e,t){let n=Ie(e,t);if(!n.trim())throw new h(`${t} is empty`);return n}function P(e,t){if(typeof e!=`number`||!Number.isFinite(e)||e<0||e>1)throw new h(`${t} is invalid`);return e}function F(e,t){if(!Number.isSafeInteger(e)||e<0||e>0xe677d21fdbff)throw new h(`${t} is invalid`);return e}function Le(e,t){if(!Number.isSafeInteger(e)||e<0)throw new h(`${t} is invalid`);return e}function Re(e,t){return e==null?void 0:F(e,t)}function ze(e,t){return e==null?void 0:N(e,t)}Object.freeze({field:`createdAt`,direction:`desc`,tieBreaker:`id`,tieDirection:`desc`}),Object.freeze({comments:200,replies:1e3,sourceContexts:200}),Object.freeze({field:`createdAt`,direction:`desc`,tieBreaker:`id`,tieDirection:`desc`});const I={$default:`false`},L={$default:`false`},R=`$user.activeReviewInvitation.project.id`;function z(e){return[`auth.id != null`,`size(auth.ref('$user.activeReviewInvitation.id')) == 1`,`size(auth.ref('${R}')) == 1`,`size(auth.ref('$user.activeReviewInvitation.status')) == 1`,`size(auth.ref('$user.activeReviewInvitation.expiresAt')) == 1`,`size(auth.ref('$user.activeReviewInvitation.revokedAt')) == 0`,`auth.ref('$user.activeReviewInvitation.status')[0] == 'accepted'`,`request.time < timestamp(auth.ref('$user.activeReviewInvitation.expiresAt')[0])`,e].join(` && `)}function B(...e){return e.map(e=>`(${e})`).join(` && `)}function V(...e){return e.map(e=>`(${e})`).join(` || `)}function H(e,t){return`!has(${e}.${t}) || ${e}.${t} == null`}const Be=`actions.data == 'update' && actions.linkedData == 'create'`,Ve=`actions.data == 'create' && actions.linkedData == 'update'`,He=`actions.data == 'create' && actions.linkedData == 'create'`,Ue=`9007199254740991`,U=e=>`${e}.matches('[^ \\t\\n\\r\\f\\u000b\\u00a0\\u1680\\u2000-\\u200a\\u2028\\u2029\\u202f\\u205f\\u3000\\ufeff]')`,We=e=>B(`${e} >= 0`,`${e} <= 253402300799999`,`${e} % 1 == 0`),W=e=>B(We(e),`(request.time - timestamp(${e})).getSeconds() <= 86400`,`(request.time - timestamp(${e})).getSeconds() >= -300`);B(Be,V(`auth.id != null && auth.id in data.ref('project.owners.id')`,z(`auth.ref('${R}')[0] in data.ref('project.id')`)));const Ge=`auth.id != null && auth.id in data.ref('page.project.owners.id')`,Ke=z(`auth.ref('${R}')[0] in data.ref('page.project.id')`);B(Ve,V(Ge,Ke),`auth.id != null && auth.id == data.authorAuthUserId && auth.id in data.ref('author.$user.id')`,`data.pageId in data.ref('page.id')`,`data.authorId in data.ref('author.id') && data.authorAuthUserId in data.ref('author.$user.id') && data.authorName in data.ref('author.displayName')`,`data.pageId in data.ref('author.project.pages.id')`),B(Ve,`data.pageId == linkedData.id`,`auth.id != null && auth.id == data.authorAuthUserId`,`data.authorId in auth.ref('$user.reviewerMemberships.id')`,`data.authorId in linkedData.ref('project.reviewers.id')`,V(`auth.id != null && auth.id in linkedData.ref('project.owners.id')`,z(`auth.ref('${R}')[0] in linkedData.ref('project.id')`))),B(Be,V(Ge,Ke)),B(He,`auth.id != null && auth.id == data.authorAuthUserId`,`linkedData.commentId == data.id`,`linkedData.authorAuthUserId == data.authorAuthUserId`);const qe=`auth.id != null && auth.id in data.ref('comment.page.project.owners.id')`,Je=z(`auth.ref('${R}')[0] in data.ref('comment.page.project.id')`);B(He,`auth.id != null && auth.id == data.authorAuthUserId`,`data.commentId == linkedData.id`,`data.authorAuthUserId == linkedData.authorAuthUserId`);const Ye=z(`auth.ref('${R}')[0] in data.ref('page.project.id')`),Xe=B(`data.id != data.commentId`,`size(data.commentId) > 0 && size(data.commentId) <= 128`),Ze=W(`data.createdAt`),Qe=B(V(`auth.id != null && auth.id in data.ref('page.project.owners.id')`,Ye),`auth.id != null && auth.id == data.authorAuthUserId && auth.id in data.ref('author.$user.id')`,Xe,`data.pageId in data.ref('page.id')`,`data.authorAuthUserId in data.ref('author.$user.id')`,`data.pageId in data.ref('author.project.pages.id')`,Ze,`size(data.contextJson) > 0 && size(data.contextJson) <= 65536`);B(`actions.data == 'create' && actions.linkedData in ['create', 'update']`,Qe,`data.commentId == linkedData.id`,`data.pageId == linkedData.pageId`,`data.authorAuthUserId == linkedData.authorAuthUserId`,`data.createdAt == linkedData.createdAt`),B(Ve,Qe),B(`actions.data in ['create', 'update'] && actions.linkedData == 'create'`,`auth.id != null && auth.id == data.authorAuthUserId`,`linkedData.commentId == data.id`,`linkedData.pageId == data.pageId`,`linkedData.authorAuthUserId == data.authorAuthUserId`,`linkedData.createdAt == data.createdAt`),B(`actions.data == 'create'`,`actions.linkedData == 'update'`,V(`auth.id != null && auth.id in data.ref('comment.page.project.owners.id')`,z(`auth.ref('${R}')[0] in data.ref('comment.page.project.id')`)),`auth.id != null && auth.id == data.authorAuthUserId && auth.id in data.ref('author.$user.id')`,`data.commentId in data.ref('comment.id')`,`data.pageId in data.ref('comment.page.id')`,`data.authorId in data.ref('author.id') && data.authorAuthUserId in data.ref('author.$user.id') && data.authorName in data.ref('author.displayName')`,`data.pageId in data.ref('author.project.pages.id')`),B(`actions.data == 'create'`,`actions.linkedData == 'update'`,`data.commentId == linkedData.id`,`data.pageId in linkedData.ref('page.id')`,`auth.id != null && auth.id == data.authorAuthUserId`,`data.authorId in auth.ref('$user.reviewerMemberships.id')`,`data.authorId in linkedData.ref('page.project.reviewers.id')`,V(`auth.id != null && auth.id in linkedData.ref('page.project.owners.id')`,z(`auth.ref('${R}')[0] in linkedData.ref('page.project.id')`)));const $e=B(`data.reviewerId != null`,`data.projectId in data.ref('project.id')`,`data.reviewerId in data.ref('reviewer.id')`,`data.projectId in data.ref('reviewer.project.id')`,`auth.id in data.ref('reviewer.$user.id')`,`auth.email in data.ref('reviewer.email')`);B(`auth.id != null`,`data.revokedAt == null`,`data.status in ['pending', 'accepted']`,`data.status == 'pending' || data.claimedByAuthUserId == auth.id`,`request.time < timestamp(data.expiresAt)`,`request.modifiedFields.all(field, field in ['status', 'claimedByAuthUserId', 'acceptedAt', 'claimRevision', 'activeUser'])`,`'status' in request.modifiedFields`,`'claimedByAuthUserId' in request.modifiedFields`,`'acceptedAt' in request.modifiedFields`,`'claimRevision' in request.modifiedFields`,`'activeUser' in request.modifiedFields`,`newData.status == 'accepted'`,`newData.claimedByAuthUserId == auth.id`,`newData.claimRevision == data.claimRevision + 1`,`math.abs((request.time - timestamp(newData.acceptedAt)).getMinutes()) <= 1`,$e),B(`actions.data == 'update'`,`actions.linkedData == 'update'`,`auth.id != null`,`auth.email != null`,`linkedData.id == auth.id`,`linkedData.email == auth.email`,`data.email == auth.email`,`data.revokedAt == null`,`data.status in ['pending', 'accepted']`,`data.status == 'pending' || data.claimedByAuthUserId == auth.id`,`request.time < timestamp(data.expiresAt)`,`newData.status == 'accepted'`,`newData.claimedByAuthUserId == auth.id`,`newData.claimRevision == data.claimRevision + 1`,`math.abs((request.time - timestamp(newData.acceptedAt)).getMinutes()) <= 1`,$e),B(`actions.data == 'update'`,`actions.linkedData == 'update'`,`auth.id != null`,`auth.email != null`,`data.id == auth.id`,`data.email == auth.email`,`linkedData.email == auth.email`,`linkedData.revokedAt == null`,`linkedData.status == 'accepted'`,`linkedData.claimedByAuthUserId == auth.id`,`request.time < timestamp(linkedData.expiresAt)`,`math.abs((request.time - timestamp(linkedData.acceptedAt)).getMinutes()) <= 1`,`linkedData.projectId in linkedData.ref('project.id')`,`linkedData.reviewerId in linkedData.ref('reviewer.id')`,`linkedData.projectId in linkedData.ref('reviewer.project.id')`,`auth.id in linkedData.ref('reviewer.$user.id')`,`auth.email in linkedData.ref('reviewer.email')`),B(`auth.id != null`,`auth.email != null`,`linkedData.id == auth.id`,`linkedData.email == auth.email`,`data.email == auth.email`,`data.claimedByAuthUserId == auth.id`,`auth.id in data.ref('activeUser.id')`),B(`auth.id != null`,`auth.email != null`,`data.id == auth.id`,`data.email == auth.email`,`linkedData.email == auth.email`,`linkedData.claimedByAuthUserId == auth.id`,`auth.id in linkedData.ref('activeUser.id')`),{...I},{...L},{...L},z(`data.id == auth.ref('${R}')[0]`),{...I},{...L},{...I},{...L},{...I},{...L},{...I},{...L},{...I},{...L},{...I},{...L},z(`auth.ref('${R}')[0] in data.ref('project.id')`),{...I},{...L},{...I},{...I},{...L},{...L},B(`data.status == 'open'`,`data.workflowRevision == 0`,`data.createdAt == data.updatedAt`,W(`data.createdAt`),H(`data`,`resolvedAt`),H(`data`,`resolvedById`)),B(`size(data.body) > 0`,`size(data.body) <= 20000`,`has(data.bodyContentMarker)`,`size(data.bodyContentMarker) == 1`,U(`data.bodyContentMarker`),`data.body.startsWith(data.bodyContentMarker)`,`size(data.authorName) > 0`,`size(data.authorName) <= 512`,U(`data.authorName`)),B(`has(data.anchorSelector)`,`has(data.anchorOffsetX)`,`has(data.anchorOffsetY)`,`has(data.anchorViewportX)`,`has(data.anchorViewportY)`,`has(data.targetKind)`,`has(data.targetPageX)`,`has(data.targetPageY)`,`has(data.targetWidth)`,`has(data.targetHeight)`,`has(data.targetViewportX)`,`has(data.targetViewportY)`,`has(data.targetViewportWidth)`,`has(data.targetViewportHeight)`,`has(data.targetPageOrigin)`,`has(data.targetPagePathname)`,`has(data.targetPageSearch)`,`has(data.targetPageHash)`,`has(data.targetPageTitle)`,`has(data.targetCapturedAt)`),B(`size(data.anchorSelector) <= 4096`,`data.anchorOffsetX >= 0.0 && data.anchorOffsetX <= 1.0`,`data.anchorOffsetY >= 0.0 && data.anchorOffsetY <= 1.0`,`data.anchorViewportX >= 0.0 && data.anchorViewportX <= 1.0`,`data.anchorViewportY >= 0.0 && data.anchorViewportY <= 1.0`),B(`data.targetKind in ['element', 'region', 'viewport']`,`size(data.targetPageOrigin) > 0 && size(data.targetPageOrigin) <= 1024`,`size(data.targetPagePathname) > 0 && size(data.targetPagePathname) <= 4096`,`size(data.targetPageSearch) <= 1024`,`size(data.targetPageHash) <= 1024`,`data.targetPageOrigin in data.ref('page.stagingOrigin')`,`data.targetPagePathname in data.ref('page.pathname') || data.targetPagePathname + '/' in data.ref('page.pathname')`,`size(data.targetPageTitle) <= 1000`,`data.targetPageX >= -100000000 && data.targetPageX <= 100000000`,`data.targetPageY >= -100000000 && data.targetPageY <= 100000000`,`data.targetWidth >= 0 && data.targetWidth <= 100000000`,`data.targetHeight >= 0 && data.targetHeight <= 100000000`,`data.targetViewportX >= -100000000 && data.targetViewportX <= 100000000`,`data.targetViewportY >= -100000000 && data.targetViewportY <= 100000000`,`data.targetViewportWidth >= 0 && data.targetViewportWidth <= 100000000`,`data.targetViewportHeight >= 0 && data.targetViewportHeight <= 100000000`,We(`data.targetCapturedAt`),`data.targetCapturedAt >= data.createdAt - 86400000`,`data.targetCapturedAt <= data.createdAt + 300000`),B(`request.modifiedFields.all(field, field in ['body', 'bodyContentMarker', 'updatedAt'])`,`'body' in request.modifiedFields`,`'bodyContentMarker' in request.modifiedFields`,`'updatedAt' in request.modifiedFields`,`size(newData.body) > 0`,`size(newData.body) <= 20000`,`has(newData.bodyContentMarker)`,`size(newData.bodyContentMarker) == 1`,U(`newData.bodyContentMarker`),`newData.body.startsWith(newData.bodyContentMarker)`,`newData.updatedAt > data.updatedAt`,`newData.updatedAt >= data.createdAt`,W(`newData.updatedAt`)),B(`newData.status != data.status`,`newData.workflowRevision == data.workflowRevision + 1`,`newData.updatedAt > data.updatedAt`,`newData.updatedAt >= data.createdAt`,W(`newData.updatedAt`),V(B(`newData.status == 'open'`,H(`newData`,`resolvedAt`),H(`newData`,`resolvedById`)),B(`newData.status == 'resolved'`,`has(newData.resolvedAt)`,`newData.resolvedAt == newData.updatedAt`,`has(newData.resolvedById)`,`newData.resolvedById == auth.id`))),{...I},{...L},B(`has(data.slotKey)`,`data.slotKey == data.commentId + ':element:' + string(data.ordinal)`),B(`size(data.selector) > 0 && size(data.selector) <= 4096`,U(`data.selector`),`size(data.tagName) > 0 && size(data.tagName) <= 128`,U(`data.tagName`),`size(data.textPreview) <= 1000`,`data.pageX >= -100000000 && data.pageX <= 100000000`,`data.pageY >= -100000000 && data.pageY <= 100000000`,`data.width >= 0 && data.width <= 100000000`,`data.height >= 0 && data.height <= 100000000`,`data.viewportX >= -100000000 && data.viewportX <= 100000000`,`data.viewportY >= -100000000 && data.viewportY <= 100000000`,`data.viewportWidth >= 0 && data.viewportWidth <= 100000000`,`data.viewportHeight >= 0 && data.viewportHeight <= 100000000`),{...I},V(qe,Je),{...L},B(`has(data.slotKey)`,`data.slotKey == data.commentId + ':scope:' + string(data.ordinal)`),B(`size(data.key) > 0 && size(data.key) <= 256`,U(`data.key`)),V(B(`data.valueType == 'string'`,`has(data.stringValue)`,`size(data.stringValue) <= 1000`,H(`data`,`numberValue`),H(`data`,`booleanValue`)),B(`data.valueType == 'number'`,`has(data.numberValue)`,`data.numberValue >= -${Ue}`,`data.numberValue <= ${Ue}`,H(`data`,`stringValue`),H(`data`,`booleanValue`)),B(`data.valueType == 'boolean'`,`has(data.booleanValue)`,H(`data`,`stringValue`),H(`data`,`numberValue`)),B(`data.valueType == 'null'`,H(`data`,`stringValue`),H(`data`,`numberValue`),H(`data`,`booleanValue`))),{...I},V(qe,Je),{...L},{...I},{...L},B(`data.createdAt == data.updatedAt`,W(`data.createdAt`),`size(data.body) > 0`,`size(data.body) <= 20000`,`has(data.bodyContentMarker)`,`size(data.bodyContentMarker) == 1`,U(`data.bodyContentMarker`),`data.body.startsWith(data.bodyContentMarker)`,`size(data.authorName) > 0`,`size(data.authorName) <= 512`,U(`data.authorName`),`request.modifiedFields.all(field, field in ['pageId', 'commentId', 'authorId', 'authorAuthUserId', 'authorName', 'body', 'bodyContentMarker', 'createdAt', 'updatedAt', 'comment', 'author'])`),B(`request.modifiedFields.all(field, field in ['body', 'bodyContentMarker', 'updatedAt'])`,`'body' in request.modifiedFields`,`'bodyContentMarker' in request.modifiedFields`,`'updatedAt' in request.modifiedFields`,`size(newData.body) > 0`,`size(newData.body) <= 20000`,`has(newData.bodyContentMarker)`,`size(newData.bodyContentMarker) == 1`,U(`newData.bodyContentMarker`),`newData.body.startsWith(newData.bodyContentMarker)`,`newData.updatedAt > data.updatedAt`,`newData.updatedAt >= data.createdAt`,W(`newData.updatedAt`)),{...I},{...L};var et=class extends Error{code;constructor(e,t){super(t),this.code=e,this.name=`ReviewBootstrapError`}};const G=new Map;function tt(e,t={}){let n=e.trim();if(!n)throw Error(`InstantDB app ID is required`);return{async resolve(e){let r=(t.databaseFactory??we)(n),i=await it(n,r,e.authHost,e.signal,e.styleNonce);for(;;)try{await nt(t.acceptInvitation,{refreshToken:i.refresh_token,invitationId:e.invitationId,suggestedDisplayName:ht(i.email),authHost:e.authHost,signal:e.signal,styleNonce:e.styleNonce});break}catch(t){if(!gt(t,`INVITATION_EMAIL_MISMATCH`))throw t;await ut(e.authHost,e.signal,e.styleNonce),i=await at(n,r,i,e.authHost,e.signal,e.styleNonce)}let{data:a}=await r.queryOnce({reviewers:{$:{where:{authUserId:i.id}}},reviewPages:{$:{where:{stagingOrigin:e.location.origin}}},invitations:{}}),o=rt(a.invitations,a.reviewers,a.reviewPages,{invitationId:e.invitationId,authUserId:i.id,email:i.email??``,location:e.location,now:Date.now()});if(!o.ok)throw new et(o.code,bt(o.code));let s={authUserId:i.id,reviewerId:o.reviewer.id,projectId:o.reviewer.projectId,invitationId:e.invitationId,email:o.reviewer.email||i.email||``,displayName:o.reviewer.displayName||i.email||`Reviewer`,role:o.reviewer.role===`agency`?`agency`:`reviewer`};return{pageId:o.page.id,session:s,repository:new Te(r,s),allowedStagingHosts:[e.location.hostname]}}}}async function nt(e,t){if(!e)return;let n={refreshToken:t.refreshToken,invitationId:t.invitationId,signal:t.signal};try{await e(n);return}catch(e){if(!gt(e,`DISPLAY_NAME_REQUIRED`))throw e}let r=await lt(t.authHost,t.signal,t.suggestedDisplayName,t.styleNonce);await e({...n,displayName:r})}function rt(e,t,n,r){let i=e.find(({id:e})=>e===r.invitationId);if(!i||yt(i.email)!==yt(r.email))return{ok:!1,code:`INVITATION_REQUIRED`};if(i.status===`revoked`)return{ok:!1,code:`INVITATION_REVOKED`};if(i.status===`expired`||i.expiresAt<=r.now)return{ok:!1,code:`INVITATION_EXPIRED`};if(i.status!==`accepted`)return{ok:!1,code:`INVITATION_NOT_ACCEPTED`};let a=t.find(e=>e.authUserId===r.authUserId&&e.projectId===i.projectId);if(!a)return{ok:!1,code:`MEMBERSHIP_REQUIRED`};let o=vt(r.location.pathname),s=n.find(e=>e.projectId===i.projectId&&e.stagingOrigin===r.location.origin&&vt(e.pathname)===o);return s?{ok:!0,invitation:i,reviewer:a,page:s}:{ok:!1,code:`PAGE_NOT_FOUND`}}async function it(e,t,n,r,i){let a=await K(r,()=>t.getAuth());if(a)return a;let o=await ot(e,r);try{return await K(r,()=>t.getAuth())||await ct(t,n,r,i)}finally{o()}}async function at(e,t,n,r,i,a){q(i);let o=await ot(e,i);try{let e=await K(i,()=>t.getAuth());return e&&e.id!==n.id?e:(e&&await K(i,async()=>{await t.auth.signOut()}),q(i),await ct(t,r,i,a))}finally{o()}}async function ot(e,t){q(t);let n=G.get(e);return n||(n={held:!1,waiters:[]},G.set(e,n)),n.held?new Promise((e,r)=>{let i,a=()=>{let e=n.waiters.indexOf(i);e<0||(n.waiters.splice(e,1),t.removeEventListener(`abort`,a),r(Z()))};i={signal:t,resolve:e,reject:r,abort:a},n.waiters.push(i),t.addEventListener(`abort`,a,{once:!0}),t.aborted&&a()}):(n.held=!0,st(e,n))}function st(e,t){let n=!1;return()=>{if(!n){for(n=!0;t.waiters.length>0;){let n=t.waiters.shift();if(n.signal.removeEventListener(`abort`,n.abort),n.signal.aborted){n.reject(Z());continue}n.resolve(st(e,t));return}t.held=!1,G.get(e)===t&&G.delete(e)}}}async function K(e,t){q(e);let n=await t();return q(e),n}function q(e){if(e.aborted)throw Z()}function ct(e,t,n,r){try{q(n)}catch(e){return Promise.reject(e)}let i=J(t);i.replaceChildren(Y(i,r),ft(i));let a=i.querySelector(`form`),o=i.querySelector(`h2`),s=i.querySelector(`.description`),c=a.elements.namedItem(`email`),l=a.elements.namedItem(`code`),u=i.querySelector(`.code`),d=i.querySelector(`button`),f=i.querySelector(`.error`),p=!1;return new Promise((t,r)=>{let m=!1,h=!1,g=!1,_=()=>{n.removeEventListener(`abort`,y),i.removeEventListener(`keydown`,b),a.removeEventListener(`submit`,x)},v=e=>{m||(m=!0,_(),e())},y=()=>{m||(g=!0,_(),h||v(()=>r(Z())))},b=e=>{let t=e;t.key===`Escape`?(t.preventDefault(),y()):t.key===`Tab`&&_t(i,t)},x=async i=>{if(i.preventDefault(),!(m||h)){h=!0,f.textContent=``,d.disabled=!0,a.setAttribute(`aria-busy`,`true`);try{if(q(n),!p){let t=c.value.trim();await K(n,async()=>{await e.auth.sendMagicCode({email:t})}),p=!0,c.readOnly=!0,u.hidden=!1,l.required=!0,o.textContent=`인증 코드`,s.textContent=`${t}로 보낸 코드를 입력하세요.`,d.textContent=`확인`,l.focus();return}await K(n,async()=>{await e.auth.signInWithMagicCode({email:c.value.trim(),code:l.value.trim()})});let r=await K(n,()=>e.getAuth());if(!r)throw Error(`인증 세션을 확인할 수 없습니다.`);v(()=>t(r))}catch(e){if(m||n.aborted||gt(e,`AUTH_CANCELLED`))return;f.textContent=dt(e)}finally{h=!1,!m&&(g||n.aborted)?v(()=>r(Z())):m||(d.disabled=!1,a.removeAttribute(`aria-busy`))}}};n.addEventListener(`abort`,y,{once:!0}),i.addEventListener(`keydown`,b),a.addEventListener(`submit`,x)})}function lt(e,t,n=``,r){if(t.aborted)return Promise.reject(Z());let i=J(e);i.replaceChildren(Y(i,r),pt(i));let a=i.querySelector(`form`),o=a.elements.namedItem(`displayName`),s=i.querySelector(`button`),c=i.querySelector(`.error`);return o.value=n.trim().slice(0,120),o.focus(),o.select(),new Promise((e,n)=>{let r=!1,l=e=>{r||(r=!0,t.removeEventListener(`abort`,u),i.removeEventListener(`keydown`,p),a.removeEventListener(`submit`,f),e())},u=()=>l(()=>n(Z())),d=()=>{let t=o.value.trim();if(!t){c.textContent=`이름을 입력해 주세요.`,o.focus();return}if(t.length>120){c.textContent=`이름은 120자 이하여야 합니다.`,o.focus();return}c.textContent=``,s.disabled=!0,a.setAttribute(`aria-busy`,`true`),l(()=>e(t))},f=e=>{e.preventDefault(),d()},p=e=>{let t=e;if(t.key===`Escape`){t.preventDefault(),u();return}if(t.key===`Tab`){_t(i,t);return}t.key===`Enter`&&!t.isComposing&&t.target===o&&(t.preventDefault(),d())};t.addEventListener(`abort`,u,{once:!0}),i.addEventListener(`keydown`,p),a.addEventListener(`submit`,f)})}function ut(e,t,n){if(t.aborted)return Promise.reject(Z());let r=J(e);r.replaceChildren(Y(r,n),mt(r));let i=r.querySelector(`form`),a=r.querySelector(`button`);return a.focus(),new Promise((e,n)=>{let o=!1,s=e=>{o||(o=!0,t.removeEventListener(`abort`,c),r.removeEventListener(`keydown`,u),i.removeEventListener(`submit`,l),e())},c=()=>s(()=>n(Z())),l=t=>{t.preventDefault(),a.disabled=!0,i.setAttribute(`aria-busy`,`true`),s(e)},u=e=>{let t=e;t.key===`Escape`?(t.preventDefault(),c()):t.key===`Tab`&&_t(r,t)};t.addEventListener(`abort`,c,{once:!0}),r.addEventListener(`keydown`,u),i.addEventListener(`submit`,l)})}function dt(e){if(e&&typeof e==`object`&&`body`in e){let t=e.body;if(t?.message)return t.message}return e instanceof Error?e.message:`로그인에 실패했습니다. 다시 시도해 주세요.`}function J(e){return e.shadowRoot??e.attachShadow({mode:`open`})}function Y(e,t){let n=e.ownerDocument.createElement(`style`);return t&&(n.nonce=t),n.textContent=xt,n}function ft(e){let t=e.ownerDocument,n=t.createElement(`form`);n.setAttribute(`role`,`dialog`),n.setAttribute(`aria-modal`,`true`),n.setAttribute(`aria-labelledby`,`visual-review-login-title`),n.setAttribute(`aria-describedby`,`visual-review-login-description`);let r=X(t,`p`,`01.works`,`eyebrow`),i=X(t,`h2`,`Visual Review`);i.id=`visual-review-login-title`;let a=X(t,`p`,`초대받은 이메일로 계속하세요.`,`description`);a.id=`visual-review-login-description`;let o=t.createElement(`label`);o.append(`이메일`);let s=t.createElement(`input`);s.name=`email`,s.type=`email`,s.autocomplete=`email`,s.required=!0,o.append(s);let c=t.createElement(`label`);c.className=`code`,c.hidden=!0,c.append(`인증 코드`);let l=t.createElement(`input`);l.name=`code`,l.inputMode=`numeric`,l.autocomplete=`one-time-code`,c.append(l);let u=X(t,`p`,``,`error`);u.setAttribute(`role`,`alert`);let d=X(t,`button`,`코드 받기`);return d.type=`submit`,n.append(r,i,a,o,c,u,d),n}function pt(e){let t=e.ownerDocument,n=t.createElement(`form`);n.setAttribute(`role`,`dialog`),n.setAttribute(`aria-modal`,`true`),n.setAttribute(`aria-labelledby`,`visual-review-name-title`),n.setAttribute(`aria-describedby`,`visual-review-name-description`);let r=X(t,`p`,`01.works`,`eyebrow`),i=X(t,`h2`,`표시 이름`);i.id=`visual-review-name-title`;let a=X(t,`p`,`피드백에 이 이름이 표시됩니다.`,`description`);a.id=`visual-review-name-description`;let o=X(t,`label`,`이름`);o.htmlFor=`visual-review-display-name`;let s=t.createElement(`input`);s.id=`visual-review-display-name`,s.name=`displayName`,s.autocomplete=`name`,s.maxLength=120,s.required=!0;let c=X(t,`p`,``,`error`);c.setAttribute(`role`,`alert`);let l=X(t,`button`,`리뷰 시작`);return l.type=`submit`,n.append(r,i,a,o,s,c,l),n}function mt(e){let t=e.ownerDocument,n=t.createElement(`form`);n.setAttribute(`role`,`dialog`),n.setAttribute(`aria-modal`,`true`),n.setAttribute(`aria-labelledby`,`visual-review-account-title`),n.setAttribute(`aria-describedby`,`visual-review-account-description`);let r=X(t,`p`,`01.works`,`eyebrow`),i=X(t,`h2`,`계정 확인`);i.id=`visual-review-account-title`;let a=X(t,`p`,`이 초대는 현재 로그인한 계정과 일치하지 않습니다.`,`description`);a.id=`visual-review-account-description`;let o=X(t,`button`,`다른 계정으로 계속`);return o.type=`submit`,n.append(r,i,a,o),n}function X(e,t,n,r){let i=e.createElement(t);return i.textContent=n,r&&(i.className=r),i}function ht(e){return e?.split(`@`)[0]?.trim().slice(0,120)??``}function gt(e,t){return!!(e&&typeof e==`object`&&`code`in e&&e.code===t)}function Z(){return new et(`AUTH_CANCELLED`,`리뷰 로그인이 취소되었습니다.`)}function _t(e,t){let n=Array.from(e.querySelectorAll(`input:not([disabled]),button:not([disabled])`)).filter(e=>!e.closest(`[hidden]`));if(n.length===0)return;let r=n[0],i=n.at(-1);t.shiftKey&&e.activeElement===r?(t.preventDefault(),i.focus()):!t.shiftKey&&e.activeElement===i&&(t.preventDefault(),r.focus())}function vt(e){return e.replace(/\/+$/,``)||`/`}function yt(e){return e.trim().toLowerCase()}function bt(e){switch(e){case`INVITATION_REQUIRED`:return`현재 계정과 일치하는 리뷰 초대를 찾을 수 없습니다.`;case`INVITATION_NOT_ACCEPTED`:return`아직 수락되지 않은 리뷰 초대입니다.`;case`INVITATION_REVOKED`:return`취소된 리뷰 초대입니다.`;case`INVITATION_EXPIRED`:return`만료된 리뷰 초대입니다.`;case`MEMBERSHIP_REQUIRED`:return`이 프로젝트의 reviewer membership이 없습니다.`;case`PAGE_NOT_FOUND`:return`현재 staging 페이지가 이 프로젝트에 등록되어 있지 않습니다.`}}const xt=`
2
+ :host{all:initial;--vr-panel:#fff;--vr-text:#161616;--vr-muted:#707070;--vr-label:#3f3f3f;--vr-control:#fff;--vr-border:#d9d9d9;--vr-action:#161616;--vr-action-text:#fff;position:fixed;inset:0;z-index:2147483646;display:grid;place-items:center;overflow:auto;padding:8px;box-sizing:border-box;background:rgba(15,15,15,.34);font-family:Inter,ui-sans-serif,system-ui,sans-serif;color:var(--vr-text)}
3
+ form{box-sizing:border-box;width:min(320px,calc(100vw - 16px));padding:20px;border:0;border-radius:14px;background:var(--vr-panel);box-shadow:0 18px 56px rgba(0,0,0,.18)}
4
+ .eyebrow{margin:0 0 10px;color:var(--vr-muted);font-size:10px;font-weight:700;letter-spacing:.09em;text-transform:uppercase}
5
+ h2{margin:0 0 5px;font-size:16px;line-height:1.3;letter-spacing:-.01em}.description{margin:0 0 18px;color:var(--vr-muted);font-size:13px;line-height:1.45}
6
+ label{display:grid;gap:6px;margin-top:12px;color:var(--vr-label);font-size:12px;font-weight:600}input{box-sizing:border-box;width:100%;height:40px;margin-top:6px;padding:0 11px;border:1px solid var(--vr-border);border-radius:9px;background:var(--vr-control);color:var(--vr-text);font:400 13px/1 Inter,ui-sans-serif,system-ui,sans-serif}
7
+ label input{margin-top:0}input:focus{border-color:#999;outline:0;box-shadow:0 0 0 3px rgba(127,127,127,.16)}.error{min-height:17px;margin:8px 0 0;color:#d92d20;font-size:11px;line-height:1.45}
8
+ button{width:100%;height:40px;margin-top:7px;border:0;border-radius:9px;background:var(--vr-action);color:var(--vr-action-text);font:650 13px/1 Inter,ui-sans-serif,system-ui,sans-serif;cursor:pointer}button:focus-visible{outline:2px solid var(--vr-action);outline-offset:2px}button:disabled{opacity:.55;cursor:wait}
9
+ @media (prefers-color-scheme:dark){:host{--vr-panel:#161616;--vr-text:#fff;--vr-muted:#a7a7a7;--vr-label:#d6d6d6;--vr-control:#222;--vr-border:#3a3a3a;--vr-action:#fff;--vr-action-text:#171717}}
10
+ @media (pointer:coarse){input,button{height:44px}}
11
+ @media (max-width:480px){form{padding:18px}input{font-size:16px}}
12
+ @media (prefers-reduced-motion:reduce){*,*::before,*::after{scroll-behavior:auto!important;transition:none!important;animation:none!important}}
13
+ `;var Q=class extends Error{code;status;constructor(e,t,n){super(t),this.code=e,this.status=n,this.name=`HostedBootstrapError`}};function St(e={}){return Ct(e)}function Ct(t={},n={}){let r=e(t.serviceUrl??`https://visual-review.01.works`),i=t.fetch??globalThis.fetch,a=n.instantRuntimeFactory??tt;if(typeof i!=`function`)throw Error(`Visual Review bootstrap requires the Fetch API`);return{async resolve(e){let t={invitationId:e.invitationId,origin:e.location.origin,pathname:e.location.pathname},n=await i(`${r}/v1/bootstrap`,{method:`POST`,headers:{accept:`application/json`,"content-type":`application/json`},body:JSON.stringify(t),cache:`no-store`,credentials:`omit`,signal:e.signal}),o=await Tt(n);if(!n.ok)throw new Q($(o,`error`)??`BOOTSTRAP_FAILED`,$(o,`message`)??`Visual Review bootstrap에 실패했습니다.`,n.status);let s=wt(o);return a(s.instantAppId,{acceptInvitation:async e=>{let t=await i(`${r}/v1/invitations/accept`,{method:`POST`,headers:{accept:`application/json`,authorization:`Bearer ${e.refreshToken}`,"content-type":`application/json`},body:JSON.stringify({invitationId:e.invitationId,...e.displayName===void 0?{}:{displayName:e.displayName}}),cache:`no-store`,credentials:`omit`,signal:e.signal}),n=await Tt(t);if(!t.ok)throw new Q($(n,`error`)??`INVITATION_ACCEPT_FAILED`,$(n,`message`)??`리뷰 초대 수락에 실패했습니다.`,t.status)}}).resolve(e)}}}function wt(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new Q(`INVALID_BOOTSTRAP_RESPONSE`,`잘못된 bootstrap 응답입니다.`,502);let t=e,n=$(t,`instantAppId`);if(t.apiVersion!==1||!n||!Et(n))throw new Q(`INVALID_BOOTSTRAP_RESPONSE`,`잘못된 bootstrap 응답입니다.`,502);return{apiVersion:1,instantAppId:n}}async function Tt(e){try{return await e.json()}catch{throw new Q(`INVALID_BOOTSTRAP_RESPONSE`,`JSON bootstrap 응답이 필요합니다.`,502)}}function $(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e[t];return typeof n==`string`&&n.trim()?n.trim():null}function Et(e){return/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(e)}export{St as createHostedReviewRuntime};
@@ -0,0 +1,200 @@
1
+ export interface VisualReviewBuildContext {
2
+ buildId: string;
3
+ gitCommit: string | null;
4
+ generatedAt?: number;
5
+ mode: 'development' | 'preview' | 'production';
6
+ }
7
+
8
+ export interface VisualReviewGeneratedFrameLocator {
9
+ assetPath: string;
10
+ /** 1-based generated line. */
11
+ line1: number;
12
+ /** 0-based generated column. */
13
+ column0: number;
14
+ runtime: 'browser' | 'server-node' | 'server-edge' | 'unknown';
15
+ debugId?: string;
16
+ }
17
+
18
+ export interface VisualReviewSourceLocation {
19
+ filePath: string;
20
+ lineNumber: number | null;
21
+ columnNumber: number | null;
22
+ componentName: string | null;
23
+ origin: 'app' | 'shared-ui' | 'dependency' | 'generated' | 'unknown';
24
+ generated?: VisualReviewGeneratedFrameLocator;
25
+ }
26
+
27
+ export interface VisualReviewSourceProvenance {
28
+ provider: 'react-grab' | 'embedded' | 'custom';
29
+ build: VisualReviewBuildContext;
30
+ resolvedAt: number;
31
+ sourceMapStatus: 'resolved' | 'fallback' | 'unavailable';
32
+ }
33
+
34
+ export interface VisualReviewAnchor {
35
+ selector: string;
36
+ offsetX: number;
37
+ offsetY: number;
38
+ viewportX: number;
39
+ viewportY: number;
40
+ }
41
+
42
+ export interface VisualReviewTargetRect {
43
+ pageX: number;
44
+ pageY: number;
45
+ width: number;
46
+ height: number;
47
+ viewportX: number;
48
+ viewportY: number;
49
+ viewportWidth: number;
50
+ viewportHeight: number;
51
+ }
52
+
53
+ export interface VisualReviewSelectedElementContext {
54
+ selector: string;
55
+ tagName: string;
56
+ textPreview: string;
57
+ rect: VisualReviewTargetRect;
58
+ source: VisualReviewSourceLocation | null;
59
+ componentStack: VisualReviewSourceLocation[];
60
+ }
61
+
62
+ export interface VisualReviewAnnotationTarget {
63
+ kind: 'element' | 'region' | 'viewport';
64
+ anchor: VisualReviewAnchor;
65
+ region: VisualReviewTargetRect;
66
+ elements: VisualReviewSelectedElementContext[];
67
+ pageUrl: string;
68
+ pageTitle: string;
69
+ capturedAt: number;
70
+ sourceProvenance?: VisualReviewSourceProvenance;
71
+ }
72
+
73
+ /** Advanced resolver seam. Most integrations should use the automatic resolver. */
74
+ export interface VisualReviewSourceContextResolver {
75
+ resolve(element: Element, options?: { signal?: AbortSignal }): Promise<{
76
+ source: VisualReviewSourceLocation | null;
77
+ componentStack: VisualReviewSourceLocation[];
78
+ provenance?: VisualReviewSourceProvenance;
79
+ }>;
80
+ unavailableProvenance?(): VisualReviewSourceProvenance;
81
+ }
82
+
83
+ export interface VisualReviewReviewerSession {
84
+ authUserId: string;
85
+ reviewerId: string;
86
+ projectId: string;
87
+ invitationId: string;
88
+ email: string;
89
+ displayName: string;
90
+ role: 'agency' | 'reviewer';
91
+ }
92
+
93
+ export interface VisualReviewComment {
94
+ id: string;
95
+ pageId: string;
96
+ authorId: string;
97
+ authorName: string;
98
+ body: string;
99
+ anchor: VisualReviewAnchor;
100
+ target: VisualReviewAnnotationTarget;
101
+ scope?: Record<string, string | number | boolean | null>;
102
+ status: 'open' | 'resolved';
103
+ workflowRevision?: number;
104
+ createdAt: number;
105
+ updatedAt: number;
106
+ resolvedAt?: number;
107
+ resolvedById?: string;
108
+ }
109
+
110
+ export interface VisualReviewReply {
111
+ id: string;
112
+ commentId: string;
113
+ authorId: string;
114
+ authorName: string;
115
+ body: string;
116
+ createdAt: number;
117
+ updatedAt: number;
118
+ }
119
+
120
+ export interface VisualReviewSnapshot {
121
+ pageId: string;
122
+ comments: VisualReviewComment[];
123
+ replies: VisualReviewReply[];
124
+ }
125
+
126
+ export type VisualReviewMutation =
127
+ | { type: 'comment.upsert'; comment: VisualReviewComment }
128
+ | { type: 'comment.delete'; commentId: string }
129
+ | { type: 'reply.upsert'; reply: VisualReviewReply }
130
+ | { type: 'reply.delete'; commentId: string; replyId: string };
131
+
132
+ export type VisualReviewSubscriptionFailure =
133
+ | {
134
+ type: 'access-lost';
135
+ code: 'permission-denied' | 'session-expired' | 'membership-revoked';
136
+ recovery: 'reauthenticate';
137
+ clearSnapshot: true;
138
+ }
139
+ | {
140
+ type: 'error';
141
+ code: 'transport' | 'data-integrity' | 'unknown';
142
+ recovery: 'retry';
143
+ clearSnapshot: true;
144
+ };
145
+
146
+ export interface VisualReviewRepository {
147
+ getSnapshot(pageId: string): Promise<VisualReviewSnapshot>;
148
+ subscribe(
149
+ pageId: string,
150
+ listener: (snapshot: VisualReviewSnapshot) => void,
151
+ onFailure?: (failure: VisualReviewSubscriptionFailure) => void,
152
+ ): () => void;
153
+ mutate(pageId: string, mutation: VisualReviewMutation): Promise<void>;
154
+ }
155
+
156
+ export interface ReviewRuntimeRequest {
157
+ invitationId: string;
158
+ location: Location;
159
+ signal: AbortSignal;
160
+ authHost: HTMLElement;
161
+ /** CSP nonce inherited from the staging document for review-owned styles. */
162
+ styleNonce?: string;
163
+ }
164
+
165
+ /** Advanced runtime seam intended for self-hosted development and tests. */
166
+ export interface ReviewRuntimeContext {
167
+ pageId: string;
168
+ session: VisualReviewReviewerSession;
169
+ repository: VisualReviewRepository;
170
+ allowedStagingHosts: string[];
171
+ }
172
+
173
+ export interface VisualReviewRuntime {
174
+ resolve(request: ReviewRuntimeRequest): Promise<ReviewRuntimeContext>;
175
+ }
176
+
177
+ export interface InstallVisualReviewOptions {
178
+ /** Override only for local development or self-hosted integration tests. */
179
+ serviceUrl?: string;
180
+ build?: Partial<VisualReviewBuildContext>;
181
+ sourceContextResolver?: VisualReviewSourceContextResolver;
182
+ runtime?: VisualReviewRuntime;
183
+ /** Explicit deployment gate. The runtime stays dormant unless this is exactly true. */
184
+ enabled?: boolean;
185
+ activationParam?: string;
186
+ /** CSP nonce for review-owned styles. Defaults to a nonce found on the host document. */
187
+ styleNonce?: string;
188
+ onError?: (error: Error) => void;
189
+ }
190
+
191
+ export interface VisualReviewInstallation {
192
+ ready: Promise<HTMLElement | null>;
193
+ /** Re-resolve the current page after a framework router changes it in place. */
194
+ refresh(): Promise<HTMLElement | null>;
195
+ dispose(): void;
196
+ }
197
+
198
+ export declare function installVisualReview(
199
+ options?: InstallVisualReviewOptions,
200
+ ): VisualReviewInstallation;
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ import{t as e}from"./install-BN5uBP-5.js";export{e as installVisualReview};
@@ -0,0 +1 @@
1
+ const e=`https://visual-review.01.works`;function t(e){let t=new URL(e),n=t.hostname===`localhost`||t.hostname===`127.0.0.1`||t.hostname.endsWith(`.test`)||t.hostname.endsWith(`.local`);if(t.protocol!==`https:`&&!(n&&t.protocol===`http:`))throw Error(`Visual Review serviceUrl must use HTTPS outside local development`);if(t.username||t.password||t.search||t.hash)throw Error(`Visual Review serviceUrl must be a plain origin or base path`);return t.toString().replace(/\/+$/,``)}const n=()=>{let e=Promise.resolve(null);return{ready:e,refresh:()=>e,dispose(){}}},r=new Map,i=6e4,a=1e4;function o(e={}){if(e.enabled!==!0||typeof window>`u`||typeof document>`u`)return n();let r=!1,i=0,a=null,o=null,f=null,m=null,h=document.baseURI,g=new WeakMap,x=new Map,T=U(window),A=X(e.styleNonce,document),M=e.activationParam??`visual-review`,N=_(window.location,M),P=p(window,e=>{let t=_(e,M);if(t===N)return;let n=D(M,e.href);n&&x.set(e.origin,n),N=t,I()}),F=e=>{r||!f||e.target!==f||(N=_(window.location,M),I())};return window.addEventListener(`visual-review:reauthenticate-required`,F),{ready:I(),refresh(){return r?Promise.resolve(null):(N=_(window.location,M),I())},dispose(){r||(r=!0,i+=1,a?.abort(),a=null,f?.remove(),f=null,m?.remove(),m=null,x.clear(),P.unsubscribe(),window.removeEventListener(`visual-review:reauthenticate-required`,F))}};function I(){let t=++i;a?.abort(),f?.remove(),f=null,m?.remove();let n=new AbortController,r=document.createElement(`div`);r.dataset.agencyReviewRoot=``,a=n,m=r;let s=L(t,n,r);return o=s,s.then(r=>{r&&B(t,n)&&f===r&&e.onReady?.(r)}),s}async function L(t,n,i){try{let e=document.body??await j(document,n.signal);if(!B(t,n))return H(t);e.append(i);let r=await R(t,n,i);return B(t,n)?r:(i.remove(),H(t))}catch(a){if(!B(t,n))return i.remove(),H(t);if(u(a,`AUTH_CANCELLED`))return i.remove(),m===i&&(m=null),null;z(a,i);let o=J(a,g.get(i)?.[2]);return q(i,o.message,A,()=>{r||m!==i||(N=_(window.location,M),I())}),e.onError?.(o),window.dispatchEvent(new CustomEvent(`visual-review:error`,{detail:o})),null}}async function R(n,r,i){let a=t(e.serviceUrl??`https://visual-review.01.works`),o=v(window.location),u=E(a,M,o,T),d=y(x.get(o.origin)),p=b(S(a,o.origin)),D=u?.source===`url`?u:d??p??u;if(!D)return g.delete(i),i.remove(),m===i&&(m=null),null;let j=D.invitationId;g.set(i,[a,o.origin,j]),D.source===`url`?(W(a,o.origin,T),x.set(o.origin,j),C(a,o.origin,j),P.suppress(()=>O(M))):D.source===`handoff`&&x.set(o.origin,j),N=_(window.location,M);let F=await k((e.runtime??await s(a)).resolve({invitationId:j,location:o,signal:r.signal,authHost:i,styleNonce:A}),r.signal);if(!B(n,r))return null;w(a,o.origin,j),V(a,j,o,T),x.set(o.origin,j);let I=e.sourceContextResolver??await l(e.build,h,r.signal);if(!B(n,r))return null;let{mountReviewWidget:L}=await c(r.signal);return B(n,r)?(f=L({...F,sourceContextResolver:I,styleNonce:A}),i.remove(),m===i&&(m=null),window.dispatchEvent(new CustomEvent(`visual-review:ready`,{detail:f})),f):null}function z(e,t){if(!d(e))return;let n=g.get(t);if(!n)return;let[r,i,a]=n;w(r,i,a),x.get(i)===a&&x.delete(i),W(r,i,T,a)}function B(e,t){return!r&&i===e&&a===t&&!t.signal.aborted}function H(e){return!r&&i!==e?o:null}}async function s(e){let{createHostedReviewRuntime:t}=await import(`./hosted-runtime-CgyV50-M.js`);return t({serviceUrl:e})}async function c(e){return A(import(`./src-1EIago0s.js`),e,a,`리뷰 위젯을 불러오는 시간이 초과되었습니다. 다시 시도해 주세요.`)}async function l(e,t,n){let r=M(e),{createGeneratedSourceContextResolver:i}=await A(import(`./generated-source-context-9dbnOHdW.js`),n,a,`리뷰 소스 정보를 불러오는 시간이 초과되었습니다. 다시 시도해 주세요.`);return i({build:r,sourceIndexBaseUrl:t})}function u(e,t){return e instanceof Error&&`code`in e&&e.code===t}function d(e){let t=e instanceof Error&&`code`in e?e.code:void 0;return typeof t==`string`&&/^INVITATION_(?:EXPIRED|NOT_FOUND|REQUIRED|REVOKED)$/.test(t)}const f=new WeakMap;function p(e,t){let n=f.get(e);if(!n){let t=e.history,r=t.pushState,i=t.replaceState,a=new Set;n={history:t,originalPushStateDescriptor:Object.getOwnPropertyDescriptor(t,`pushState`),originalReplaceStateDescriptor:Object.getOwnPropertyDescriptor(t,`replaceState`),patchedPushState:function(t,n,i){r.call(this,t,n,i),m(e)},patchedReplaceState:function(t,n,r){i.call(this,t,n,r),m(e)},popstateListener:()=>m(e),subscribers:a,suppressionDepth:0},f.set(e,n),h(t,`pushState`,n.patchedPushState),h(t,`replaceState`,n.patchedReplaceState),e.addEventListener(`popstate`,n.popstateListener)}n.subscribers.add(t);let r=!0;return{suppress(e){n.suppressionDepth+=1;try{return e()}finally{--n.suppressionDepth}},unsubscribe(){r&&(r=!1,n.subscribers.delete(t),!(n.subscribers.size>0)&&(e.removeEventListener(`popstate`,n.popstateListener),g(n.history,`pushState`,n.patchedPushState,n.originalPushStateDescriptor),g(n.history,`replaceState`,n.patchedReplaceState,n.originalReplaceStateDescriptor),f.delete(e)))}}}function m(e){let t=f.get(e);if(!t||t.suppressionDepth>0)return;let n=v(e.location);[...t.subscribers].forEach(e=>e(n))}function h(e,t,n){Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:!0,value:n})}function g(e,t,n,r){if(Object.getOwnPropertyDescriptor(e,t)?.value===n){if(r){Object.defineProperty(e,t,r);return}delete e[t]}}function _(e,t){return`${e.origin}\n${e.pathname}\n${D(t,e.href)??``}`}function v(e){return new URL(e.href)}function y(e){return e?{invitationId:e,source:`memory`}:null}function b(e){return e?{invitationId:e,source:`handoff`}:null}function x(e,t){return JSON.stringify([e,t])}function S(e,t,n=Date.now()){let i=x(e,t),a=r.get(i);if(a){if(a.expiresAt>n)return a.invitationId;clearTimeout(a.timeout),r.delete(i)}}function C(e,t,n,a=Date.now()){T(a);let o=x(e,t),s=r.get(o);for(s&&(clearTimeout(s.timeout),r.delete(o));r.size>=32;){let e=r.keys().next().value;if(!e)break;let t=r.get(e);t&&clearTimeout(t.timeout),r.delete(e)}let c=a+i,l=setTimeout(()=>{r.get(o)?.expiresAt===c&&r.delete(o)},i);r.set(o,{invitationId:n,expiresAt:c,timeout:l})}function w(e,t,n){let i=x(e,t),a=r.get(i);a?.invitationId===n&&(clearTimeout(a.timeout),r.delete(i))}function T(e){for(let[t,n]of r)n.expiresAt>e||(clearTimeout(n.timeout),r.delete(t))}function E(e,t,n,r){let i=D(t,n.href);if(i)return{invitationId:i,source:`url`};let a=H(r,G(e,n.origin));return a?{invitationId:a,source:`storage`}:K(n.hostname)?{invitationId:`local-preview`,source:`local-preview`}:null}function D(e,t){let n=new URL(t);return(n.searchParams.get(e)??n.searchParams.get(`agency-review`)??n.searchParams.get(`agency-review-invite`))?.trim()||null}function O(e){let t=new URL(window.location.href),n=new Set([e,`visual-review`,`agency-review`,`agency-review-invite`]),r=!1;n.forEach(e=>{t.searchParams.has(e)&&(t.searchParams.delete(e),r=!0)}),r&&window.history.replaceState(window.history.state,``,`${t.pathname}${t.search}${t.hash}`)}function k(e,t){return new Promise((n,r)=>{let i=()=>r(new DOMException(`Aborted`,`AbortError`));if(t.aborted){i();return}t.addEventListener(`abort`,i,{once:!0}),e.then(e=>{t.removeEventListener(`abort`,i),n(e)},e=>{t.removeEventListener(`abort`,i),r(e)})})}function A(e,t,n,r){return new Promise((i,a)=>{let o=!1,s=e=>{o||(o=!0,clearTimeout(l),t.removeEventListener(`abort`,c),e())},c=()=>{s(()=>a(new DOMException(`Aborted`,`AbortError`)))},l=setTimeout(()=>{s(()=>a(Error(r)))},n);if(t.aborted){c();return}t.addEventListener(`abort`,c,{once:!0}),e.then(e=>s(()=>i(e)),e=>s(()=>a(e)))})}function j(e,t){return e.body?Promise.resolve(e.body):t.aborted?Promise.reject(new DOMException(`Aborted`,`AbortError`)):new Promise((n,r)=>{let i=!1,a=new MutationObserver(()=>c()),o=()=>{e.removeEventListener(`DOMContentLoaded`,c),t.removeEventListener(`abort`,l),a.disconnect()},s=e=>{i||(i=!0,o(),e())},c=()=>{let t=e.body;t&&s(()=>n(t))},l=()=>{s(()=>r(new DOMException(`Aborted`,`AbortError`)))};e.addEventListener(`DOMContentLoaded`,c),t.addEventListener(`abort`,l,{once:!0}),a.observe(e,{childList:!0,subtree:!0}),c()})}function M(e){let t=document.querySelector(`meta[name="visual-review-build"]`),n=document.querySelector(`meta[name="visual-review-commit"]`),r=B(F()),i=B(I());return{buildId:e?.buildId??z(t)??r??`unversioned`,gitCommit:L(e,n,i),generatedAt:e?.generatedAt,mode:e?.mode??P(N())??(K(window.location.hostname)?`development`:`production`)}}function N(){try{return process.env.VISUAL_REVIEW_PUBLIC_BUILD_MODE}catch{return}}function P(e){return e===`development`||e===`preview`||e===`production`?e:void 0}function F(){try{return process.env.VISUAL_REVIEW_PUBLIC_BUILD_ID}catch{return}}function I(){try{return process.env.VISUAL_REVIEW_PUBLIC_GIT_COMMIT}catch{return}}function L(e,t,n){return e?.gitCommit===null?null:typeof e?.gitCommit==`string`?R(e.gitCommit):R(t?.content)??R(n)}function R(e){if(typeof e!=`string`)return null;let t=e.trim().toLowerCase();return/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/.test(t)?t:null}function z(e){return B(e?.content)}function B(e){return typeof e==`string`&&e.length>0?e:null}function V(e,t,n,r){try{r?.setItem(G(e,n.origin),t)}catch{}}function H(e,t){try{return e?.getItem(t)??null}catch{return null}}function U(e){try{return e.localStorage}catch{return null}}function W(e,t,n,r){try{if(!n)return;let i=G(e,t),a=n.getItem(i);if(a===null||r!==void 0&&a!==r)return;n.removeItem(i)}catch{}}function G(e,t){return`visual-review:${e}:${t}:invitation`}function K(e){return e===`localhost`||e===`127.0.0.1`||e.endsWith(`.test`)||e.endsWith(`.local`)}function q(e,t,n,r){let i=e.shadowRoot??e.attachShadow({mode:`open`}),a=i.ownerDocument,o=a.createElement(`style`);n&&(o.nonce=n),o.textContent=$;let s=a.createElement(`strong`);s.textContent=`Visual Review를 시작할 수 없습니다`;let c=a.createElement(`span`);c.textContent=t;let l=a.createElement(`button`);l.type=`button`,l.textContent=`다시 시도`,l.addEventListener(`click`,()=>{l.disabled=!0,r?.()},{once:!0}),i.replaceChildren(o,s,c,l)}function J(e,t){let n=e instanceof Error?e.message:String(e),r=Error(Y(n,t));if(e&&typeof e==`object`){let n=`code`in e?e.code:void 0,i=`status`in e?e.status:void 0;typeof n==`string`&&Object.defineProperty(r,"code",{configurable:!0,enumerable:!0,value:Y(n,t)}),typeof i==`number`&&Number.isFinite(i)&&Object.defineProperty(r,"status",{configurable:!0,enumerable:!0,value:i})}return r}function Y(e,t){if(!t)return e;let n=new Set([t,encodeURIComponent(t)]),r=e;for(let e of n)e&&(r=r.split(e).join(`[redacted]`));return r}function X(e,t){if(e!==void 0)return Q(e);let n=t.currentScript,r=n?Z(n):void 0;if(r)return r;try{for(let e of t.querySelectorAll(`script[nonce],style[nonce]`)){let t=Z(e);if(t)return t}}catch{}}function Z(e){let t=`nonce`in e?e.nonce:void 0;return typeof t==`string`?Q(t):void 0}function Q(e){return e.trim()||void 0}const $=`:host{all:initial;position:fixed;right:18px;bottom:18px;z-index:2147483646;max-width:360px;padding:16px 18px;border:1px solid #efc4bd;border-radius:14px;background:#fff8f6;box-shadow:0 12px 40px rgba(0,0,0,.14);color:#7a271a;font:13px/1.5 Inter,ui-sans-serif,system-ui,sans-serif}strong{display:block;margin-bottom:4px;color:#53150d}span{display:block}button{margin-top:12px;padding:7px 10px;border:1px solid #d9a79f;border-radius:8px;background:#fff;color:#7a271a;font:650 12px/1 Inter,ui-sans-serif,system-ui,sans-serif;cursor:pointer}button:focus-visible{outline:2px solid #7a271a;outline-offset:2px}button:disabled{opacity:.55;cursor:wait}`;export{e as n,t as r,o as t};
@@ -0,0 +1,44 @@
1
+ import type { NextConfig } from 'next';
2
+
3
+ export interface VisualReviewBuildIdentityOptions {
4
+ /** Browser-visible deployment-unique build identifier. Never reuse it for different output. */
5
+ buildId?: string;
6
+ /** Browser-visible full Git SHA. `null` explicitly disables automatic discovery. */
7
+ gitCommit?: string | null;
8
+ }
9
+
10
+ export type VisualReviewReleaseMode = 'development' | 'preview' | 'production';
11
+
12
+ export interface VisualReviewNextSourceMapOptions {
13
+ /** Enables upload explicitly. A project-scoped upload token is still required. */
14
+ enabled?: boolean;
15
+ /** Node-only build secret. Prefer VISUAL_REVIEW_SOURCE_MAP_TOKEN in CI. */
16
+ token?: string;
17
+ /** Hosted service origin. Primarily useful for local/self-hosted verification. */
18
+ serviceUrl?: string;
19
+ /** Release environment recorded with the private source-map manifest. */
20
+ mode?: VisualReviewReleaseMode;
21
+ }
22
+
23
+ export interface VisualReviewNextOptions extends VisualReviewBuildIdentityOptions {
24
+ /** Upload private Next.js browser, Node, and Edge source maps after compilation. */
25
+ sourceMaps?: boolean | VisualReviewNextSourceMapOptions;
26
+ /** Adds opaque production JSX markers by default. Set `false` for identity-only output. */
27
+ sourceMetadata?: boolean;
28
+ }
29
+
30
+ /** Adds public provenance without changing Next.js's own build ID. */
31
+ export declare function withVisualReview<T extends NextConfig>(
32
+ nextConfig: T,
33
+ options?: VisualReviewNextOptions,
34
+ ): T;
35
+ export declare function withVisualReview<
36
+ T extends (...arguments_: any[]) => NextConfig | Promise<NextConfig>,
37
+ >(
38
+ nextConfig: T,
39
+ options?: VisualReviewNextOptions,
40
+ ): (...arguments_: Parameters<T>) => ReturnType<T>;
41
+ export declare function withVisualReview(
42
+ nextConfig?: NextConfig,
43
+ options?: VisualReviewNextOptions,
44
+ ): NextConfig;