PageSourceSearch

https://kingjamesbiblereader.com/assets/DevToolsPage-CutIYNsI.js

js kingjamesbiblereader.com collected 2026-10-02 01:34:11 UTC 43,961 bytes, 43 lines download raw bytes

1import{c as q,r as u,az as w,j as e,J as A,p as ee,V as te,W as J,T as he,R as fe,x as ge,n as be,a6 as ve,B as ye}from"./index-DwOsqt_4.js";import{j as F,l as K,S as ue,C as pe,k as ae,b as je,a as we,d as Ne,c as ke,E as Se}from"./bibleApi-COTrrsw1.js";import{R as z}from"./rotate-ccw-ItJytbXd.js";import{U as se}from"./upload-C-d6az2H.js";import{E as Ce}from"./external-link-sqXUD4a8.js";import{B as re}from"./button-CPBJ4d74.js";import{L as ne,I as oe}from"./label-DBwMCnm6.js";import{W as xe}from"./wrench-B7WIWxtJ.js";import{S as Re}from"./shield-check-Cshbu5B8.js";import{M as Ee}from"./mail-UQM040rt.js";import{L as _e}from"./lock-Daq8tnrr.js";import{S as Ie}from"./smartphone-B1nGnX_y.js";import{P as ie}from"./puzzle-C1w1wJYh.js";/**
2 * @license lucide-react v0.475.0 - ISC
3 *
4 * This source code is licensed under the ISC license.
5 * See the LICENSE file in the root directory of this source tree.
6 */const Te=[["path",{d:"m3 17 2 2 4-4",key:"1jhpwq"}],["path",{d:"m3 7 2 2 4-4",key:"1obspn"}],["path",{d:"M13 6h8",key:"15sg57"}],["path",{d:"M13 12h8",key:"h98zly"}],["path",{d:"M13 18h8",key:"oe0vm4"}]],Ae=q("ListChecks",Te);/**
7 * @license lucide-react v0.475.0 - ISC
8 *
9 * This source code is licensed under the ISC license.
10 * See the LICENSE file in the root directory of this source tree.
11 */const Le=[["path",{d:"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4",key:"1uf3rs"}],["polyline",{points:"16 17 21 12 16 7",key:"1gabdz"}],["line",{x1:"21",x2:"9",y1:"12",y2:"12",key:"1uyos4"}]],Me=q("LogOut",Le);/**
12 * @license lucide-react v0.475.0 - ISC
13 *
14 * This source code is licensed under the ISC license.
15 * See the LICENSE file in the root directory of this source tree.
16 */const Oe=[["path",{d:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",key:"1c8476"}],["path",{d:"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7",key:"1ydtos"}],["path",{d:"M7 3v4a1 1 0 0 0 1 1h7",key:"t51u73"}]],W=q("Save",Oe);/**
17 * @license lucide-react v0.475.0 - ISC
18 *
19 * This source code is licensed under the ISC license.
20 * See the LICENSE file in the root directory of this source tree.
21 */const $e=[["polyline",{points:"4 17 10 11 4 5",key:"akl6gq"}],["line",{x1:"12",x2:"20",y1:"19",y2:"19",key:"q2wloq"}]],De=q("Terminal",$e),Be="KJB-DEV-2026",He=o=>{var i;return((i=ee.find(r=>r.apiName===o))==null?void 0:i.shortName)||o},de=o=>{const i=He(o.book);return o.verse===ue?`${i} ${o.chapter} — Superscription/Subscript`:o.verse===pe?`${i} ${o.chapter} — Colophon`:`${i} ${o.chapter}:${o.verse}`};function Ue({onJump:o}){const[i,r]=u.useState([]),[l,g]=u.useState(!0),[y,f]=u.useState(null),m=u.useCallback(async()=>{g(!0);try{const a=await w.entities.BibleTextOverride.list("-updated_date",1e3);r(a)}catch{r([])}g(!1)},[]);u.useEffect(()=>{m()},[m]);const h=async a=>{if(confirm(`Remove the override for ${de(a)}? The original text will be restored for everyone.`)){f(a.id);try{await w.functions.invoke("saveBibleTextOverride",{op:"delete",id:a.id,key:Be}),F(),await K(!0),await m()}catch(p){alert("Revert failed: "+(p.message||"unknown"))}f(null)}};return e.jsxs("div",{className:"rounded-xl bg-card border border-border overflow-hidden",children:[e.jsxs("div",{className:"flex items-center gap-2 px-4 py-3 border-b border-border",children:[e.jsx(Ae,{className:"w-4 h-4 text-primary"}),e.jsxs("span",{className:"font-sans text-sm font-semibold text-foreground",children:["Your edits (",i.length,")"]})]}),l?e.jsx("div",{className:"flex justify-center py-8",children:e.jsx(A,{className:"w-5 h-5 animate-spin text-primary/70"})}):i.length===0?e.jsx("p",{className:"font-sans text-xs text-muted-foreground px-4 py-4",children:"No edits yet. Corrections you save will be listed here."}):e.jsx("div",{children:i.map(a=>e.jsxs("div",{className:"px-4 py-3 border-b border-border last:border-0",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2 mb-1",children:[e.jsx("button",{onClick:()=>o&&o(a.book,a.chapter),className:"font-sans text-xs font-semibold text-accent hover:underline text-left",children:de(a)}),e.jsxs("button",{onClick:()=>h(a),disabled:y===a.id,className:"flex items-center gap-1 px-2 py-1 rounded bg-secondary text-destructive text-xs hover:bg-destructive/10 shrink-0",children:[y===a.id?e.jsx(A,{className:"w-3 h-3 animate-spin"}):e.jsx(z,{className:"w-3 h-3"})," Revert"]})]}),a.note&&e.jsxs("p",{className:"font-sans text-[11px] text-muted-foreground mb-1",children:["Note: ",a.note]}),e.jsx("p",{className:"font-serif text-sm text-foreground leading-snug",children:a.text})]},a.id))})]})}function le(o){return String(o).match(/\s+|\S+/g)||[]}function Pe(o,i){const r=le(o),l=le(i),g=r.length,y=l.length,f=Array.from({length:g+1},()=>new Array(y+1).fill(0));for(let x=g-1;x>=0;x--)for(let j=y-1;j>=0;j--)f[x][j]=r[x]===l[j]?f[x+1][j+1]+1:Math.max(f[x+1][j],f[x][j+1]);const m=[],h=(x,j)=>{const v=m[m.length-1];v&&v.type===x?v.value+=j:m.push({type:x,value:j})};let a=0,p=0;for(;a<g&&p<y;)r[a]===l[p]?(h("equal",r[a]),a++,p++):f[a+1][p]>=f[a][p+1]?(h("removed",r[a]),a++):(h("added",l[p]),p++);for(;a<g;)h("removed",r[a]),a++;for(;p<y;)h("added",l[p]),p++;return m}function ce({original:o,current:i}){const r=Pe(o||"",i||"");return e.jsxs("div",{className:"mt-2 rounded-lg border border-border bg-secondary/40 p-2.5",children:[e.jsx("p",{className:"font-sans text-[11px] font-semibold text-muted-foreground mb-1",children:"Changes"}),e.jsx("p",{className:"font-serif text-sm leading-relaxed text-foreground break-words",children:r.map((l,g)=>l.type==="added"?e.jsx("span",{className:"rounded bg-green-500/25 text-green-700 dark:text-green-300 px-0.5",children:l.value},g):l.type==="removed"?e.jsx("span",{className:"rounded bg-red-500/20 text-red-700 dark:text-red-300 line-through px-0.5",children:l.value},g):e.jsx("span",{children:l.value},g))})]})}const V="KJB-DEV-2026";function Ve(){const[o,i]=u.useState("Genesis"),[r,l]=u.useState(1),[g,y]=u.useState([]),[f,m]=u.useState({}),[h,a]=u.useState({}),[p,x]=u.useState({}),[j,v]=u.useState({}),[b,E]=u.useState(!1),[C,$]=u.useState(null),[H,n]=u.useState(""),[c,d]=u.useState(0),t=ee.find(s=>
21s.apiName===o),D=t?t.chapters:150,_=async()=>{E(!0),n("");try{const s=await w.entities.BibleTextOverride.filter({book:o,chapter:Number(r)}),k={},S={};s.forEach(U=>{U.verse>=1e3?S[U.verse-1e3]=U:k[U.verse]=U}),x(k),v(S);const{verses:I}=await je(o,Number(r)),R=we(o,Number(r)),N=Ne(o,Number(r)),T=ke(o,Number(r)),P=[...R!=null?[{verse:ue,text:R,kind:"subscript"}]:[],...I,...N!=null?[{verse:pe,text:N,kind:"colophon"}]:[],...T!=null?[{verse:Se,text:T,kind:"endmarker"}]:[]];y(P),m({}),a({})}catch(s){n(s.message||"Failed to load")}E(!1)};u.useEffect(()=>{_()},[o,r]);const B=async(s,k)=>{var S;$(s),n("");try{const I=p[s];if(I)await w.functions.invoke("saveBibleTextOverride",{op:"update",id:I.id,text:k,key:V});else{const R=await w.functions.invoke("saveBibleTextOverride",{op:"create",book:o,chapter:Number(r),verse:s,text:k,key:V}),N=(S=R==null?void 0:R.data)==null?void 0:S.record;N&&x(T=>({...T,[s]:N}))}F(),await K(!0),n(`Saved ${t==null?void 0:t.shortName} ${r}:${s} — live for all readers.`),m(R=>{const N={...R};return delete N[s],N}),d(R=>R+1)}catch(I){n("Save failed: "+(I.message||"unknown"))}$(null)},L=async(s,k)=>{var I;const S=ae(s);$(S),n("");try{const R=j[s];if(R)await w.functions.invoke("saveBibleTextOverride",{op:"update",id:R.id,text:k,key:V});else{const N=await w.functions.invoke("saveBibleTextOverride",{op:"create",book:o,chapter:Number(r),verse:S,text:k,key:V}),T=(I=N==null?void 0:N.data)==null?void 0:I.record;T&&v(P=>({...P,[s]:T}))}F(),await K(!0),n(`Saved heading for ${t==null?void 0:t.shortName} ${r}:${s} — live for all readers.`),a(N=>{const T={...N};return delete T[s],T}),d(N=>N+1)}catch(R){n("Heading save failed: "+(R.message||"unknown"))}$(null)},M=async s=>{const k=p[s];if(k&&confirm(`Remove the override for ${t==null?void 0:t.shortName} ${r}:${s}? The original text will be restored for everyone.`)){$(s);try{await w.functions.invoke("saveBibleTextOverride",{op:"delete",id:k.id,key:V}),x(S=>{const I={...S};return delete I[s],I}),F(),await K(!0),await _(),d(S=>S+1),n(`Reverted ${t==null?void 0:t.shortName} ${r}:${s} to original.`)}catch(S){n("Revert failed: "+(S.message||"unknown"))}$(null)}};return e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{className:"rounded-xl bg-card border border-border p-4 space-y-3",children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block font-sans text-xs text-muted-foreground mb-1",children:"Book"}),e.jsx("select",{value:o,onChange:s=>{i(s.target.value),l(1)},className:"w-full px-3 py-2 rounded-lg bg-secondary border border-border text-sm text-foreground",children:ee.map(s=>e.jsx("option",{value:s.apiName,children:s.shortName},s.abbr))})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block font-sans text-xs text-muted-foreground mb-1",children:"Chapter"}),e.jsx("select",{value:r,onChange:s=>l(Number(s.target.value)),className:"w-full px-3 py-2 rounded-lg bg-secondary border border-border text-sm text-foreground",children:Array.from({length:D},(s,k)=>k+1).map(s=>e.jsxs("option",{value:s,children:["Chapter ",s]},s))})]})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Use [brackets] for italic (supplied) words. Saved edits apply to every reader instantly and cost no credits. Psalm superscriptions/subscripts and epistle colophons are editable here too. In Psalm 119, each stanza's Hebrew-letter heading (ALEPH, BETH, …) shows its own editable field above the verse it precedes (verses 1, 9, 17…)."}),H&&e.jsx("p",{className:"text-xs text-primary",children:H})]}),e.jsx(Ue,{onJump:(s,k)=>{i(s),l(Number(k))}},c),b?e.jsx("div",{className:"flex justify-center py-12",children:e.jsx(A,{className:"w-6 h-6 animate-spin text-primary/70"})}):e.jsx("div",{className:"space-y-3",children:g.map(s=>{const k=!!p[s.verse],S=f[s.verse]!=null?f[s.verse]:s.text,I=f[s.verse]!=null&&f[s.verse]!==s.text,R=s.heading!=null||!!j[s.verse],N=s.heading||"",T=h[s.verse]!=null?h[s.verse]:N,P=h[s.verse]!=null&&h[s.verse]!==N,U=C===ae(s.verse);return e.jsxs("div",{className:`rounded-xl border p-3 ${k?"border-primary/50 bg-primary/5":"border-border bg-card"}`,children:[e.jsxs("div",{className:"flex items-center justify-between mb-1.5",children:[e.jsxs("span",{className:"font-sans text-xs font-semibold text-accent",children:[s.kind==="subscript"?`${t==null?void 0:t.shortName} ${r} — Superscription/Subscript`:s.kind==="colophon"?`${t==null?void 0:t.shortName} ${r} — Colophon`:s.kind==="endmarker"?`${t==null?void 0:t.shortName} ${r} — End Marker`:`${t==null?void 0:t.shortName} ${r}:${s.verse}`," ",k&&e.jsx("span",{className:"text-primary",children:"(overridden)"})]}),e.jsxs("div",{className:"flex gap-1.5",children:[k&&e.jsxs("button",{onClick:()=>M(s.verse),disabled:C===s.verse,className:"flex items-center gap-1 px-2 py-1 rounded bg-secondary text-destructive text-xs hover:bg-destructive/10",children:[e.jsx(z,{className:"w-3 h-3"})," Revert"]}),e.jsxs("button",{onClick:()=>B(s.verse,S),disabled:C===s.verse||!I,className:"flex items-center gap-1 px-2 py-1 rounded bg-primary text-primary-foreground text-xs hover:opacity-90 disabled:opacity-40",children:[C===s.verse?e.jsx(A,{className:"w-3 h-3 animate-spin"}):e.jsx(W,{className:"w-3 h-3"})," Save"]})]})]}),R&&e.jsxs("div",{className:"mb-2 rounded-lg border border-accent/40 bg-accent/5 p-2",children:[e.jsxs("div",{className:"flex items-center justify-between mb-1",children:[e.jsx("span",{className:"font-sans text-[11px] font-semibold text-accent",children:"Hebrew-letter heading (above this verse)"}),e.jsxs("button",{onClick:()=>L(s.verse,T),disabled:U||!P,className:"flex items-center gap-1 px-2 py-0.5 rounded bg-accent text-accent-foreground text-[11px] hover:opacity-90 disabled:opacity-40",children:[U?e.jsx(A,{className:"w-3 h-3 animate-spin"}):e.jsx(W,{className:"w-3 h-3"})," Save heading"]})]}),e.jsx("input",{type:"text",value:T,onChange:Y=>a(G=>({...G,[s.verse]:Y.target.value})),placeholder:"e.g. ALEPH",className:"w-full px-3 py-1.5 rounded-lg bg-secondary border border-border text-sm font-serif text-foreground uppercase"}),P&&e.jsx(ce,{original:N,current:T})]}),e.jsx("textarea",{value:S,onChange:Y=>m(G=>({...G,[s.verse]:Y.target.value})),rows:Math.max(2,Math.ceil(S.length/80)),className:"w-full px-3 py-2 rounded-lg bg-secondary border border-border text-sm font-serif text-foreground resize-y"}),I&&e.jsx(ce,{original:s.text,current:S})]},s.verse)})})]})}function We(o){return new Promise((i,r)=>{const l=new Image;l.crossOrigin="anonymous",l.onload=()=>i(l),l.onerror=r,l.src=o})}async function ze(o,i,{maskable:r=!1,bgColor:l="#0f1117"}={}){const g=await We(o),y=document.createElement("canvas");y.width=i,y.height=i;const f=y.getContext("2d");f.fillStyle=l,f.fillRect(0,0,i,i);const m=Math.min(g.width,g.height),h=(g.width-m)/2,a=(g.height-m)/2,x=i*(r?.8:1),j=(i-x)/2;return f.drawImage(g,h,a,m,m,j,j,x,x),await new Promise(v=>y.toBlob(v,"image/png"))}async function Fe(o,i,r){const l=await ze(o,i,r);return new File([l],`icon-${i}${r!=null&&r.maskable?"-maskable":""}.png`,{type:"image/png"})}const me="KJB-DEV-2026",Ke=[{size:192,purpose:"any"},{size:512,purpose:"any"},{size:512,purpose:"maskable"}];function qe(){const[o,i]=u.useState(null),[r,l]=u.useState([]),[g,y]=u.useState(!0),[f,m]=u.useState(""),[h,a]=u.useState(""),[p,x]=u.useState(null),j=u.useRef(null),v=async()=>{var n;y(!0);try{const d=(await w.entities.ManifestConfig.list("-updated_date",1))[0]||null;i(d),l((n=d==null?void 0:d.icons)!=null&&n.length?d.icons:[])}catch(c){a("Load failed: "+(c.message||"unknown"))}y(!1)};u.useEffect(()=>
21{v()},[]);const b=async n=>{var d;const c=(d=n.target.files)==null?void 0:d[0];if(j.current&&(j.current.value=""),!!c){m("Processing icons…"),a("");try{const t=await new Promise((_,B)=>{const L=new FileReader;L.onload=()=>_(L.result),L.onerror=B,L.readAsDataURL(c)}),D=[];for(const _ of Ke){m(`Cropping ${_.size}px ${_.purpose}…`);const B=await Fe(t,_.size,{maskable:_.purpose==="maskable"}),{file_url:L}=await w.integrations.Core.UploadFile({file:B});D.push({src:L,sizes:`${_.size}x${_.size}`,type:"image/png",purpose:_.purpose})}l(D),a("Icons generated & uploaded. Click Save to apply for all users.")}catch(t){a("Icon processing failed: "+(t.message||"unknown"))}m("")}},E=async()=>{var n,c,d;m("Saving…"),a("");try{const t=await w.functions.invoke("saveManifestConfig",{icons:r,key:me});(n=t==null?void 0:t.data)!=null&&n.config&&i(t.data.config),a("Saved. The manifest will serve these icons — republish/clear cache to see them install.")}catch(t){a("Save failed: "+(((d=(c=t==null?void 0:t.response)==null?void 0:c.data)==null?void 0:d.error)||t.message||"unknown"))}m("")},C=async()=>{var n,c;if(!o){a("Already using built-in default icons.");return}if(confirm("Remove custom icons and revert the manifest to the built-in defaults?")){m("Reverting…");try{await w.functions.invoke("saveManifestConfig",{revert:!0,key:me}),i(null),l([]),a("Reverted to default icons.")}catch(d){a("Revert failed: "+(((c=(n=d==null?void 0:d.response)==null?void 0:n.data)==null?void 0:c.error)||d.message||"unknown"))}m("")}},$=async()=>{m("Testing manifest…"),x(null),a("");try{const c=await(await fetch("/functions/manifest",{cache:"no-store"})).json(),d=[],t=(M,s)=>d.push({ok:M,label:s});t(!!c.name,"Has name"),t(!!c.short_name,"Has short_name"),t(c.start_url==="/",'start_url is "/"'),t(c.display==="standalone","display is standalone"),t(Array.isArray(c.icons)&&c.icons.length>0,"Has icons");const D=(c.icons||[]).some(M=>/(^|\s)192x192/.test(M.sizes)&&(M.purpose||"any").includes("any"));t(D,'Has ≥192px "any" icon');const _=(c.icons||[]).some(M=>(M.purpose||"").includes("maskable"));t(_,"Has maskable icon");const B=(c.icons||[]).some(M=>/512x512/.test(M.sizes));t(B,"Has 512px icon"),t(!!c.theme_color,"Has theme_color"),t(!!c.background_color,"Has background_color");const L=(c.screenshots||[]).some(M=>M.form_factor==="narrow");t(L,"Has narrow screenshot"),x({checks:d,raw:c})}catch(n){a("Test failed: "+(n.message||"unknown"))}m("")},H=r.length?r:null;return e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{className:"rounded-xl bg-card border border-border p-4 space-y-3",children:[e.jsx("p",{className:"font-sans text-sm font-semibold text-foreground",children:"Manifest icons"}),e.jsx("p",{className:"font-sans text-xs text-muted-foreground",children:`Upload one square-ish source image. It's auto-cropped & padded into the required sizes (192/512 "any" + 512 maskable with a safe zone), uploaded, then saved so the live manifest serves them.`}),e.jsx("input",{ref:j,type:"file",accept:"image/*",onChange:b,className:"hidden"}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs("button",{onClick:()=>{var n;return(n=j.current)==null?void 0:n.click()},disabled:!!f,className:"flex items-center gap-2 px-4 py-2 rounded-lg bg-primary text-primary-foreground text-sm font-medium hover:opacity-90 disabled:opacity-50",children:[e.jsx(se,{className:"w-4 h-4"})," Upload & Auto-Crop"]}),e.jsxs("button",{onClick:E,disabled:!!f||!r.length,className:"flex items-center gap-2 px-4 py-2 rounded-lg bg-secondary text-foreground text-sm font-medium hover:bg-accent/20 disabled:opacity-50",children:[e.jsx(W,{className:"w-4 h-4"})," Save"]}),e.jsxs("button",{onClick:C,disabled:!!f,className:"flex items-center gap-2 px-4 py-2 rounded-lg bg-secondary text-destructive text-sm font-medium hover:bg-destructive/10 disabled:opacity-50",children:[e.jsx(z,{className:"w-4 h-4"})," Revert to defaults"]})]}),f&&e.jsxs("p",{className:"text-xs text-primary flex items-center gap-1.5",children:[e.jsx(A,{className:"w-3.5 h-3.5 animate-spin"})," ",f]}),h&&e.jsx("p",{className:"text-xs text-primary",children:h})]}),g?e.jsx("div",{className:"flex justify-center py-8",children:e.jsx(A,{className:"w-6 h-6 animate-spin text-primary/70"})}):e.jsxs("div",{className:"rounded-xl bg-card border border-border p-4",children:[e.jsx("p",{className:"font-sans text-xs text-muted-foreground mb-3",children:H?"Current custom icons:":"Using built-in default icons (no custom set saved)."}),H&&e.jsx("div",{className:"grid grid-cols-2 sm:grid-cols-3 gap-4",children:H.map((n,c)=>{var d;return e.jsxs("div",{className:"flex flex-col items-center gap-2",children:[e.jsx("div",{className:"w-24 h-24 bg-secondary/40 border border-border flex items-center justify-center overflow-hidden",style:{borderRadius:(d=n.purpose)!=null&&d.includes("maskable")?"9999px":"1rem"},children:e.jsx("img",{src:n.src,alt:n.sizes,className:"w-full h-full object-contain"})}),e.jsxs("p",{className:"text-[11px] text-muted-foreground",children:[n.sizes," · ",n.purpose]})]},c)})})]}),e.jsxs("div",{className:"rounded-xl bg-card border border-border p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("p",{className:"font-sans text-sm font-semibold text-foreground",children:"Test manifest"}),e.jsx("button",{onClick:$,disabled:!!f,className:"px-3 py-1.5 rounded-lg bg-primary text-primary-foreground text-xs font-medium hover:opacity-90 disabled:opacity-50",children:"Run checks"})]}),p&&e.jsxs("div",{className:"space-y-1.5",children:[p.checks.map((n,c)=>e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[n.ok?e.jsx(te,{className:"w-4 h-4 text-green-600"}):e.jsx(J,{className:"w-4 h-4 text-amber-600"}),e.jsx("span",{className:n.ok?"text-foreground":"text-amber-600 font-medium",children:n.label})]},c)),e.jsxs("details",{className:"mt-2",children:[e.jsx("summary",{className:"text-xs text-muted-foreground cursor-pointer",children:"View raw manifest"}),e.jsx("pre",{className:"mt-2 text-[10px] bg-secondary rounded-lg p-3 overflow-x-auto max-h-64",children:JSON.stringify(p.raw,null,2)})]})]})]})]})}const O={chrome:"https://chromewebstore.google.com/detail/kjb-reader-sidepanel/gbnipepkpenjgdpjfepgcgddmgbofmah",edge:"https://microsoftedge.microsoft.com/addons/detail/kjb-reader-sidepanel/bphmmbiepbhfnfijaapbmpimkkjdceee",firefox:"https://base44.app/api/apps/6a713d810d97fdb5921ed14e/files/mp/public/6a713d810d97fdb5921ed14e/580bbb860_kjb-reader-v04138-firefox.zip",opera:"https://base44.app/api/apps/6a713d810d97fdb5921ed14e/files/mp/public/6a713d810d97fdb5921ed14e/0889d0997_kjb-reader-v04138-opera.zip",version:"v0.4.138",show_instructions:!0},Je=[{key:"version",label:"Version label",placeholder:"v0.4.138"},{key:"chrome",label:"Chrome download URL",placeholder:O.chrome},{key:"edge",label:"Edge download URL",placeholder:O.edge},{key:"firefox",label:"Firefox download URL",placeholder:O.firefox},{key:"opera",label:"Opera download URL",placeholder:O.opera}];function Ye(){const[o,i]=u.useState(null),[r,l]=u.useState(O),[g,y]=u.useState(!0),[f,m]=u.useState(!1),[h,a]=u.useState(""),p=async()=>{y(!0);try{const b=(await w.entities.ExtensionConfig.list("-updated_date",1))[0]||null;i(b),l({chrome:(b==null?void 0:b.chrome)||O.chrome,edge:(b==null?void 0:b.edge)||O.edge,firefox:(b==null?void 0:b.firefox)||O.firefox,opera:(b==null?void 0:b.opera)||O.opera,version:(b==null?void 0:b.version)||O.version,show_instructions:(b==null?void 0:b.show_instructions)!==!1})}catch(v){a("Load failed: "+(v.message||"unknown"))}y(!1)};u.useEffect(()=>{p()},[]);const x=async()=>{var v,b,E;m(!0),a("");try{const C=await w.functions.invoke("saveExtensionConfig",r);(v=C==null?void 0:C.data)!=null&&v.config&&i(C.data.config),a("Saved. The /extension page will use these links for all users.")}catch(C){a("Save failed: "+(((E=(b=C==null?void 0:C.response)==null?void 0:b.data)==null?void 0:E.error)||C.message||"unknown"))}m(!1)},j=async()=>{var v,b;if(confirm("Remove the saved config and revert /extension to the built-in defaults?")){m(!0),a("");try{await w.functions.invoke("saveExtensionConfig",{revert:!0}),i(null),l(O),a("Reverted to defaults.")}catch(E){a("Revert failed: "+(((b=(v=E==null?void 0:E.response)==null?void 0:v.data)==null?void 0:b.error)||E.message||"unknown"))}m(!1)}};return g?e.jsx("div",{className:"flex justify-center py-8",children:e.jsx(A,{className:"w-6 h-6 animate-spin text-primary/70"})}):e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"rounded-xl bg-card border border-border p-4 space-y-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-sans text-sm font-semibold text-foreground",children:"Extension download links"}),e.jsxs("p",{className:"font-sans text-xs text-muted-foreground mt-1",children:["These URLs power the download buttons on the ",e.jsx("code",{className:"px-1 py-0.5 rounded bg-secondary text-foreground",children:"/extension"})," page. Leave a field blank to fall back to the built-in default."]})]}),e.jsx("div",{className:"space-y-3",children:Je.map(v=>e.jsxs("div",{className:"space-y-1",children:[e.jsx("label",{className:"font-sans text-xs font-medium text-foreground",children:v.label}),e.jsx("input",{type:"text",value:r[v.key],placeholder:v.placeholder,onChange:b=>l(E=>({...E,[v.key]:b.target.value})),className:"w-full px-3 py-2 rounded-lg bg-background border border-border text-sm text-foreground focus:border-accent outline-none"})]},v.key))}),e.jsxs("div",{className:"flex items-center justify-between gap-4 pt-1",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-sans text-sm font-medium text-foreground",children:"Show installation instructions"}),e.jsx("p",{className:"font-sans text-xs text-muted-foreground",children:"Display the step-by-step install guide on /extension"})]}),e.jsx(he,{checked:r.show_instructions,onCheckedChange:v=>l(b=>({...b,show_instructions:v})),className:"shrink-0"})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs("button",{onClick:x,disabled:f,className:"flex items-center gap-2 px-4 py-2 rounded-lg bg-primary text-primary-foreground text-sm font-medium hover:opacity-90 disabled:opacity-50",children:[e.jsx(W,{className:"w-4 h-4"})," Save"]}),e.jsxs("button",{onClick:j,disabled:f,className:"flex items-center gap-2 px-4 py-2 rounded-lg bg-secondary text-destructive text-sm font-medium hover:bg-destructive/10 disabled:opacity-50",children:[e.jsx(z,{className:"w-4 h-4"})," Revert to defaults"]}),e.jsxs("a",{href:"/extension",target:"_blank",rel:"noopener noreferrer",className:"flex items-center gap-2 px-4 py-2 rounded-lg bg-secondary text-foreground text-sm font-medium hover:bg-accent/20",children:[e.jsx(Ce,{className:"w-4 h-4"})," View page"]})]}),f&&e.jsxs("p",{className:"text-xs text-primary flex items-center gap-1.5",children:[e.jsx(A,{className:"w-3.5 h-3.5 animate-spin"})," Saving…"]}),h&&e.jsxs("p",{className:`text-xs flex items-center gap-1.5 ${h.startsWith("Save failed")||h.startsWith("Revert failed")||h.startsWith("Load failed")?"text-destructive":"text-primary"}`,children:[h.startsWith("Save failed")||h.startsWith("Revert failed")||h.startsWith("Load failed")?e.jsx(J,{className:"w-3.5 h-3.5"}):e.jsx(te,{className:"w-3.5 h-3.5"}),h]})]}),e.jsx("div",{className:"rounded-xl bg-card border border-border p-4",children:e.jsx("p",{className:"font-sans text-xs text-muted-foreground",children:o?"A custom config is saved and live on /extension.":"No custom config saved — /extension is using the built-in defaults."})})]})}const X="https://base44.app/api/apps/6a713d810d97fdb5921ed14e/files/mp/public/6a713d810d97fdb5921ed14e/679d87279_icon128.png",Q=[{src:"https://media.base44.com/images/public/6a8011c360ff52dad38eb2f3/426f5c30f_Screenshot2026-08-16012745.png",label:"Results"},{src:"https://media.base44.com/images/public/6a8011c360ff52dad38eb2f3/2d3c47491_Screenshot2026-08-16012601.png",label:"Read"},{src:"https://media.base44.com/images/public/6a8011c360ff52dad38eb2f3/64c3a9b7b_Screenshot2026-08-16012624.png",label:"Gospel"},{src:"https://media.base44.com/images/public/6a8011c360ff52dad38eb2f3/6ed4814da_Screenshot2026-08-16012656.png",label:"Resources"}];function Ge(){const[o,i]=u.useState(null),[r,l]=u.useState(X),[g,y]=u.useState(Q),[f,m]=u.useState(!0),[h,a]=u.useState(""),[p,x]=u.useState(""),j=u.useRef(null),v=u.useRef([]),b=async()=>{var n;m(!0);try{const d=(await w.entities.ExtensionConfig.list("-updated_date",1))[0]||null;i(d),l((d==null?void 0:d.hero_icon)||X),y((n=d==null?void 0:d.mockups)!=null&&n.length?d.mockups:Q)}catch(c){x("Load failed: "+(c.message||"unknown"))}m(!1)};u.useEffect(()=>{b()},[]);const E=async n=>{var d;const c=(d=n.target.files)==null?void 0:d[0];if(j.current&&(j.current.value=""),!!c){a("Uploading hero icon…"),x("");try{const{file_url:t}=await w.integrations.Core.UploadFile({file:c});l(t),x("Hero icon uploaded. Click Save to apply.")}catch(t){x("Upload failed: "+(t.message||"unknown"))}a("")}},C=async(n,c)=>{var t;const d=(t=c.target.files)==null?void 0:t[0];if(v.current[n]&&(v.current[n].value=""),!!d){a(`Uploading ${g[n].label}…`),x("");try{const{file_url:D}=await w.integrations.Core.UploadFile({file:d});y(_=>_.map((B,L)=>L===n?{...B,src:D}:B)),x("Image uploaded. Click Save to apply.")}catch(D){x("Upload failed: "+(D.message||"unknown"))}a("")}},$=async()=>{var n,c,d;a("Saving…"),x("");try{const t=await w.functions.invoke("saveExtensionConfig",{hero_icon:r,mockups:g});(n=t==null?void 0:t.data)!=null&&n.config&&i(t.data.config),x("Saved. The /extension page will use these images for all users.")}catch(t){x("Save failed: "+(((d=(c=t==null?void 0:t.response)==null?void 0:c.data)==null?void 0:d.error)||t.message||"unknown"))}a("")},H=async()=>{var n,c;if(confirm("Remove the saved images and revert /extension to the built-in defaults?")){a("Reverting…"),x("");try{await w.functions.invoke("saveExtensionConfig",{hero_icon:"",mockups:[]}),l(X),y(Q),x("Reverted to default images.")}catch(d){x("Revert failed: "+(((c=(n=d==null?void 0:d.response)==null?void 0:n.data)==null?void 0:c.error)||d.message||"unknown"))}a("")}};return f?e.jsx("div",{className:"flex justify-center py-8",children:e.jsx(A,{className:"w-6 h-6 animate-spin text-primary/70"})}):e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"rounded-xl bg-card border border-border p-4 space-y-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-sans text-sm font-semibold text-foreground",children:"Hero icon"}),e.jsx("p",{className:"font-sans text-xs text-muted-foreground mt-1",children:"Shown at the top of the /extension page."})]}),e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsx("img",{src:r,alt:"Hero icon",className:"w-16 h-16 rounded-2xl border border-border object-cover"}),e.jsx("input",{ref:j,type:"file",accept:"image/*",onChange:E,className:"hidden"}),e.jsxs("button",{onClick:()=>{var n;return(n=j.current)==null?void 0:n.click()},disabled:!!h,className:"flex items-center gap-2 px-4 py-2 rounded-lg bg-primary text-primary-foreground text-sm font-medium hover:opacity-90 disabled:opacity-50",children:[e.jsx(se,{className:"w-4 h-4"})," Upload"]})]})]}),e.jsxs("div",{className:"rounded-xl bg-card border border-border p-4 space-y-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-sans text-sm font-semibold text-foreground",children:"Sidebar preview mockups"}),e.jsx("p",{className:"font-sans text-xs text-muted-foreground mt-1",children:'The 4 screenshots shown in "See It In Action" on /extension.'})]}),e.jsx("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-4",children:g.map((n,c)=>e.jsxs("div",{className:"flex flex-col items-center gap-2",children:[e.jsx("img",{src:n.src,alt:n.label,className:"w-full aspect-[9/16] object-cover rounded-lg border border-border bg-secondary/40"}),e.jsx("p",{className:"text-xs font-medium text-foreground",children:n.label}),e.jsx("input",{ref:d=>v.current[c]=d,type:"file",accept:"image/*",onChange:d=>C(c,d),className:"hidden"}),e.jsxs("button",{onClick:()=>{var d;return(d=v.current[c])==null?void 0:d.click()},disabled:!!h,className:"flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-secondary text-foreground text-xs font-medium hover:bg-accent/20 disabled:opacity-50",children:[e.jsx(se,{className:"w-3.5 h-3.5"})," Replace"]})]},c))})]}),e.jsxs("div",{className:"flex flex-
21wrap gap-2",children:[e.jsxs("button",{onClick:$,disabled:!!h,className:"flex items-center gap-2 px-4 py-2 rounded-lg bg-primary text-primary-foreground text-sm font-medium hover:opacity-90 disabled:opacity-50",children:[e.jsx(W,{className:"w-4 h-4"})," Save"]}),e.jsxs("button",{onClick:H,disabled:!!h,className:"flex items-center gap-2 px-4 py-2 rounded-lg bg-secondary text-destructive text-sm font-medium hover:bg-destructive/10 disabled:opacity-50",children:[e.jsx(z,{className:"w-4 h-4"})," Revert to defaults"]})]}),h&&e.jsxs("p",{className:"text-xs text-primary flex items-center gap-1.5",children:[e.jsx(A,{className:"w-3.5 h-3.5 animate-spin"})," ",h]}),p&&e.jsxs("p",{className:`text-xs flex items-center gap-1.5 ${p.startsWith("Save failed")||p.startsWith("Revert failed")||p.startsWith("Load failed")||p.startsWith("Upload failed")?"text-destructive":"text-primary"}`,children:[p.startsWith("Save failed")||p.startsWith("Revert failed")||p.startsWith("Load failed")||p.startsWith("Upload failed")?e.jsx(J,{className:"w-3.5 h-3.5"}):e.jsx(te,{className:"w-3.5 h-3.5"}),p]})]})}class Xe extends fe.Component{constructor(i){super(i),this.state={error:null}}static getDerivedStateFromError(i){return{error:i}}componentDidUpdate(i){i.resetKey!==this.props.resetKey&&this.state.error&&this.setState({error:null})}render(){var i;if(this.state.error){const r=((i=this.state.error)==null?void 0:i.message)||String(this.state.error),l=/dynamically imported module|Failed to fetch|Importing a module script failed|ChunkLoadError/i.test(r);return e.jsx("div",{className:"rounded-xl bg-destructive/10 border border-destructive/40 p-4",children:e.jsxs("div",{className:"flex items-start gap-2 text-destructive",children:[e.jsx(J,{className:"w-5 h-5 shrink-0 mt-0.5"}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"font-sans text-sm font-semibold",children:"This tool failed to load."}),l?e.jsx("p",{className:"font-sans text-xs mt-1 opacity-90",children:"The app was updated. Reload to load the latest version."}):e.jsx("p",{className:"font-sans text-xs mt-1 break-words opacity-90",children:r}),e.jsx("button",{onClick:()=>window.location.reload(),className:"mt-3 px-3 py-1.5 rounded-lg bg-destructive text-destructive-foreground text-xs font-medium hover:opacity-90",children:"Reload"})]})]})})}return this.props.children}}const Qe=({className:o})=>e.jsxs("svg",{className:o,viewBox:"0 0 24 24",fill:"currentColor",children:[e.jsx("path",{d:"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"}),e.jsx("path",{d:"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"}),e.jsx("path",{d:"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"}),e.jsx("path",{d:"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"})]});function Ze(){const[o,i]=u.useState(""),[r,l]=u.useState(""),[g,y]=u.useState(""),[f,m]=u.useState(!1),h=async p=>{p.preventDefault(),y(""),m(!0);try{await w.auth.loginViaEmailPassword(o,r),window.location.href="/dev-tools"}catch(x){y(x.message||"Invalid email or password"),m(!1)}},a=()=>{w.auth.loginWithProvider("google","/dev-tools")};return e.jsx("div",{className:"min-h-screen flex items-center justify-center px-5 py-10",children:e.jsxs("div",{className:"w-full max-w-sm",children:[e.jsxs("div",{className:"text-center mb-6",children:[e.jsx("div",{className:"inline-flex items-center justify-center w-14 h-14 rounded-2xl bg-gradient-to-br from-slate-600 to-slate-800 shadow-lg shadow-slate-500/30 mb-4",children:e.jsx(xe,{className:"w-7 h-7 text-white"})}),e.jsx("h1",{className:"font-serif text-2xl font-bold text-foreground mb-1",children:"Dev Tools"}),e.jsxs("p",{className:"font-sans text-xs text-muted-foreground flex items-center justify-center gap-1.5",children:[e.jsx(Re,{className:"w-3.5 h-3.5"}),"Admin sign-in required"]})]}),e.jsxs("div",{className:"bg-card/70 backdrop-blur-xl border border-border/60 rounded-2xl p-6 shadow-lg shadow-black/[0.03]",children:[e.jsxs(re,{variant:"outline",className:"w-full h-12 text-sm font-medium mb-4",onClick:a,children:[e.jsx(Qe,{className:"w-5 h-5 mr-2"}),"Continue with Google"]}),e.jsxs("div",{className:"relative mb-4",children:[e.jsx("div",{className:"absolute inset-0 flex items-center",children:e.jsx("div",{className:"w-full border-t border-border"})}),e.jsx("div",{className:"relative flex justify-center text-xs uppercase",children:e.jsx("span",{className:"bg-card px-3 text-muted-foreground",children:"or"})})]}),g&&e.jsx("div",{className:"mb-4 p-3 rounded-lg bg-destructive/10 text-destructive text-sm",children:g}),e.jsxs("form",{onSubmit:h,className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(ne,{htmlFor:"dev-email",children:"Email"}),e.jsxs("div",{className:"relative",children:[e.jsx(Ee,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground","aria-hidden":"true"}),e.jsx(oe,{id:"dev-email",type:"email",autoComplete:"email",autoFocus:!0,placeholder:"[email protected]",value:o,onChange:p=>i(p.target.value),className:"pl-10 h-12",required:!0})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(ne,{htmlFor:"dev-password",children:"Password"}),e.jsxs("div",{className:"relative",children:[e.jsx(_e,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground","aria-hidden":"true"}),e.jsx(oe,{id:"dev-password",type:"password",autoComplete:"current-password",placeholder:"••••••••",value:r,onChange:p=>l(p.target.value),className:"pl-10 h-12",required:!0})]})]}),e.jsx(re,{type:"submit",className:"w-full h-12 font-medium",disabled:f,children:f?e.jsxs(e.Fragment,{children:[e.jsx(A,{className:"w-4 h-4 mr-2 animate-spin"}),"Signing in..."]}):"Sign in"})]})]})]})})}const Z=`I have a Capacitor 6 project (React PWA) with an existing android/ folder for an app called "KJB Reader" (appId: com.kingjamesbiblereader.twa). I need you to fully regenerate the native Android shell.
22
23Context:
24- The web app itself is untouched — only capacitor.config.ts, package.json, and the android/ native project change.
25- @capacitor/push-notifications and web-push have already been removed from package.json; @capacitor/share has been added.
26- capacitor.config.ts server.url must stay "https://kingjamesbiblereader.com" (remote-URL mode, not a bundled build).
27- appId MUST remain "com.kingjamesbiblereader.twa" (Play Store package name — do not change).
28
29Steps:
301. Delete the existing android/ folder entirely.
312. Run \`npx cap add android\` to regenerate a fresh native Android project from the current capacitor.config.ts and installed plugins.
323. Run \`npx cap sync android\`.
334. Re-apply these customizations to the freshly generated project (they existed before and must be preserved):
34   a. capacitor.config.ts: appId "com.kingjamesbiblereader.twa", appName "KJB Reader", server.url "https://kingjamesbiblereader.com", cleartext: false, allowNavigation list for OAuth hosts (accounts.google.com, accounts.youtube.com, oauth.googleusercontent.com, appleid.apple.com, apple.com, *.apple.com, icloud.com, *.icloud.com, github.com, *.github.com, login.microsoftonline.com, facebook.com, *.facebook.com, base44.com, *.base44.com), android.allowMixedContent: false. Do NOT add a PushNotifications plugin block.
35   b. android/app/src/main/java/com/kingjamesbiblereader/twa/MainActivity.java: keep it extending BridgeActivity, with the existing onCreate() logic — enable 3rd-party cookies via CookieManager, and set a custom WebChromeClient subclassing BridgeWebChromeClient that overrides onCreateWindow() to load OAuth popups (window.open) in the same WebView instead of escaping to Chrome (transport.setWebView(view); resultMsg.sendToTarget(); return true).
36   c. Add an Android Share Target: in AndroidManifest.xml add an <intent-filter> on MainActivity for android.intent.action.SEND with mimeType text/plain, so KJB Reader appears in the Android share sheet when a user selects text in another app.
37   d. In MainActivity.java (package com.kingjamesbiblereader.twa), add a handler (called from onCreate via getIntent(), and from an overridden onNewIntent()) that: checks if the incoming Intent action is Intent.ACTION_SEND with type "text/plain", reads Intent.EXTRA_TEXT, builds the URL "https://kingjamesbiblereader.com/search?q=" + Uri.encode(sharedText), and loads it in the WebView (getBridge().getWebView().loadUrl(url) on cold start via onCreate, or the same call in onNewIntent for a running instance). Call setIntent(intent) inside onNewIntent since launchMode is singleTask.
38   e. android/app/build.gradle: remove the try/catch block that conditionally applies the com.google.gms.google-services plugin based on google-services.json (push notifications are gone, so this FCM setup is no longer needed).
39   f. Confirm android/app/build.gradle keeps applicationId "com.kingjamesbiblereader.twa" (and namespace matching), the same signingConfigs.release block reading ANDROID_KEY
39STORE_PATH / ANDROID_KEYSTORE_PASSWORD / ANDROID_KEY_ALIAS / ANDROID_KEY_PASSWORD from environment variables, and buildTypes.release using that signingConfig.
40   g. Confirm the AndroidManifest.xml keeps the FileProvider <provider> block and the INTERNET permission.
415. Run a release build (\`./gradlew assembleRelease\` or \`bundleRelease\`) with the CI keystore env vars set, and confirm it compiles and installs, still loading kingjamesbiblereader.com in the WebView, with the OAuth popup behavior and the new Share Target intact.
42
43Do not change the applicationId, do not switch server.url to a bundled local build, and do not reintroduce push-notifications or google-services.`;function es(){const[o,i]=u.useState(!1),r=async()=>{try{await navigator.clipboard.writeText(Z)}catch{const l=document.createElement("textarea");l.value=Z,l.style.position="fixed",l.style.opacity="0",document.body.appendChild(l),l.select(),document.execCommand("copy"),document.body.removeChild(l)}i(!0),setTimeout(()=>i(!1),2e3)};return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-3 gap-3",children:[e.jsx("h2",{className:"font-serif text-lg font-bold text-foreground",children:"Android Rebuild Prompt (for Claude)"}),e.jsxs("button",{onClick:r,className:`flex items-center gap-1.5 px-3.5 py-2 rounded-lg text-sm font-medium transition-colors shrink-0 ${o?"bg-green-600 text-white":"bg-primary text-primary-foreground hover:opacity-90"}`,children:[o?e.jsx(ge,{className:"w-4 h-4"}):e.jsx(be,{className:"w-4 h-4"}),o?"Copied!":"Copy"]})]}),e.jsx("pre",{className:"whitespace-pre-wrap break-words font-sans text-xs leading-relaxed text-foreground bg-secondary rounded-lg p-4 max-h-[60vh] overflow-y-auto",children:Z})]})}const ss=[{id:"text",label:"Edit Bible Text",icon:ye},{id:"manifest",label:"Manifest & Icons",icon:Ie},{id:"links",label:"Extension Links",icon:ie},{id:"images",label:"Extension Images",icon:ie},{id:"prompts",label:"Android Prompt",icon:De}];function hs(){const[o,i]=u.useState("text"),[r,l]=u.useState(()=>{try{return localStorage.getItem("kjb-debug-recorder")==="true"}catch{return!1}}),{user:g,isLoadingAuth:y}=ve();if(y)return e.jsx("div",{className:"min-h-screen flex items-center justify-center",children:e.jsx(A,{className:"w-6 h-6 animate-spin text-primary/70"})});if(!g||g.role!=="admin")return e.jsx(Ze,{});const f=()=>{w.auth.logout("/dev-tools")};return e.jsxs("div",{className:"w-full max-w-4xl mx-auto px-5 sm:px-8 py-8 pb-24",children:[e.jsxs("div",{className:"flex items-center justify-between mb-1 gap-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(xe,{className:"w-5 h-5 text-primary"}),e.jsx("h1",{className:"font-serif text-2xl font-bold text-foreground",children:"Dev Tools"})]}),e.jsxs("button",{onClick:f,className:"flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-secondary text-foreground hover:bg-accent/20 text-xs font-medium transition-colors",children:[e.jsx(Me,{className:"w-3.5 h-3.5"}),"Sign out"]})]}),e.jsxs("p",{className:"font-sans text-xs text-muted-foreground mb-6",children:["Signed in as ",g.email||g.full_name||"admin"," · Private admin utilities."]}),e.jsxs("div",{className:"flex items-center justify-between gap-4 mb-6 p-3 rounded-xl bg-secondary/60 border border-border",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-sans text-sm font-medium text-foreground",children:"Debug Recorder"}),e.jsx("p",{className:"font-sans text-xs text-muted-foreground",children:"Shows a floating Rec button in the app. Start it, reproduce the issue, stop it, then copy or download the log to send for analysis."})]}),e.jsx("button",{onClick:()=>{try{const m=localStorage.getItem("kjb-debug-recorder")!=="true";localStorage.setItem("kjb-debug-recorder",String(m)),window.dispatchEvent(new Event("kjb-debug-recorder-change")),l(m)}catch{}},className:`px-3.5 py-2 rounded-lg text-xs font-medium transition-colors ${r?"bg-primary text-primary-foreground":"bg-secondary text-foreground hover:bg-accent/20"}`,children:r?"On":"Off"})]}),e.jsx("div",{className:"flex flex-wrap gap-2 mb-6",children:ss.map(m=>{const h=m.icon,a=o===m.id;return e.jsxs("button",{onClick:()=>i(m.id),className:`flex items-center gap-1.5 px-3.5 py-2 rounded-lg text-sm font-medium transition-colors ${a?"bg-primary text-primary-foreground":"bg-secondary text-foreground hover:bg-accent/20"}`,children:[e.jsx(h,{className:"w-4 h-4"})," ",m.label]},m.id)})}),e.jsxs(Xe,{resetKey:o,children:[o==="text"&&e.jsx(Ve,{}),o==="manifest"&&e.jsx(qe,{}),o==="links"&&e.jsx(Ye,{}),o==="images"&&e.jsx(Ge,{}),o==="prompts"&&e.jsx(es,{})]})]})}export{hs as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.