seg-cam 0.4.4 → 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "seg-cam",
3
- "version": "0.4.4",
3
+ "version": "0.4.6",
4
4
  "private": false,
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -82213,10 +82213,13 @@ var handleInit = async (message) => {
82213
82213
  sendDebug(`[Worker] Runing in production: ${isProduction}`);
82214
82214
  await loadModules();
82215
82215
  await BodyPixSegmenter.getInstance();
82216
+ const device = tf.backend().device ? tf.backend().device : "unknown";
82216
82217
  self.postMessage({
82217
82218
  type: "ready",
82218
82219
  task: config.task,
82219
- model: "BodyPix"
82220
+ model: "BodyPix",
82221
+ device,
82222
+ dtype: "float32"
82220
82223
  });
82221
82224
  modelLoaded = true;
82222
82225
  } catch (error) {
@@ -82229,6 +82232,7 @@ var handleDetect = async (message) => {
82229
82232
  const { requestId, dimensions, bitmap: inputBitmap, threshold: threshold3 } = message;
82230
82233
  let outputBitmap;
82231
82234
  try {
82235
+ console.log("[Worker] handleDetect called with requestId:", requestId, "dimensions:", dimensions, "bitmap:", !!inputBitmap, "threshold:", threshold3);
82232
82236
  if (isProcessing) {
82233
82237
  throw new Error("New request before previous finished");
82234
82238
  }
@@ -82347,12 +82351,15 @@ var handleDetect = async (message) => {
82347
82351
  };
82348
82352
  self.onmessage = async (event) => {
82349
82353
  const message = event.data;
82354
+ console.log("[Worker] Received message type:", message.type, "requestId:", message.requestId);
82350
82355
  try {
82351
82356
  switch (message.type) {
82352
82357
  case "init":
82358
+ console.log("[Worker] Processing init message");
82353
82359
  await handleInit(message);
82354
82360
  break;
82355
82361
  case "detect":
82362
+ console.log("[Worker] Processing detect message with requestId:", message.requestId);
82356
82363
  await handleDetect(message);
82357
82364
  break;
82358
82365
  default:
package/dist/index.d.mts DELETED
@@ -1,150 +0,0 @@
1
- import React from 'react';
2
-
3
- type TaskType = "object-detection" | "image-segmentation";
4
- type ModelType = "BodyPix";
5
- type ObjectDetectionType = {
6
- score: number;
7
- label: string;
8
- box: {
9
- xmin: number;
10
- ymin: number;
11
- xmax: number;
12
- ymax: number;
13
- };
14
- };
15
- type ImageSegmentationType = {
16
- label: string;
17
- score?: number;
18
- mask: any;
19
- };
20
- declare const DEFAULT_CONFIG: {
21
- TASK: TaskType;
22
- MODEL: ModelType;
23
- BODYPIX_ARCHITECTURE: "MobileNetV1" | "ResNet50";
24
- BODYPIX_MULTIPLIER: number;
25
- BODYPIX_QUANT_BYTES: number;
26
- BODYPIX_STRIDE: number;
27
- MULTI_SEGMENTATION: boolean;
28
- SEGMENT_BODY_PARTS: boolean;
29
- BACKGROUND_SHADE: number;
30
- SHIRT_SHADE: number;
31
- DETECTION_THRESHOLD: number;
32
- TARGET_PART_ID: number;
33
- ONLY_DRAW_MASK: boolean;
34
- VERBOSE: boolean;
35
- };
36
-
37
- /**
38
- * Detection statistics interface
39
- */
40
- interface DetectionStats {
41
- /** Number of detections found */
42
- jerseyCount: number;
43
- /** Average confidence score (0-100) */
44
- confidence: number;
45
- /** Processing time in milliseconds */
46
- processingTime: number;
47
- /** Frames per second */
48
- fps: number;
49
- }
50
-
51
- interface JerseyDetectorHandle {
52
- isReady: boolean;
53
- stats: DetectionStats;
54
- lastError: string | null;
55
- }
56
- interface JerseyDetectorProps {
57
- videoRef: React.RefObject<HTMLVideoElement>;
58
- onWorkerReady?: (ready: boolean) => void;
59
- onWorkerError?: (error: string | null) => void;
60
- onStatsUpdate?: (stats: DetectionStats) => void;
61
- onSegmentedImage?: (segmentedImages: ImageBitmap[]) => void;
62
- task?: TaskType;
63
- model?: ModelType;
64
- verbose?: boolean;
65
- bodyPixArchitecture?: 'MobileNetV1' | 'ResNet50';
66
- bodyPixMultiplier?: number;
67
- bodyPixQuantBytes?: number;
68
- bodyPixStride?: number;
69
- multiSegmentation?: boolean;
70
- segmentBodyParts?: boolean;
71
- backgroundShade?: number;
72
- shirtShade?: number;
73
- threshold?: number;
74
- targetPartId?: number;
75
- onlyDrawMask?: boolean;
76
- workerUrl?: string;
77
- }
78
- declare const JerseyDetector: React.ForwardRefExoticComponent<JerseyDetectorProps & React.RefAttributes<JerseyDetectorHandle>>;
79
-
80
- type WorkerConfig = {
81
- task: TaskType;
82
- model: ModelType;
83
- verbose: boolean;
84
- bodyPixArchitecture?: 'MobileNetV1' | 'ResNet50';
85
- bodyPixMultiplier?: number;
86
- bodyPixQuantBytes?: number;
87
- bodyPixStride?: number;
88
- multiSegmentation?: boolean;
89
- segmentBodyParts?: boolean;
90
- backgroundShade?: number;
91
- shirtShade?: number;
92
- threshold?: number;
93
- targetPartId?: number;
94
- };
95
- type ImageDimensions$1 = {
96
- width: number;
97
- height: number;
98
- };
99
- type WorkerInitMessage = {
100
- type: "init";
101
- isProduction: boolean;
102
- config: WorkerConfig;
103
- };
104
- type WorkerDetectMessage = {
105
- type: "detect";
106
- dimensions: ImageDimensions$1;
107
- threshold?: number;
108
- bitmap: ImageBitmap;
109
- };
110
- type WorkerReadyMessage = {
111
- type: "ready";
112
- };
113
- type WorkerProgressMessage = {
114
- type: "loading_progress";
115
- progress: number;
116
- file: string;
117
- };
118
- type WorkerErrorMessage = {
119
- type: "error";
120
- error_message: string;
121
- };
122
- type WorkerDetectResponseMessage = {
123
- type: "detect_response";
124
- bitmap: ImageBitmap;
125
- stats: DetectionStats;
126
- segmentedImages?: ImageBitmap[];
127
- };
128
- type WorkerDebugMessage = {
129
- type: "debug";
130
- debug_message: string;
131
- };
132
- type WorkerPostMessage = WorkerInitMessage | WorkerDetectMessage;
133
- type WorkerResponseMessage = WorkerReadyMessage | WorkerProgressMessage | WorkerErrorMessage | WorkerDetectResponseMessage | WorkerDetectMessage;
134
-
135
- interface ImageDimensions {
136
- width: number;
137
- height: number;
138
- }
139
- /**
140
- * Simplified hook for jersey detection worker
141
- * Manages worker lifecycle, state, and detection requests
142
- */
143
- declare function useJerseyWorker(config: WorkerConfig, workerUrlProp?: string): {
144
- isReady: boolean;
145
- workerReady: boolean;
146
- lastError: string | null;
147
- detect: (bitmap: ImageBitmap, dimensions: ImageDimensions, threshold?: number) => Promise<any>;
148
- };
149
-
150
- export { DEFAULT_CONFIG, type DetectionStats, type ImageDimensions$1 as ImageDimensions, type ImageSegmentationType, JerseyDetector, type JerseyDetectorHandle, type JerseyDetectorProps, type ModelType, type ObjectDetectionType, type TaskType, type WorkerConfig, type WorkerDebugMessage, type WorkerDetectMessage, type WorkerDetectResponseMessage, type WorkerErrorMessage, type WorkerInitMessage, type WorkerPostMessage, type WorkerProgressMessage, type WorkerReadyMessage, type WorkerResponseMessage, useJerseyWorker };
package/dist/index.d.ts DELETED
@@ -1,151 +0,0 @@
1
- import React from 'react';
2
-
3
- type TaskType = "object-detection" | "image-segmentation";
4
- type ModelType = "BodyPix";
5
- type ObjectDetectionType = {
6
- score: number;
7
- label: string;
8
- box: {
9
- xmin: number;
10
- ymin: number;
11
- xmax: number;
12
- ymax: number;
13
- };
14
- };
15
- type ImageSegmentationType = {
16
- label: string;
17
- score?: number;
18
- mask: any;
19
- };
20
- declare const DEFAULT_CONFIG: {
21
- TASK: TaskType;
22
- MODEL: ModelType;
23
- BODYPIX_ARCHITECTURE: "MobileNetV1" | "ResNet50";
24
- BODYPIX_MULTIPLIER: number;
25
- BODYPIX_QUANT_BYTES: number;
26
- BODYPIX_STRIDE: number;
27
- MULTI_SEGMENTATION: boolean;
28
- SEGMENT_BODY_PARTS: boolean;
29
- BACKGROUND_SHADE: number;
30
- SHIRT_SHADE: number;
31
- DETECTION_THRESHOLD: number;
32
- TARGET_PART_ID: number;
33
- ONLY_DRAW_MASK: boolean;
34
- VERBOSE: boolean;
35
- };
36
-
37
- /**
38
- * Detection statistics interface
39
- */
40
- interface DetectionStats {
41
- /** Number of detections found */
42
- jerseyCount: number;
43
- /** Average confidence score (0-100) */
44
- confidence: number;
45
- /** Processing time in milliseconds */
46
- processingTime: number;
47
- /** Frames per second */
48
- fps: number;
49
- }
50
-
51
- interface JerseyDetectorHandle {
52
- isReady: boolean;
53
- stats: DetectionStats;
54
- lastError: string | null;
55
- capture: (format?: "image/jpeg" | "image/png", quality?: number) => string;
56
- }
57
- interface JerseyDetectorProps {
58
- videoRef: React.RefObject<HTMLVideoElement>;
59
- onWorkerReady?: (ready: boolean) => void;
60
- onWorkerError?: (error: string | null) => void;
61
- onStatsUpdate?: (stats: DetectionStats) => void;
62
- onSegmentedImage?: (segmentedImages: ImageBitmap[]) => void;
63
- task?: TaskType;
64
- model?: ModelType;
65
- verbose?: boolean;
66
- bodyPixArchitecture?: 'MobileNetV1' | 'ResNet50';
67
- bodyPixMultiplier?: number;
68
- bodyPixQuantBytes?: number;
69
- bodyPixStride?: number;
70
- multiSegmentation?: boolean;
71
- segmentBodyParts?: boolean;
72
- backgroundShade?: number;
73
- shirtShade?: number;
74
- threshold?: number;
75
- targetPartId?: number;
76
- onlyDrawMask?: boolean;
77
- workerUrl?: string;
78
- }
79
- declare const JerseyDetector: React.ForwardRefExoticComponent<JerseyDetectorProps & React.RefAttributes<JerseyDetectorHandle>>;
80
-
81
- type WorkerConfig = {
82
- task: TaskType;
83
- model: ModelType;
84
- verbose: boolean;
85
- bodyPixArchitecture?: 'MobileNetV1' | 'ResNet50';
86
- bodyPixMultiplier?: number;
87
- bodyPixQuantBytes?: number;
88
- bodyPixStride?: number;
89
- multiSegmentation?: boolean;
90
- segmentBodyParts?: boolean;
91
- backgroundShade?: number;
92
- shirtShade?: number;
93
- threshold?: number;
94
- targetPartId?: number;
95
- };
96
- type ImageDimensions$1 = {
97
- width: number;
98
- height: number;
99
- };
100
- type WorkerInitMessage = {
101
- type: "init";
102
- isProduction: boolean;
103
- config: WorkerConfig;
104
- };
105
- type WorkerDetectMessage = {
106
- type: "detect";
107
- dimensions: ImageDimensions$1;
108
- threshold?: number;
109
- bitmap: ImageBitmap;
110
- };
111
- type WorkerReadyMessage = {
112
- type: "ready";
113
- };
114
- type WorkerProgressMessage = {
115
- type: "loading_progress";
116
- progress: number;
117
- file: string;
118
- };
119
- type WorkerErrorMessage = {
120
- type: "error";
121
- error_message: string;
122
- };
123
- type WorkerDetectResponseMessage = {
124
- type: "detect_response";
125
- bitmap: ImageBitmap;
126
- stats: DetectionStats;
127
- segmentedImages?: ImageBitmap[];
128
- };
129
- type WorkerDebugMessage = {
130
- type: "debug";
131
- debug_message: string;
132
- };
133
- type WorkerPostMessage = WorkerInitMessage | WorkerDetectMessage;
134
- type WorkerResponseMessage = WorkerReadyMessage | WorkerProgressMessage | WorkerErrorMessage | WorkerDetectResponseMessage | WorkerDetectMessage;
135
-
136
- interface ImageDimensions {
137
- width: number;
138
- height: number;
139
- }
140
- /**
141
- * Simplified hook for jersey detection worker
142
- * Manages worker lifecycle, state, and detection requests
143
- */
144
- declare function useJerseyWorker(config: WorkerConfig, workerUrlProp?: string): {
145
- isReady: boolean;
146
- workerReady: boolean;
147
- lastError: string | null;
148
- detect: (bitmap: ImageBitmap, dimensions: ImageDimensions, threshold?: number) => Promise<any>;
149
- };
150
-
151
- export { DEFAULT_CONFIG, type DetectionStats, type ImageDimensions$1 as ImageDimensions, type ImageSegmentationType, JerseyDetector, type JerseyDetectorHandle, type JerseyDetectorProps, type ModelType, type ObjectDetectionType, type TaskType, type WorkerConfig, type WorkerDebugMessage, type WorkerDetectMessage, type WorkerDetectResponseMessage, type WorkerErrorMessage, type WorkerInitMessage, type WorkerPostMessage, type WorkerProgressMessage, type WorkerReadyMessage, type WorkerResponseMessage, useJerseyWorker };
package/dist/index.js DELETED
@@ -1 +0,0 @@
1
- "use strict";var de=Object.create;var L=Object.defineProperty;var ge=Object.getOwnPropertyDescriptor;var ye=Object.getOwnPropertyNames;var pe=Object.getPrototypeOf,Te=Object.prototype.hasOwnProperty;var ke=(e,t)=>{for(var o in t)L(e,o,{get:t[o],enumerable:!0})},te=(e,t,o,m)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of ye(t))!Te.call(e,s)&&s!==o&&L(e,s,{get:()=>t[s],enumerable:!(m=ge(t,s))||m.enumerable});return e};var De=(e,t,o)=>(o=e!=null?de(pe(e)):{},te(t||!e||!e.__esModule?L(o,"default",{value:e,enumerable:!0}):o,e)),be=e=>te(L({},"__esModule",{value:!0}),e);var h=(e,t,o)=>new Promise((m,s)=>{var _=i=>{try{b(o.next(i))}catch(R){s(R)}},y=i=>{try{b(o.throw(i))}catch(R){s(R)}},b=i=>i.done?m(i.value):Promise.resolve(i.value).then(_,y);b((o=o.apply(e,t)).next())});var Re={};ke(Re,{DEFAULT_CONFIG:()=>a,JerseyDetector:()=>X,useJerseyWorker:()=>Y});module.exports=be(Re);var n=require("react"),oe=De(require("react"));var g=require("react");var f=null,I=!1,O=null,q=0,G=null,p=new Map,Ee=0;function Y(e,t){let o=(0,g.useRef)(!1),[m,s]=(0,g.useState)(!1),[_,y]=(0,g.useState)(null),b=(0,g.useRef)(!0),i=(0,g.useRef)(!1);(0,g.useEffect)(()=>{s(I),y(O)},[]),(0,g.useEffect)(()=>e?(b.current=!0,q++,h(null,null,function*(){var w;if(!f||!Ie(G,e)){f&&(console.log("[useJerseyWorker] Terminating old worker due to config change"),f.terminate(),f=null,I=!1);try{i.current=(w=e.verbose)!=null?w:i.current,console.log(`[useJerseyWorker] Verbose set to ${i.current}`);let d=t||"/jersey-detector-worker.js";console.log(`[useJerseyWorker] Initializing worker from: ${d}`),f=new Worker(d),G=e,I=!1,O=null,s(!1),y(null),f.onmessage=c=>{let r=c.data;switch(r.type){case"ready":I=!0,s(!0),console.log(`[v0 useJerseyWorker] Worker ready: ${r.task} | ${r.model} | device: ${r.device} | dtype: ${r.dtype}`);break;case"loading_progress":i.current&&console.log(`[v0 useJerseyWorker] Loaded ${r.progress}% of ${r.file}`);break;case"debug":i.current&&console.log(r.debug_message);break;case"error":let T=r.error_message||"Unknown worker error";console.error("[v0 useJerseyWorker] Worker sent error message:",T),I=!1,O=T,s(!1),y(T);break;case"detect_response":if(r.requestId&&p.has(r.requestId)){let l=p.get(r.requestId);if(l){if(i.current){let k=r.stats;console.log(`Det count ${k.detectionCount} | Conf: ${k.averageConfidence} | proc time: ${k.processingTime}ms`)}l.resolve(r),p.delete(r.requestId)}}else if(p.size>0){let l=p.entries().next();if(!l.done){let[k,$]=l.value;$.resolve(r),p.delete(k)}}break}},f.onerror=c=>{let r=c.message||"Worker initialization error";console.error("[useJerseyWorker] Worker error:",r),I=!1,O=r,s(!1),y(r)},f.postMessage({type:"init",config:e})}catch(d){let c=(d==null?void 0:d.message)||String(d);console.error("[useJerseyWorker] Failed to create worker:",c),s(!1),y(c)}}else s(I),y(O)}),()=>{b.current=!1,q--,q<=0&&f&&(console.log("[useJerseyWorker] Terminating worker (refCount 0)"),f.terminate(),f=null,I=!1,O=null,G=null,p.clear())}):void 0,[e]);let R=(0,g.useCallback)((v,w,d=.5)=>h(null,null,function*(){if(!f||!I)throw new Error("Worker not ready");if(o.current)return console.log("[v0 useJerseyWorker] New request before detection completed"),null;let c=`req_${++Ee}_${Date.now()}`;return new Promise((r,T)=>{p.set(c,{resolve:r,reject:T});try{o.current=!0,f.postMessage({type:"detect",requestId:c,dimensions:w,bitmap:v,threshold:d},[v])}catch(l){p.delete(c);let k=`Failed to send detect: ${l==null?void 0:l.message}`;T(new Error(k))}finally{o.current=!1}setTimeout(()=>{p.has(c)&&(p.delete(c),T(new Error("Detection timeout")))},1e4)})}),[m]);return{isReady:m,workerReady:m,lastError:_,detect:R}}function Ie(e,t){return e?JSON.stringify(e)===JSON.stringify(t):!1}var a={TASK:"image-segmentation",MODEL:"BodyPix",BODYPIX_ARCHITECTURE:"MobileNetV1",BODYPIX_MULTIPLIER:.75,BODYPIX_QUANT_BYTES:2,BODYPIX_STRIDE:16,MULTI_SEGMENTATION:!0,SEGMENT_BODY_PARTS:!0,BACKGROUND_SHADE:0,SHIRT_SHADE:170,DETECTION_THRESHOLD:.5,TARGET_PART_ID:12,ONLY_DRAW_MASK:!0,VERBOSE:!1};var X=(0,n.forwardRef)(({videoRef:e,onWorkerReady:t,onWorkerError:o,onStatsUpdate:m,onSegmentedImage:s,task:_=a.TASK,model:y=a.MODEL,verbose:b=a.VERBOSE,bodyPixArchitecture:i=a.BODYPIX_ARCHITECTURE,bodyPixMultiplier:R=a.BODYPIX_MULTIPLIER,bodyPixQuantBytes:v=a.BODYPIX_QUANT_BYTES,bodyPixStride:w=a.BODYPIX_STRIDE,multiSegmentation:d=a.MULTI_SEGMENTATION,segmentBodyParts:c=a.SEGMENT_BODY_PARTS,backgroundShade:r=a.BACKGROUND_SHADE,shirtShade:T=a.SHIRT_SHADE,threshold:l=a.DETECTION_THRESHOLD,targetPartId:k=a.TARGET_PART_ID,onlyDrawMask:$=a.ONLY_DRAW_MASK,workerUrl:se},ne)=>{var V,z;let j=(0,n.useRef)(null),B=(0,n.useRef)(null),U=(0,n.useRef)(!1),N=(0,n.useRef)([]),ie=(0,n.useRef)(null),A=(0,n.useRef)(!1),[K,ae]=(0,n.useState)({jerseyCount:0,confidence:0,fps:0,processingTime:0}),ce=(0,n.useMemo)(()=>({task:_,model:y,verbose:b,bodyPixArchitecture:i,bodyPixMultiplier:R,bodyPixQuantBytes:v,bodyPixStride:w,multiSegmentation:d,segmentBodyParts:c,backgroundShade:r,shirtShade:T,threshold:l,targetPartId:k}),[_,y,b,i,R,v,w,d,c,r,T,l,k]),le=(0,n.useMemo)(()=>{var u,E;return{width:((u=e.current)==null?void 0:u.videoWidth)||0,height:((E=e.current)==null?void 0:E.videoHeight)||0}},[(V=e.current)==null?void 0:V.videoWidth,(z=e.current)==null?void 0:z.videoHeight]),{isReady:C,workerReady:M,lastError:W,detect:ue}=Y(ce,se);(0,n.useEffect)(()=>{t==null||t(M)},[M,t]),(0,n.useEffect)(()=>{W&&(A.current=!0,console.error("[v0] Worker error detected, stopping detection loop:",W)),o==null||o(W)},[W,o]);let fe=()=>h(null,null,function*(){var Q,Z,ee;let u=e.current,E=j.current;if(A.current||!M||!C||!u||!E||U.current||u.readyState<2||u.paused||u.ended)return;let J=null,x=null;try{U.current=!0;let S=u.videoWidth,P=u.videoHeight;ie.current={width:S,height:P},J=yield createImageBitmap(u);let D=yield ue(J,le,l);if((D==null?void 0:D.type)==="detect_response"&&D.bitmap){x=D.bitmap;let F=E.getContext("2d");F&&((E.width!==S||E.height!==P)&&(E.width=S,E.height=P),$&&F.clearRect(0,0,S,P),x&&F.drawImage(x,0,0)),N.current.push(Date.now()),N.current=N.current.filter(H=>Date.now()-H<1e3);let re={jerseyCount:((Q=D.stats)==null?void 0:Q.detectionCount)||0,confidence:((Z=D.stats)==null?void 0:Z.averageConfidence)||0,fps:N.current.length,processingTime:((ee=D.stats)==null?void 0:ee.processingTime)||0};if(ae(re),m==null||m(re),D.segmentedImages){let H=D.segmentedImages;h(null,null,function*(){try{yield s==null?void 0:s(H)}finally{H.forEach(me=>me.close())}})}}}catch(S){console.error("[v0] Detection error:",S),A.current=!0}finally{J&&J.close(),x&&x.close(),U.current=!1}});return(0,n.useEffect)(()=>{if(!M||!C||A.current)return;let u=()=>h(null,null,function*(){!M||!C||A.current||(yield fe(),B.current=requestAnimationFrame(u))});return B.current=requestAnimationFrame(u),()=>{B.current&&cancelAnimationFrame(B.current)}},[M,C]),(0,n.useImperativeHandle)(ne,()=>({isReady:C,lastError:W,stats:K}),[C,W,K]),oe.default.createElement("canvas",{ref:j,className:"absolute inset-0 w-full h-full pointer-events-none",style:{zIndex:10}})});X.displayName="JerseyDetector";0&&(module.exports={DEFAULT_CONFIG,JerseyDetector,useJerseyWorker});
package/dist/index.mjs DELETED
@@ -1 +0,0 @@
1
- var R=(r,d,i)=>new Promise((T,n)=>{var w=t=>{try{k(i.next(t))}catch(E){n(E)}},f=t=>{try{k(i.throw(t))}catch(E){n(E)}},k=t=>t.done?T(t.value):Promise.resolve(t.value).then(w,f);k((i=i.apply(r,d)).next())});import{forwardRef as Te,useImperativeHandle as ke,useRef as S,useEffect as G,useState as De,useMemo as oe}from"react";import be from"react";import{useEffect as re,useState as te,useCallback as ge,useRef as $}from"react";var l=null,b=!1,W=null,U=0,F=null,m=new Map,ye=0;function q(r,d){let i=$(!1),[T,n]=te(!1),[w,f]=te(null),k=$(!0),t=$(!1);re(()=>{n(b),f(W)},[]),re(()=>r?(k.current=!0,U++,R(null,null,function*(){var I;if(!l||!pe(F,r)){l&&(console.log("[useJerseyWorker] Terminating old worker due to config change"),l.terminate(),l=null,b=!1);try{t.current=(I=r.verbose)!=null?I:t.current,console.log(`[useJerseyWorker] Verbose set to ${t.current}`);let u=d||"/jersey-detector-worker.js";console.log(`[useJerseyWorker] Initializing worker from: ${u}`),l=new Worker(u),F=r,b=!1,W=null,n(!1),f(null),l.onmessage=o=>{let e=o.data;switch(e.type){case"ready":b=!0,n(!0),console.log(`[v0 useJerseyWorker] Worker ready: ${e.task} | ${e.model} | device: ${e.device} | dtype: ${e.dtype}`);break;case"loading_progress":t.current&&console.log(`[v0 useJerseyWorker] Loaded ${e.progress}% of ${e.file}`);break;case"debug":t.current&&console.log(e.debug_message);break;case"error":let g=e.error_message||"Unknown worker error";console.error("[v0 useJerseyWorker] Worker sent error message:",g),b=!1,W=g,n(!1),f(g);break;case"detect_response":if(e.requestId&&m.has(e.requestId)){let a=m.get(e.requestId);if(a){if(t.current){let y=e.stats;console.log(`Det count ${y.detectionCount} | Conf: ${y.averageConfidence} | proc time: ${y.processingTime}ms`)}a.resolve(e),m.delete(e.requestId)}}else if(m.size>0){let a=m.entries().next();if(!a.done){let[y,H]=a.value;H.resolve(e),m.delete(y)}}break}},l.onerror=o=>{let e=o.message||"Worker initialization error";console.error("[useJerseyWorker] Worker error:",e),b=!1,W=e,n(!1),f(e)},l.postMessage({type:"init",config:r})}catch(u){let o=(u==null?void 0:u.message)||String(u);console.error("[useJerseyWorker] Failed to create worker:",o),n(!1),f(o)}}else n(b),f(W)}),()=>{k.current=!1,U--,U<=0&&l&&(console.log("[useJerseyWorker] Terminating worker (refCount 0)"),l.terminate(),l=null,b=!1,W=null,F=null,m.clear())}):void 0,[r]);let E=ge((h,I,u=.5)=>R(null,null,function*(){if(!l||!b)throw new Error("Worker not ready");if(i.current)return console.log("[v0 useJerseyWorker] New request before detection completed"),null;let o=`req_${++ye}_${Date.now()}`;return new Promise((e,g)=>{m.set(o,{resolve:e,reject:g});try{i.current=!0,l.postMessage({type:"detect",requestId:o,dimensions:I,bitmap:h,threshold:u},[h])}catch(a){m.delete(o);let y=`Failed to send detect: ${a==null?void 0:a.message}`;g(new Error(y))}finally{i.current=!1}setTimeout(()=>{m.has(o)&&(m.delete(o),g(new Error("Detection timeout")))},1e4)})}),[T]);return{isReady:T,workerReady:T,lastError:w,detect:E}}function pe(r,d){return r?JSON.stringify(r)===JSON.stringify(d):!1}var s={TASK:"image-segmentation",MODEL:"BodyPix",BODYPIX_ARCHITECTURE:"MobileNetV1",BODYPIX_MULTIPLIER:.75,BODYPIX_QUANT_BYTES:2,BODYPIX_STRIDE:16,MULTI_SEGMENTATION:!0,SEGMENT_BODY_PARTS:!0,BACKGROUND_SHADE:0,SHIRT_SHADE:170,DETECTION_THRESHOLD:.5,TARGET_PART_ID:12,ONLY_DRAW_MASK:!0,VERBOSE:!1};var se=Te(({videoRef:r,onWorkerReady:d,onWorkerError:i,onStatsUpdate:T,onSegmentedImage:n,task:w=s.TASK,model:f=s.MODEL,verbose:k=s.VERBOSE,bodyPixArchitecture:t=s.BODYPIX_ARCHITECTURE,bodyPixMultiplier:E=s.BODYPIX_MULTIPLIER,bodyPixQuantBytes:h=s.BODYPIX_QUANT_BYTES,bodyPixStride:I=s.BODYPIX_STRIDE,multiSegmentation:u=s.MULTI_SEGMENTATION,segmentBodyParts:o=s.SEGMENT_BODY_PARTS,backgroundShade:e=s.BACKGROUND_SHADE,shirtShade:g=s.SHIRT_SHADE,threshold:a=s.DETECTION_THRESHOLD,targetPartId:y=s.TARGET_PART_ID,onlyDrawMask:H=s.ONLY_DRAW_MASK,workerUrl:ne},ie)=>{var K,V;let X=S(null),x=S(null),L=S(!1),B=S([]),ae=S(null),O=S(!1),[j,ce]=De({jerseyCount:0,confidence:0,fps:0,processingTime:0}),le=oe(()=>({task:w,model:f,verbose:k,bodyPixArchitecture:t,bodyPixMultiplier:E,bodyPixQuantBytes:h,bodyPixStride:I,multiSegmentation:u,segmentBodyParts:o,backgroundShade:e,shirtShade:g,threshold:a,targetPartId:y}),[w,f,k,t,E,h,I,u,o,e,g,a,y]),ue=oe(()=>{var c,D;return{width:((c=r.current)==null?void 0:c.videoWidth)||0,height:((D=r.current)==null?void 0:D.videoHeight)||0}},[(K=r.current)==null?void 0:K.videoWidth,(V=r.current)==null?void 0:V.videoHeight]),{isReady:_,workerReady:v,lastError:C,detect:fe}=q(le,ne);G(()=>{d==null||d(v)},[v,d]),G(()=>{C&&(O.current=!0,console.error("[v0] Worker error detected, stopping detection loop:",C)),i==null||i(C)},[C,i]);let me=()=>R(null,null,function*(){var z,Q,Z;let c=r.current,D=X.current;if(O.current||!v||!_||!c||!D||L.current||c.readyState<2||c.paused||c.ended)return;let N=null,A=null;try{L.current=!0;let M=c.videoWidth,J=c.videoHeight;ae.current={width:M,height:J},N=yield createImageBitmap(c);let p=yield fe(N,ue,a);if((p==null?void 0:p.type)==="detect_response"&&p.bitmap){A=p.bitmap;let Y=D.getContext("2d");Y&&((D.width!==M||D.height!==J)&&(D.width=M,D.height=J),H&&Y.clearRect(0,0,M,J),A&&Y.drawImage(A,0,0)),B.current.push(Date.now()),B.current=B.current.filter(P=>Date.now()-P<1e3);let ee={jerseyCount:((z=p.stats)==null?void 0:z.detectionCount)||0,confidence:((Q=p.stats)==null?void 0:Q.averageConfidence)||0,fps:B.current.length,processingTime:((Z=p.stats)==null?void 0:Z.processingTime)||0};if(ce(ee),T==null||T(ee),p.segmentedImages){let P=p.segmentedImages;R(null,null,function*(){try{yield n==null?void 0:n(P)}finally{P.forEach(de=>de.close())}})}}}catch(M){console.error("[v0] Detection error:",M),O.current=!0}finally{N&&N.close(),A&&A.close(),L.current=!1}});return G(()=>{if(!v||!_||O.current)return;let c=()=>R(null,null,function*(){!v||!_||O.current||(yield me(),x.current=requestAnimationFrame(c))});return x.current=requestAnimationFrame(c),()=>{x.current&&cancelAnimationFrame(x.current)}},[v,_]),ke(ie,()=>({isReady:_,lastError:C,stats:j}),[_,C,j]),be.createElement("canvas",{ref:X,className:"absolute inset-0 w-full h-full pointer-events-none",style:{zIndex:10}})});se.displayName="JerseyDetector";export{s as DEFAULT_CONFIG,se as JerseyDetector,q as useJerseyWorker};