1var st=Object.defineProperty;var at=(d,r,s)=>r in d?st(d,r,{enumerable:!0,configurable:!0,writable:!0,value:s}):d[r]=s;var b=(d,r,s)=>at(d,typeof r!="symbol"?r+"":r,s);import{c as qe,Y as nt,r as o,s as R,u as P,j as e,v as K,m as W,n as $,o as Y,p as X,q as he,B as k,b as G,I as ee,a as Ae,aa as it}from"./index-Ct8eLu1I.js";import{S as ct}from"./switch-BivgU5Jr.js";import{S as ot}from"./slider-7jwSdK_r.js";import{T as lt,a as dt,b as fe,c as pe}from"./tabs-BxjRtXE_.js";import{c as te,n as Ue}from"./normalizeEpc-DqujmFKo.js";import{T as Me}from"./triangle-alert-DJpcx1Nd.js";import{V as mt}from"./volume-2-D1GY6zle.js";import{R as ut}from"./radio-tsTiTjcV.js";import{U as ht}from"./user-check-BwC8fXcP.js";import{L as ft}from"./layers-DmHX825Z.js";/** 2 * @license lucide-react v0.462.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 ge=qe("PlugZap",[["path",{d:"M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6-2.3 2.3a2.4 2.4 0 0 0 0 3.4Z",key:"goz73y"}],["path",{d:"m2 22 3-3",key:"19mgm9"}],["path",{d:"M7.5 13.5 10 11",key:"7xgeeb"}],["path",{d:"M10.5 16.5 13 14",key:"10btkg"}],["path",{d:"m18 3-4 4h6l-4 4",key:"16psg9"}]]);/** 7 * @license lucide-react v0.462.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 pt=qe("Usb",[["circle",{cx:"10",cy:"7",r:"1",key:"dypaad"}],["circle",{cx:"4",cy:"20",r:"1",key:"22iqad"}],["path",{d:"M4.7 19.3 19 5",key:"1enqfc"}],["path",{d:"m21 3-3 1 2 2Z",key:"d3ov82"}],["path",{d:"M9.26 7.68 5 12l2 5",key:"1esawj"}],["path",{d:"m10 14 5 2 3.5-3.5",key:"v8oal5"}],["path",{d:"m18 12 1-1 1 1-1 1Z",key:"1bh22v"}]]),gt=[{vendorId:1256,productId:8420},{vendorId:4292,productId:6e4}],Le=0,xt=3,bt=7,wt=30;function yt(d=8,r="none",s=1){const a=r==="none"?0:r==="odd"?1:2,i=s===1?0:2;return(d&255)<<8|a<<4|i}function vt(d){const r=new Uint8Array(4);return new DataView(r.buffer).setUint32(0,d>>>0,!0),r}function Oe(){return typeof navigator<"u"&&"usb"in navigator}class xe{constructor(r){b(this,"readable",null);b(this,"writable",null);b(this,"iface",0);b(this,"epIn",1);b(this,"epOut",1);b(this,"packet",64);b(this,"open_",!1);this.device=r}static async request(){if(!Oe())throw new Error("This browser does not support USB direct. Use Chrome or Edge.");const r=await navigator.usb.requestDevice({filters:gt});return new xe(r)}ctrl(r,s,a){return this.device.controlTransferOut({requestType:"vendor",recipient:"interface",request:r,value:s,index:this.iface},a)}async open(r){const s=this.device;try{await s.open(),s.configuration||await s.selectConfiguration(1);const i=s.configuration.interfaces[0];this.iface=i.interfaceNumber,await s.claimInterface(this.iface);for(const c of i.alternate.endpoints)c.type==="bulk"&&(c.direction==="in"?(this.epIn=c.endpointNumber,this.packet=c.packetSize||64):this.epOut=c.endpointNumber)}catch(i){const c=i.message||"";throw/access denied|unable to claim|SecurityError/i.test(c)||i.name==="SecurityError"?new Error('Windows has the reader locked to another driver. Run the one-time USB driver setup (see "USB direct setup" on this page), then unplug and replug the reader.'):i}await this.ctrl(Le,1),await this.ctrl(wt,0,vt(r.baudRate)),await this.ctrl(xt,yt(r.dataBits??8,r.parity??"none",r.stopBits??1)),await this.ctrl(bt,771),this.open_=!0;const a=this;this.readable=new ReadableStream({async pull(i){for(;a.open_;)try{const c=await s.transferIn(a.epIn,a.packet*4);if(c.data&&c.data.byteLength>0){i.enqueue(new Uint8Array(c.data.buffer,c.data.byteOffset,c.data.byteLength).slice());return}}catch(c){a.open_?i.error(c):i.close();return}i.close()},cancel(){a.open_=!1}}),this.writable=new WritableStream({async write(i){await s.transferOut(a.epOut,i)}})}async close(){this.open_=!1;try{await this.ctrl(Le,0)}catch{}try{await this.device.releaseInterface(this.iface)}catch{}try{await this.device.close()}catch{}this.readable=null,this.writable=null}}const We=160,jt=255,I={REAL_TIME_INVENTORY:137,READ_MEMORY:129,WRITE_MEMORY:130,SET_ACCESS_EPC_MATCH:133,SET_OUTPUT_POWER:118,GET_OUTPUT_POWER:119,BUZZER:122},Nt={RESERVED:0,EPC:1,TID:2,USER:3};function $e(){return typeof navigator<"u"&&"serial"in navigator}
11function J(d){return Array.from(d).map(r=>r.toString(16).padStart(2,"0").toUpperCase()).join("")}function re(d){const r=d.replace(/[^0-9a-fA-F]/g,""),s=new Uint8Array(Math.floor(r.length/2));for(let a=0;a<s.length;a++)s[a]=parseInt(r.substr(a*2,2),16);return s}function _t(d){let r=0;for(const s of d)r+=s;return~r+1&255}function Et(d,r=[],s=jt){const a=r.length+3,i=[We,a,s,d,...r];return Uint8Array.from([...i,_t(i)])}function St(d){return Math.ceil(d.replace(/[^0-9a-fA-F]/g,"").length/4)<<11&65535}class Tt{constructor(r={}){b(this,"port",null);b(this,"writer",null);b(this,"reader",null);b(this,"buffer",[]);b(this,"pending",[]);b(this,"closing",!1);b(this,"inventoryTimer",null);b(this,"inventoryInFlight",null);b(this,"inventoryDone",null);b(this,"busy",0);this.events=r}get connected(){return!!this.port}async connect(r=115200,s="serial"){var i,c;let a;if(s==="usb")a=await xe.request();else{if(!$e())throw new Error("This browser cannot talk to USB readers. Use Chrome or Edge on a desktop.");a=await navigator.serial.requestPort()}await a.open({baudRate:r,dataBits:8,stopBits:1,parity:"none"}),this.port=a,this.closing=!1,this.writer=a.writable.getWriter(),this.reader=a.readable.getReader(),(c=(i=this.events).onStatus)==null||c.call(i,"connected"),this.readLoop()}async disconnect(){var r,s,a,i,c,m;this.closing=!0,this.stopInventory();try{await((r=this.reader)==null?void 0:r.cancel())}catch{}try{(s=this.reader)==null||s.releaseLock(),(a=this.writer)==null||a.releaseLock()}catch{}try{await((i=this.port)==null?void 0:i.close())}catch{}this.port=null,this.reader=null,this.writer=null,this.buffer=[],(m=(c=this.events).onStatus)==null||m.call(c,"disconnected")}async readLoop(){var r,s;for(;this.reader&&!this.closing;)try{const{value:a,done:i}=await this.reader.read();if(i)break;a&&this.ingest(a)}catch(a){this.closing||(s=(r=this.events).onError)==null||s.call(r,a.message);break}}ingest(r){for(const s of r)this.buffer.push(s);for(;;){const s=this.buffer.indexOf(We);if(s<0){this.buffer=[];return}if(s>0&&this.buffer.splice(0,s),this.buffer.length<2)return;const i=this.buffer[1]+2;if(this.buffer.length<i)return;const c=this.buffer.slice(0,i);this.buffer.splice(0,i),this.handleFrame(Uint8Array.from(c))}}handleFrame(r){var c,m,x,_,j;(m=(c=this.events).onFrame)==null||m.call(c,J(r));const s=r[3],a=r.slice(4,r.length-1);if(s===I.REAL_TIME_INVENTORY){if(a.length===7||a.length===1){(x=this.inventoryDone)==null||x.call(this);return}const T=kt(a);T&&((j=(_=this.events).onTag)==null||j.call(_,T));return}const i=this.pending.findIndex(T=>T.cmd===s);if(i>=0){const T=this.pending.splice(i,1)[0];clearTimeout(T.timer),T.resolve(a)}}async send(r,s=[]){if(!this.writer)throw new Error("Reader is not connected.");await this.writer.write(Et(r,s))}async request(r,s=[],a=2e3){this.busy++;try{this.inventoryInFlight&&await this.inventoryInFlight;try{return await this.rawRequest(r,s,a)}catch{return await new Promise(c=>setTimeout(c,120)),await this.rawRequest(r,s,a)}}finally{this.busy--}}rawRequest(r,s,a){return new Promise((i,c)=>{const m=setTimeout(()=>{this.pending=this.pending.filter(x=>x.timer!==m),c(new Error("The reader did not answer. Check the cable and try again."))},a);this.pending.push({cmd:r,resolve:i,reject:c,timer:m}),this.send(r,s).catch(x=>{clearTimeout(m),c(x)})})}startInventory(r=400){this.stopInventory();const s=()=>{this.busy>0||this.inventoryInFlight||(this.inventoryInFlight=new Promise(a=>{const i=setTimeout(a,1500);this.inventoryDone=()=>{clearTimeout(i),a()}}).then(()=>{this.inventoryInFlight=null,this.inventoryDone=null}),this.send(I.REAL_TIME_INVENTORY,[1]).catch(a=>{var i,c;return(c=(i=this.events).onError)==null?void 0:c.call(i,a.message)}))};s(),this.inventoryTimer=setInterval(s,r)}stopInventory(){this.inventoryTimer&&clearInterval(this.inventoryTimer),this.inventoryTimer=null}async setPower(r){const s=Math.max(0,Math.min(30,Math.round(r))),a=await this.request(I.SET_OUTPUT_POWER,[s]);if(a.length===1&&a[0]!==16)throw new Error(`Reader refused power ${s} dBm (code 0x${a[0].toString(16)})`)}async getPower(){return(await this.request(I.GET_OUTPUT_POWER,[]))[0]}async setBeeper(r){await this.request(I.BUZZER,[r])}async beep(){await this.setBeeper(1),await new Promise(r=>setTimeout(r,1500)),await this.setBeeper(0)}async setEpcMatch(r){const s=re(r);await this.request(I.SET_ACCESS_EPC_MATCH,[0,s.length,...Array.from(s)])}async clearEpcMatch(){await this.request(I.SET_ACCESS_EPC_MATCH,[1]).catch(()=>{})}async readBank(r,s,a,i="00000000"){const c=Array.from(re(i.padStart(8,"0"))),m=await this.request(I.READ_MEMORY,[r,s,a,...c],4e3);if(m.length>=6){const _=m[2],j=m[3+_];if(3+_+3<=m.length&&j>0&&j<=_)return J(m.slice(3+_-j,3+_))}const x=Math.max(0,m.length-3);return J(m.slice(Math.max(0,x-a*2),x))}async writeEpc(r,s="00000000"){const a=re(r);if(a.length%2!==0)throw new Error("EPC must be a whole number of bytes.");const i=St(r),c=[i>>8&255,i&255,...Array.from(a)],m=c.length/2,x=Array.from(re(s.padStart(8,"0")));await this.request(I.WRITE_MEMORY,[...x,Nt.EPC,1,m,...c],6e3)}}function kt(d){if(d.length<7)return null;const r=d[0],s=J(d.slice(1,3)),a=d[d.length-1],i=d.slice(3,d.length-1);return i.length<4?null:{epc:J(i),pc:s,rssi:a,antenna:r,at:Date.now()}}const Ct=200;let De=null;function q(d){try{De??(De=new AudioContext);const r=De;r.state==="suspended"&&r.resume();
11const s=d==="read"?[[1800,0]]:d==="write"?[[1800,0],[2400,.16]]:[[400,0]];for(const[a,i]of s){const c=r.createOscillator(),m=r.createGain();c.frequency.value=a;const x=r.currentTime+i;m.gain.setValueAtTime(.15,x),m.gain.exponentialRampToValueAtTime(.001,x+(d==="error"?.35:.12)),c.connect(m).connect(r.destination),c.start(x),c.stop(x+.4)}}catch{}}function Wt(){const{currentOrganization:d}=nt(),r=(d==null?void 0:d.id)??null,s=o.useRef(null),[a,i]=o.useState(!1),c=10,[m,x]=o.useState(()=>Number(localStorage.getItem("bp.tagprog.minSignal")??0)),_=o.useRef(m);o.useEffect(()=>{_.current=m,localStorage.setItem("bp.tagprog.minSignal",String(m))},[m]);const[j,T]=o.useState(null),O=(j==null?void 0:j.v)??null,[E,be]=o.useState(null),[y,se]=o.useState(null),[ze,we]=o.useState(!1),[ye,Fe]=o.useState([]);o.useEffect(()=>{if(!E)return;const t=setTimeout(()=>{be(null),se(null)},1500);return()=>clearTimeout(t)},[E]),o.useEffect(()=>{if(!j)return;const t=setTimeout(()=>T(null),1500);return()=>clearTimeout(t)},[j]);const[ae,ve]=o.useState(""),[je,ne]=o.useState([]),[v,Ve]=o.useState(null),[ie,Ne]=o.useState(""),[_e,Ee]=o.useState(!1),[z,Ze]=o.useState(()=>{try{return JSON.parse(localStorage.getItem("bp.tagprog.ledger")??"{}")}catch{return{}}}),Se=o.useRef(z);o.useEffect(()=>{Se.current=z,localStorage.setItem("bp.tagprog.ledger",JSON.stringify(z))},[z]);const ce=localStorage.getItem("bp.tagprog.prefix")??"E280",[C,He]=o.useState(ce),[U,F]=o.useState(()=>{var t;return(((t=z[ce])==null?void 0:t.last)??1e3)+1}),[B,Ye]=o.useState(!1),[oe,Xe]=o.useState([]),V=o.useRef(!1),Z=o.useRef(null),Te=o.useRef(!1),M=o.useRef({prefix:ce,next:U}),L=o.useRef(!0),Q=o.useRef(new Set),[H,A]=o.useState("ready");o.useEffect(()=>{Te.current=B},[B]),o.useEffect(()=>{M.current={prefix:C,next:U}},[C,U]);const Ge=t=>{var l;He(t),localStorage.setItem("bp.tagprog.prefix",t);const n=(l=Se.current[t])==null?void 0:l.last;n!=null&&F(n+1)},[D,ke]=o.useState(null);o.useEffect(()=>{const t=te(C);let n=!1;return(async()=>{var p;const[{data:l},{count:u}]=await Promise.all([R.from("rfid_tag_numbers").select("seq").eq("prefix",t).order("seq",{ascending:!1}).limit(1),R.from("rfid_tag_numbers").select("epc",{count:"exact",head:!0}).eq("prefix",t)]);if(n)return;const f=(p=l==null?void 0:l[0])==null?void 0:p.seq,h=f!=null?{last:Number(f),count:u??0}:null;ke(h),h&&F(g=>Math.max(g,h.last+1))})(),()=>{n=!0}},[C]),o.useEffect(()=>{if(!B)return;const t=setInterval(()=>{const n=Z.current;(!n||Date.now()-n.at>1200)&&!L.current&&!V.current&&(L.current=!0,A("ready"))},300);return()=>clearInterval(t)},[B]),o.useEffect(()=>{B&&(L.current=!0,A("ready"))},[B]);const Ce=$e(),Re=Oe(),Je=Ce||Re,S=o.useCallback((t,n,l)=>{Fe(u=>[{at:Date.now(),epc:t,text:n,ok:l},...u].slice(0,Ct))},[]),le=o.useCallback(async t=>{if(r){we(!0);try{const{data:n,error:l}=await R.from("rfid_transponders").select("epc, is_primary, is_active, member_number, family_member_id, rider_name").eq("organization_id",r).eq("epc",t).maybeSingle();if(l)throw l;if(!n){se({epc:t,riderName:null,memberNumber:null,isPrimary:!1,active:!1});return}let u=n.rider_name,f=n.member_number?String(n.member_number):null;if(n.family_member_id){const{data:h}=await R.from("rider_family_members").select("first_name, last_name, beyondpro_member_number").eq("id",n.family_member_id).maybeSingle();if(h){const p=`${h.first_name??""} ${h.last_name??""}`.trim();p&&(u=p),h.beyondpro_member_number&&(f=String(h.beyondpro_member_number))}}se({epc:t,riderName:u,memberNumber:f,isPrimary:!!n.is_primary,active:!!n.is_active})}catch(n){P.error("Could not check that tag",{description:n.message})}finally{we(!1)}}},[r]),de=(t,n)=>{const l=te(t),u=n.toString(16).toUpperCase();return(l+u.padStart(24-l.length,"0")).slice(0,24).padEnd(24,"0")},Pe=o.useCallback(()=>de(M.current.prefix,M.current.next),[]),me=o.useCallback(async(t,n)=>{var p;const l=s.current;if(!(l!=null&&l.connected))throw new Error("Connect the reader first.");const u=Ue(t);if(!u.ok)throw new Error(u.reason??"That tag number is not valid.");const f=n??((p=Z.current)==null?void 0:p.epc);f&&await l.setEpcMatch(f);try{await l.writeEpc(u.normalized)}finally{await l.clearEpcMatch()}await new Promise(g=>setTimeout(g,300));const h=u.normalized.length/4;for(let g=0;g<3;g++){let w="";try{await l.setEpcMatch(u.normalized),w=await l.readBank(1,2,h)}catch{}finally{await l.clearEpcMatch()}if(w.toUpperCase()===u.normalized)return!0;await new Promise(N=>setTimeout(N,250))}return!1},[]),ue=o.useCallback(async t=>{if(T(g=>g&&Date.now()-g.at<700&&g.v>t.rssi?g:{v:t.rssi,at:Date.now()}),t.rssi<_.current)return;be(t);const n=Z.current,l=n&&n.epc===t.epc&&Date.now()-n.at<1500;if(Z.current={epc:t.epc,at:Date.now()},!Te.current){l||(q("read"),le(t.epc));return}if(V.current||!L.current)return;if(Q.current.has(t.epc)){L.current=!1,A("remove"),q("error"),S(t.epc,"Already written in this batch â take it off the pad.",!0);return}L.current=!1,V.current=!0,A("writing");const u=M.current.prefix,f=M.current.next;let h="",p=f;try{const{data:g,error:w}=await R.rpc("reserve_tag_number",{_prefix:u,_start:f,_organization_id:r??null});if(w)throw new Error(w.message);const N=Array.isArray(g)?g[0]:g;if(!(N!=null&&N.epc))throw new Error("Could not reserve a tag number.");h=N.epc,p=Number(N.seq)}catch(g){q("error"),S("",`Not written â ${g.message}`,!1),A("remove"),setTimeout(()=>{V.current=!1},500);return}p>f&&S(h,`Skipped ${p-f} number(s) already issued on Beyond Pro.`,!0);try{const g=await me(h,t.epc);
11Q.current.add(h),Q.current.add(t.epc),Ze(w=>{const N=w[u]??{last:0,epcs:[]};return{...w,[u]:{last:Math.max(N.last,p),epcs:N.epcs.includes(h)?N.epcs:[...N.epcs,h]}}}),ke(w=>({last:Math.max((w==null?void 0:w.last)??0,p),count:((w==null?void 0:w.count)??0)+1})),q(g?"write":"error"),S(h,g?`Written and verified (was ${t.epc})`:`Written, but the check read did not match â lift and re-place the tag to confirm (was ${t.epc})`,g),Xe(w=>[{epc:h,seq:p,at:Date.now()},...w]),M.current={...M.current,next:p+1},F(p+1),Z.current={epc:h,at:Date.now()},A("remove")}catch(g){q("error"),S(h,g.message,!1),A("remove")}finally{setTimeout(()=>{V.current=!1},500)}},[le,Pe,S,me]),Ie=o.useRef(ue);o.useEffect(()=>{Ie.current=ue},[ue]);const Be=async(t="usb")=>{try{const n=new Tt({onTag:l=>Ie.current(l),onError:l=>S("",l,!1),onStatus:l=>i(l==="connected")});await n.connect(115200,t),s.current=n,await n.setPower(c).catch(l=>S("",`Strength not applied: ${l.message}`,!1)),await n.setBeeper(0).catch(()=>{}),n.startInventory(350),P.success("Reader connected")}catch(n){if(String(n.name)==="NotFoundError")return;P.error("Could not connect",{description:n.message})}},Qe=async()=>{var t;await((t=s.current)==null?void 0:t.disconnect()),s.current=null,i(!1)};o.useEffect(()=>()=>{var t;(t=s.current)==null||t.disconnect()},[]),o.useEffect(()=>{const t=ae.trim();if(!t||t.length<2){ne([]);return}let n=!1;const l=setTimeout(async()=>{const u=t.replace(/\D/g,"");let f=R.from("rider_family_members").select("id, first_name, last_name, beyondpro_member_number").limit(12);f=u&&u===t?f.eq("beyondpro_member_number",Number(u)):f.or(`first_name.ilike.%${t}%,last_name.ilike.%${t}%`);const{data:h}=await f;n||ne((h??[]).map(p=>({id:p.id,name:`${p.first_name??""} ${p.last_name??""}`.trim()||"Unnamed rider",memberNumber:p.beyondpro_member_number?String(p.beyondpro_member_number):null})))},250);return()=>{n=!0,clearTimeout(l)}},[ae]);const Ke=async t=>{if(!r||!v)return;const{error:n}=await R.functions.invoke("manage-rider-transponders",{body:{organization_id:r,member_number:v.memberNumber,family_member_id:v.id,rider_name:v.name,transponders:[{epc:t,is_primary:!0}],mode:"append",allow_clear:!1}});if(n)throw new Error(n.message)},et=async()=>{const t=Ue(ie);if(!t.ok){P.error(t.reason??"That tag number is not valid.");return}if(!v){P.error("Pick a rider first");return}Ee(!0);try{const{data:n}=await R.from("rfid_transponders").select("id").ilike("epc",t.normalized).neq("family_member_id",v.id).limit(1);if(n&&n.length)throw new Error("That tag number already belongs to another rider on Beyond Pro. Pick a different number.");const l=await me(t.normalized);await Ke(t.normalized),await R.rpc("record_tag_write",{_epc:t.normalized,_organization_id:r}),q(l?"write":"error"),S(t.normalized,`Assigned to ${v.name}${l?"":" (check read did not match â re-place the tag to confirm)"}`,l),P.success("Tag written and linked",{description:`${t.normalized} â ${v.name}`}),le(t.normalized)}catch(n){q("error"),S(t.normalized,n.message,!1),P.error("Could not program that tag",{description:n.message})}finally{Ee(!1)}},tt=()=>{const t=`sequence,epc,written_at 12`,n=oe.slice().reverse().map(h=>`${h.seq},${h.epc},${new Date(h.at).toISOString()}`).join(` 13`),l=new Blob([t+n],{type:"text/csv"}),u=URL.createObjectURL(l),f=document.createElement("a");f.href=u,f.download=`tag-batch-${new Date().toISOString().slice(0,10)}.csv`,f.click(),URL.revokeObjectURL(u)},rt=o.useMemo(()=>y?!y.riderName&&!y.memberNumber?e.jsx(K,{variant:"secondary",children:"Blank / unassigned"}):e.jsx(K,{className:"bg-emerald-600 hover:bg-emerald-600",children:"Assigned"}):null,[y]);return Je?e.jsxs("div",{className:"container mx-auto py-6 max-w-4xl space-y-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold",children:"Tag Programmer"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Plug the desktop reader into this computer to check, write and assign transponders â no separate program needed."})]}),e.jsxs(W,{children:[e.jsxs(Y,{className:"pb-3",children:[e.jsxs(X,{className:"text-base flex items-center gap-2",children:[e.jsx(pt,{className:"h-4 w-4"})," Reader"]}),e.jsx(he,{children:a?"Connected and scanning the pad.":"Not connected."})]}),e.jsxs($,{className:"space-y-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[a?e.jsxs(k,{variant:"outline",onClick:Qe,children:[e.jsx(ge,{className:"h-4 w-4 mr-2"})," Disconnect"]}):e.jsxs(e.Fragment,{children:[Re&&e.jsxs(k,{onClick:()=>Be("usb"),children:[e.jsx(ge,{className:"h-4 w-4 mr-2"})," Connect (USB direct)"]}),Ce&&e.jsxs(k,{variant:"outline",onClick:()=>Be("serial"),children:[e.jsx(ge,{className:"h-4 w-4 mr-2"})," Connect (COM port)"]})]}),e.jsxs(k,{variant:"outline",disabled:!a,onClick:()=>{var t;return(t=s.current)==null?void 0:t.beep().catch(n=>P.error("Beep failed",{description:n.message}))},children:[e.jsx(mt,{className:"h-4 w-4 mr-2"})," Test beep"]}),a&&e.jsxs(K,{variant:"secondary",children:[e.jsx(ut,{className:"h-3 w-3 mr-1"})," Live"]})]}
13),!a&&e.jsxs("details",{className:"rounded-md border p-3 text-sm",children:[e.jsx("summary",{className:"cursor-pointer font-medium",children:"USB direct setup (one time per Windows laptop)"}),e.jsxs("ol",{className:"list-decimal pl-5 mt-2 space-y-1 text-muted-foreground",children:[e.jsxs("li",{children:[e.jsx("a",{className:"underline text-primary font-medium",href:"https://github.com/pbatard/libwdi/releases/download/v1.5.1/zadig-2.9.exe",download:!0,children:"Download Zadig (zadig-2.9.exe)"})," ","â free, signed, no install."," ",e.jsx("a",{className:"underline text-muted-foreground",href:"https://zadig.akeo.ie",target:"_blank",rel:"noreferrer",children:"Zadig website"})]}),e.jsx("li",{children:"Plug in the reader, open Zadig, then Options â List All Devices."}),e.jsxs("li",{children:['Pick the reader (shows as "SmartThings Dongle" or "CP210x"), choose ',e.jsx("b",{children:"WinUSB"}),", click Replace/Install Driver."]}),e.jsxs("li",{children:["Unplug and replug the reader, then click ",e.jsx("b",{children:"Connect (USB direct)"})," here."]})]}),e.jsx("p",{className:"mt-2 text-xs text-muted-foreground",children:"No unsigned drivers or test mode needed. Mac, Linux and Chromebooks skip this step. To go back to the old Write Card program, uninstall the device in Device Manager and reinstall its COM driver."})]}),e.jsxs("p",{className:"text-xs text-muted-foreground max-w-sm",children:["Reader strength is fixed at ",c," dBm â the lowest this reader supports. Use the pad filter below to ignore tags farther away."]}),e.jsxs("div",{className:"space-y-2 max-w-sm",children:[e.jsxs(G,{className:"text-xs uppercase tracking-wide text-muted-foreground",children:["Pad-only filter â ignore signal below ",m,m===0?" (off)":""]}),e.jsx(ot,{value:[m],min:0,max:120,step:1,onValueChange:([t])=>x(t)}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Strongest tag the reader hears: ",e.jsx("span",{className:"font-mono",children:O??"â"}),O!=null&&m>0&&(O<m?e.jsxs("span",{className:"ml-1 font-medium text-muted-foreground",children:["â ignored (below ",m,"), not used"]}):e.jsx("span",{className:"ml-1 font-medium text-primary",children:"â on the pad, used"})),". Tags farther away read weaker and are ignored."]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(k,{size:"sm",variant:"outline",disabled:O==null,onClick:()=>{const t=Math.max(0,(O??0)-3);x(t),S("",`Pad filter set to ${t} (tag on pad read ${O})`,!0)},children:"Tag is on the pad â set filter"}),m>0&&e.jsx(k,{size:"sm",variant:"ghost",onClick:()=>x(0),children:"Turn filter off"})]})]})]})]}),e.jsxs(lt,{defaultValue:"verify",children:[e.jsxs(dt,{children:[e.jsx(fe,{value:"verify",children:"Check a tag"}),e.jsx(fe,{value:"assign",children:"Write & assign"}),e.jsx(fe,{value:"batch",children:"Batch writing"})]}),e.jsx(pe,{value:"verify",className:"pt-4",children:e.jsxs(W,{children:[e.jsxs(Y,{className:"pb-3",children:[e.jsx(X,{className:"text-base",children:"Place a tag on the pad"}),e.jsx(he,{children:"We read it and show who it belongs to."})]}),e.jsxs($,{className:"space-y-3",children:[!E&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"Waiting for a tagâ¦"}),E&&e.jsxs("div",{className:"rounded-md border p-4 space-y-2",children:[e.jsx("div",{className:"font-mono text-lg tracking-wide",children:E.epc}),(()=>{var l;const t=((l=E.epc.match(/../g))==null?void 0:l.map(u=>parseInt(u,16)))??[];return t.length>0&&t.every(u=>u>=32&&u<=126)?e.jsxs("div",{className:"text-sm",children:["Reads as text: ",e.jsxs("span",{className:"font-mono font-semibold",children:['"',String.fromCharCode(...t),'"']})]}):null})(),e.jsxs("div",{className:"text-xs text-muted-foreground",children:["PC word ",E.pc," · ",E.epc.length/4," words"]}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:["Signal ",E.rssi," · read ",new Date(E.at).toLocaleTimeString()]}),e.jsx("div",{className:"flex items-center gap-2 pt-1",children:ze?e.jsx("span",{className:"text-sm text-muted-foreground",children:"Checkingâ¦"}):e.jsxs(e.Fragment,{children:[rt,(y==null?void 0:y.riderName)&&e.jsx("span",{className:"text-sm font-medium",children:y.riderName}),(y==null?void 0:y.memberNumber)&&e.jsxs("span",{className:"text-sm text-muted-foreground",children:["BP #",y.memberNumber]}),(y==null?void 0:y.isPrimary)&&e.jsx(K,{variant:"outline",children:"Primary"})]})}),e.jsx(k,{size:"sm",variant:"outline",onClick:()=>Ne(E.epc),children:"Use this number below"})]})]})]})}),e.jsx(pe,{value:"assign",className:"pt-4",children:e.jsxs(W,{children:[e.jsx(Y,{className:"pb-3",children:e.jsxs(X,{className:"text-base flex items-center gap-2",children:[e.jsx(ht,{className:"h-4 w-4"})," Write a tag and link it to a rider"]})}),e.jsxs($,{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(G,{children:"Find the rider"}),e.jsx(ee,{value:ae,onChange:t=>ve(t.target.value),placeholder:"Name or Beyond Pro number"}),je.length>0&&e.jsx("div",{className:"rounded-md border divide-y max-h-56 overflow-auto",children:je.map(t=>e.jsxs("button",{type:"button",className:`w-full text-left px-3 py-2 text-sm hover:bg-muted ${(v==null?void 0:v.id)===t.id?"bg-muted":""}`,onClick:()=>{Ve(t),ne([]),ve(t.name)},children:[e.jsx("span",{className:"font-medium",children:t.name}),t.memberNumber&&e.jsxs("span",{className:"text-muted-foreground",children:[" · BP #",t.memberNumber]})]},t.id))}),v&&e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Programming for ",e.jsx("span",{className:"font-medium text-foreground",children:v.name})]})]}),e.jsxs("div",{className:"space-y-2 max-w-sm",children:[e.jsx(G,{children:"Tag number to write (24 characters)"}),e.jsx(ee,{value:ie,onChange:t=>Ne(te(t.target.value)),placeholder:"E28011700000000000001001",className:"font-mono",maxLength:24})]}),e.jsxs(k,{onClick:et,disabled:!a||_e||!v||ie.length!==24,children:[e.jsx(Ae,{className:"h-4 w-4 mr-2"}),_e?"Writingâ¦":"Write, check and assign"]})]})]})}),e.jsx(pe,{value:"batch",className:"pt-4",children:e.jsxs(W,{children:[e.jsxs(Y,{className:"pb-3",children:[e.jsxs(X,{className:"text-base flex items-center gap-2",children:[e.jsx(ft,{className:"h-4 w-4"})," Batch writing"]}),e.jsx(he,{children:"Turn this on, then drop one tag at a time on the pad. Each gets the next number."})]}),e.jsxs($,{className:"space-y-4",children:[e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2 max-w-lg",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(G,{children:"Number start"}),e.jsx(ee,{value:C,onChange:t=>Ge(te(t.target.value)),className:"font-mono"})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(G,{children:"Next tag number"}),e.jsx(ee,{type:"number",value:U,onChange:t=>F(Number(t.target.value)||0)})]})]}),e.jsxs("div",{className:"text-sm text-muted-foreground",children:["Next tag will be ",e.jsx("span",{className:"font-mono text-foreground",children:de(C,U)})]}),e.jsxs("div",{className:"rounded-md border bg-muted/40 px-3 py-2 text-sm space-y-1",children:[D?e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:["Last number issued with ",e.jsx("span",{className:"font-mono",children:C})," across Beyond Pro: ",e.jsxs("b",{children:["#",D.last]})," ",e.jsxs("span",{className:"font-mono text-muted-foreground",children:["(",de(C,D.last),")"]})]}),e.jsxs("div",{className:"text-muted-foreground",children:[D.count," tag(s) issued with this start, on any laptop at any track."]}),U<=D.last&&e.jsxs("div",{className:"text-destructive font-medium",children:["#",U," was already issued. Used numbers are skipped automatically."," ",e.jsxs("button",{className:"underline",onClick:()=>F(D.last+1),children:["Jump to #",D.last+1]})]})]}):e.jsxs("div",{className:"text-muted-foreground",children:["No tags issued yet with ",e.jsx("span",{className:"font-mono",children:C||"â"})," anywhere on Beyond Pro."]}),e.jsx("div",{className:"text-xs text-muted-foreground",children:"Every number is reserved with Beyond Pro before it's written, so no two tags on the platform can match."})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(ct,{checked:B,onCheckedChange:Ye,disabled:!a}),e.jsx("span",{className:"text-sm",children:"Write automatically when a tag touches the pad"})]}),B&&e.jsxs("div",{className:`rounded-md border px-3 py-2 text-sm font-medium ${H==="remove"?"border-amber-300 bg-amber-50 text-amber-900":H==="writing"?"border-blue-300 bg-blue-50 text-blue-900":"border-emerald-300 bg-emerald-50 text-emerald-900"}`,children:[H==="remove"&&"Done â take the tag off the pad, then place the next one.",H==="writing"&&"Writing⦠keep the tag still on the pad.",H==="ready"&&`Ready â place a tag on the pad for ${Pe()}.`]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Each tag gets one number. To put a different number on a tag that was already written, use the Write & assign tab â it always overwrites whatever is on the tag."}),e.jsx(k,{size:"sm",variant:"outline",onClick:()=>{Q.current.clear(),L.current=!0,A("ready"),P.success("Batch reset â tags can be written again")},children:"Start a fresh batch"}),oe.length>0&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs(k,{size:"sm",variant:"outline",onClick:tt,children:[e.jsx(it,{className:"h-4 w-4 mr-2"})," Export list"]}),e.jsx("div",{className:"rounded-md border divide-y max-h-56 overflow-auto text-sm",children:oe.map(t=>e.jsxs("div",{className:"px-3 py-1.5 flex justify-between",children:[e.jsx("span",{className:"font-mono",children:t.epc}),e.jsxs("span",{className:"text-muted-foreground",children:["#",t.seq]})]},`${t.epc}-${t.at}`))})]})]})]})})]}),e.jsxs(W,{children:[e.jsx(Y,{className:"pb-3",children:e.jsx(X,{className:"text-base",children:"Activity"})}),e.jsx($,{children:ye.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Nothing yet."}):e.jsx("div",{className:"space-y-1 max-h-64 overflow-auto text-sm",children:ye.map(t=>e.jsxs("div",{className:"flex gap-2 items-start",children:[t.ok?e.jsx(Ae,{className:"h-4 w-4 text-emerald-600 mt-0.5 shrink-0"}):e.jsx(Me,{className:"h-4 w-4 text-amber-500 mt-0.5 shrink-0"}),e.jsx("span",{className:"font-mono text-xs",children:t.epc}),e.jsx("span",{className:"text-muted-foreground",children:t.text})]},`${t.at}-${t.epc}`))})})]})]}):e.jsxs("div",{className:"container mx-auto py-6 max-w-3xl space-y-4",children:[e.jsx("h1",{className:"text-2xl font-bold",children:"Tag Programmer"}),e.jsx(W,{children:e.jsxs($,{className:"p-6 flex gap-3 text-sm",children:[e.jsx(Me,{className:"h-5 w-5 text-amber-500 shrink-0"}),e.jsx("div",{children:"This browser can't talk to the USB desktop reader. Open Beyond Pro in Chrome or Edge on a laptop or desktop, then come back to this page."})]})})]})}export{Wt 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.