1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[4950],{4950:(e,t,r)=>{r.d(t,{l:()=>p});var n=r(95155),a=r(12115),l=r(19497),s=r(1835);let o={de:{unclassified:"Nicht klassifiziert",moreSuffix:"weitere",channelKeywords:"Channel-Keywords"},fr:{unclassified:"Non class\xe9",moreSuffix:"autres",channelKeywords:"Mots-cl\xe9s du canal"},es:{unclassified:"Sin clasificar",moreSuffix:"m\xe1s",channelKeywords:"Palabras clave del canal"},it:{unclassified:"Non classificato",moreSuffix:"altri",channelKeywords:"Parole chiave del canale"},pt:{unclassified:"N\xe3o classificado",moreSuffix:"mais",channelKeywords:"Palavras-chave do canal"},nl:{unclassified:"Niet geclassificeerd",moreSuffix:"meer",channelKeywords:"Kanaal-trefwoorden"},pl:{unclassified:"Nieskategoryzowane",moreSuffix:"wiÄcej",channelKeywords:"SÅowa kluczowe kanaÅu"},en:{unclassified:"Unclassified",moreSuffix:"more",channelKeywords:"Channel Keywords"}};function i(e){return e>=1e6?(e/1e6).toFixed(1)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":e.toLocaleString()}let u=["#10b981","#3b82f6","#f59e0b","#ef4444","#8b5cf6","#ec4899","#06b6d4","#84cc16","#f97316","#6366f1","#14b8a6","#a855f7","#eab308","#22d3ee","#f43f5e","#0ea5e9","#d946ef","#65a30d","#e11d48","#7c3aed"],c={avgViews:"Avg Views",avgLikes:"Avg Likes",engagement:"Engagement"};function d(e){return null==e?"#4b5563":e<=3?"#10b981":e<=10?"#22c55e":e<=20?"#eab308":e<=35?"#f97316":"#ef4444"}function g(e,t,r){if(r===t)return"#10b981";let n=Math.max(0,Math.min(1,(e-t)/(r-t))),a=Math.round(n<.5?239:239-(n-.5)*446),l=Math.round(n<.5?68+2*n*187:185+(n-.5)*0),s=Math.round(n<.5?68:68+(n-.5)*122);return`rgb(${a},${l},${s})`}function h(e,t){if(!e.length)return[];let r=[{x:0,y:0,r:e[0]}];for(let n=1;n<e.length;n++){let a=e[n],l=0,s=0,o=1/0,i=a<6?8:a<12?5:3,u=Math.min(r.length,50);for(let e=0;e<u;e++){let n=r[e].r+a+t;for(let u=0;u<360;u+=i){let i=u*Math.PI/180,c=r[e].x+Math.cos(i)*n,d=r[e].y+Math.sin(i)*n,g=!0;for(let e=0;e<r.length;e++){let n=c-r[e].x,l=d-r[e].y;if(n*n+l*l<(a+r[e].r+t-.5)**2){g=!1;break}}if(g){let e=c*c+d*d;e<o&&(o=e,l=c,s=d)}}}r.push({x:l,y:s,r:a})}return r}let m=new Set(["Channel Identity","Channel-Identity","Channel Identity Tags","Sales Funnel & Lead Magnets","Sales Funnel","Sales-Funnel & Lead-Magnets"]),x=new Set(["Meta & Personality Tags","Meta-Tags","Meta Tags","Meta-Tag Cluster"]),f="#9ca3af";function p({videos:e,tagCategories:t=[],onClusterClick:p,onVideoBubbleClick:b,keywordData:w,channelId:y,channelTags:v=[],videoBestRanks:k,defaultExpanded:C=!1,highlightedClusters:j=null,displayLanguage:M}){let N=o[(M||"en").toLowerCase().slice(0,2)]??o.en,S=(0,a.useMemo)(()=>j&&0!==j.length?new Set(j.map(e=>(e||"").trim().toLowerCase())):null,[j]),[L,E]=(0,a.useState)(v.length>0?"both":"video"),[R,$]=(0,a.useState)(t);(0,a.useEffect)(()=>{$(t)},[t]);let[V,T]=(0,a.useState)(null),[A,_]=(0,a.useState)(""),[F,P]=(0,a.useState)(null),[z,K]=(0,a.useState)(""),[U,I]=(0,a.useState)(null),[O,D]=(0,a.useState)("idle"),B=(0,a.useRef)(null),Y=(0,a.useCallback)(async e=>{if(y){D("saving");try{let t=await fetch(`/api/channels/${y}/video-tag-categories`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({categories:e})});if(!t.ok){let e=await t.json().catch(()=>({}));console.error("[BubbleChart] save failed:",e),D("error");return}D("saved"),B.current&&clearTimeout(B.current),B.current=setTimeout(()=>D("idle"),2500)}catch(e){console.error("[BubbleChart] save threw:",e),D("error")}}},[y]);(0,a.useEffect)(()=>()=>{B.current&&clearTimeout(B.current)},[]);let X=(0,a.useCallback)((e,t)=>{let r=t.trim();r&&r!==e&&$(t=>{let n=t.map(t=>t.name===e?{...t,name:r}:t);return Y(n),n})},[Y]),q=(0,a.useCallback)((e,t,r)=>{let n=r.trim();n&&n!==t&&$(r=>{let a=r.map(r=>r.name!==e?r:{...r,tags:r.tags.map(e=>e.tag===t?{...e,tag:n}:e)});return Y(a),a})},[Y]),{uiLanguage:W}=(0,s.ok)(),[H,G]=(0,a.useState)(null),[J,Q]=(0,a.useState)(null),[Z,ee]=(0,a.useState)("category"),[et,er]=(0,a.useState)("avgViews"),en=!!k&&Object.keys(k).length>0;(0,a.useEffect)(()=>{en||"rank"!==Z||ee("category")},[en,Z]);let ea=(0,a.useMemo)(()=>
1{if(!en||!e?.length)return new Map;let t=new Map;for(let r of e){if(!r.id)continue;let e=k[r.id];if(e&&null!=e.rank)for(let n of[...r.tags||[],...r.hashtags||[]]){let r=n.toLowerCase().replace(/#/g,"").trim();if(r.length<2)continue;let a=t.get(r);(!a||e.rank<a.rank)&&t.set(r,{rank:e.rank,keyword:e.keyword})}}return t},[en,e,k]),[el,es]=(0,a.useState)("off"),[eo,ei]=(0,a.useState)("xViews"),eu=(0,a.useCallback)(e=>"xViews"===e?"xViewsMax":"xLikes"===e?"xLikesMax":"xComments"===e?"xCommentsMax":"xEngMax",[]),ec=(0,a.useCallback)(e=>"xViews"===e?"xViews":"xLikes"===e?"xLikes":"xComments"===e?"xComments":"xEng",[]),[ed,eg]=(0,a.useState)(!C),[eh,em]=(0,a.useState)(!0),[ex,ef]=(0,a.useState)(!1),ep=(0,a.useRef)(null),eb=(0,a.useRef)(!1);(0,a.useEffect)(()=>{let e=!1;return fetch("/api/me/bubble-chart-prefs").then(e=>e.ok?e.json():null).then(t=>{if(e)return;let r=t?.prefs??{};"string"==typeof r.colorMode&&ee(r.colorMode),"string"==typeof r.perfMetric&&er(r.perfMetric),"string"==typeof r.outlierStyle&&es(r.outlierStyle),"string"==typeof r.outlierMetric&&ei(r.outlierMetric),"boolean"==typeof r.showFill&&em(r.showFill),"boolean"==typeof r.collapsedSmallClusters&&eg(r.collapsedSmallClusters),"string"==typeof r.tagSource&&E(r.tagSource),eb.current=!0}).catch(()=>{eb.current=!0}),()=>{e=!0}},[]);let ew=(0,a.useRef)(null);(0,a.useEffect)(()=>{if(eb.current)return ew.current&&clearTimeout(ew.current),ew.current=setTimeout(()=>{fetch("/api/me/bubble-chart-prefs",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({colorMode:Z,perfMetric:et,outlierStyle:el,outlierMetric:eo,showFill:eh,collapsedSmallClusters:ed,tagSource:L})})},500),()=>{ew.current&&clearTimeout(ew.current)}},[Z,et,el,eo,eh,ed,L]);let[ey,ev]=(0,a.useState)([]);(0,a.useEffect)(()=>{!y||w?.length||fetch(`/api/channels/${y}/keyword-data`).then(e=>e.ok?e.json():null).then(e=>{e?.keywords&&ev(e.keywords)}).catch(()=>{})},[y,w]);let ek=w?.length?w:ey,eC=(0,a.useMemo)(()=>{let e=new Map;for(let t of ek)e.set(t.keyword.toLowerCase(),t);return e},[ek]),ej=(0,a.useMemo)(()=>(function(e){let t=new Map,r=new Date,n=new Date(r.getFullYear(),r.getMonth()-3,r.getDate()),a=new Date(r.getFullYear(),r.getMonth()-6,r.getDate()),l=new Map,s=new Map;for(let t of e){if(!t.publishedAt||!t.tags)continue;let e=new Date(t.publishedAt);for(let r of t.tags){let t=r.toLowerCase().trim();!(t.length<2)&&(e>=n?l.set(t,(l.get(t)||0)+1):e>=a&&s.set(t,(s.get(t)||0)+1))}}for(let e of new Set([...l.keys(),...s.keys()])){let r=l.get(e)||0,n=s.get(e)||0;0===n&&r>0?t.set(e,100):n>0&&t.set(e,Math.round((r-n)/n*100))}return t})(e),[e]),eM=(0,a.useMemo)(()=>{if(!v||0===v.length)return null;let e=v.map(e=>(e||"").trim()).filter(e=>e.length>1).map(e=>({tag:e,count:1,avgViews:0,avgLikes:0,engagement:0}));return 0===e.length?null:{name:N.channelKeywords,tags:e,totalCount:e.length,color:"#f97316"}},[v,N.channelKeywords]),{clusters:eN,uncategorized:eS,totalKeywords:eL}=(0,a.useMemo)(()=>{if("channel"===L)return{clusters:eM?[eM]:[],uncategorized:[],totalKeywords:eM?eM.tags.length:0};if(!e?.length)return"both"===L&&eM?{clusters:[eM],uncategorized:[],totalKeywords:eM.tags.length}:{clusters:[],uncategorized:[],totalKeywords:0};let t=new Map;for(let r of e)for(let e of[...r.tags||[],...r.hashtags||[]]){let n=e.toLowerCase().replace(/#/g,"").trim();if(n.length<2)continue;let a=t.get(n)||{count:0,views:0,likes:0,xViews:0,xLikes:0,xComments:0,xEng:0};a.count++,a.views+=r.viewCount||0,a.likes+=r.likeCount||0,"number"==typeof r.xViews&&r.xViews>a.xViews&&(a.xViews=r.xViews),"number"==typeof r.xLikes&&r.xLikes>a.xLikes&&(a.xLikes=r.xLikes),"number"==typeof r.xComments&&r.xComments>a.xComments&&(a.xComments=r.xComments),"number"==typeof r.xEng&&r.xEng>a.xEng&&(a.xEng=r.xEng),t.set(n,a)}let r=Array.from(t.entries()).filter(([,e])=>e.count>=1).map(([e,t])=>({tag:e,count:t.count,avgViews:Math.round(t.views/t.count),avgLikes:Math.round(t.likes/t.count),engagement:t.views>0?Math.round(t.likes/t.views*1e4)/100:0,trend:ej.get(e),xViewsMax:t.xViews>0?t.xViews:null,xLikesMax:t.xLikes>0?t.xLikes:null,xCommentsMax:t.xComments>0?t.xComments:null,xEngMax:t.xEng>0?t.xEng:null})).sort((e,t)=>
1t.count-e.count);if(R.length>0){let e=new Set,n=[],a=[],l=[];for(let r of R){if("Miscellaneous"===r.name)continue;if("Unclassified"===r.name||"Nicht klassifiziert"===r.name||"Non class\xe9"===r.name||"Sin clasificar"===r.name||"Non classificato"===r.name||"N\xe3o classificado"===r.name||"Niet geclassificeerd"===r.name||"Nieskategoryzowane"===r.name){for(let n of r.tags){let r=n.tag.toLowerCase().replace(/#/g,"").trim();if(e.has(r))continue;let a=t.get(r);l.push(a?{tag:n.tag,count:a.count,avgViews:Math.round(a.views/a.count),avgLikes:Math.round(a.likes/a.count),engagement:a.views>0?Math.round(a.likes/a.views*1e4)/100:0,trend:ej.get(r)}:{tag:n.tag,count:n.count,avgViews:0,avgLikes:0,engagement:0,trend:ej.get(r)}),e.add(r)}continue}if(x.has(r.name)){for(let t of r.tags)e.add(t.tag.toLowerCase().replace(/#/g,"").trim());continue}let s=m.has(r.name),o=[];for(let n of r.tags){let r=n.tag.toLowerCase().replace(/#/g,"").trim();if(e.has(r))continue;let a=t.get(r);a?(o.push({tag:n.tag,count:a.count,avgViews:Math.round(a.views/a.count),avgLikes:Math.round(a.likes/a.count),engagement:a.views>0?Math.round(a.likes/a.views*1e4)/100:0,trend:ej.get(r),xViewsMax:a.xViews>0?a.xViews:null,xLikesMax:a.xLikes>0?a.xLikes:null,xCommentsMax:a.xComments>0?a.xComments:null,xEngMax:a.xEng>0?a.xEng:null,...s?{colorOverride:f}:{}}),e.add(r)):n.count>=1&&(o.push({tag:n.tag,count:n.count,avgViews:0,avgLikes:0,engagement:0,trend:ej.get(r),...s?{colorOverride:f}:{}}),e.add(r))}if(s){a.push(...o);continue}o.length>0&&(o.sort((e,t)=>t.count-e.count),n.push({name:r.name,tags:o,totalCount:o.reduce((e,t)=>e+t.count,0),color:u[n.length%u.length]}))}n.sort((e,t)=>t.totalCount-e.totalCount);let s=null;if(eM||a.length>0){let e=eM?.tags||[],t=new Set(e.map(e=>e.tag.toLowerCase().replace(/#/g,"").trim())),r=[...e,...a.filter(e=>{let r=e.tag.toLowerCase().replace(/#/g,"").trim();return!t.has(r)&&(t.add(r),!0)})];r.length>0&&(s={name:N.channelKeywords,tags:r,totalCount:r.length,color:"#f97316"})}let o="both"===L&&s?[s,...n]:n,i=r.filter(t=>!e.has(t.tag.toLowerCase())).slice(0,2e3),c=new Set(i.map(e=>e.tag.toLowerCase()));return{clusters:o,uncategorized:[...i,...l.filter(e=>!c.has(e.tag.toLowerCase()))].sort((e,t)=>t.count-e.count),totalKeywords:r.length}}let n=function(e){let t=new Set,r=[],n=e.map((e,t)=>({...e,idx:t})).sort((e,t)=>t.count-e.count);for(let e of n){if(t.has(e.idx))continue;let a=[e];for(let r of(t.add(e.idx),n))!t.has(r.idx)&&function(e,t){let r=e.toLowerCase(),n=t.toLowerCase();if(r===n)return 1;if(r.includes(n)||n.includes(r))return .7;let a=new Set(r.split(/[\s\-_]+/)),l=new Set(n.split(/[\s\-_]+/)),s=0;for(let e of a)e.length>2&&l.has(e)&&s++;return s>0?.5*s/Math.max(a.size,l.size):0}(e.tag,r.tag)>=.35&&(a.push(r),t.add(r.idx));r.push({name:e.tag,tags:a.sort((e,t)=>t.count-e.count),totalCount:a.reduce((e,t)=>e+t.count,0),color:u[r.length%u.length]})}return r.sort((e,t)=>t.totalCount-e.totalCount)}(r.slice(0,500));return{clusters:"both"===L&&eM?[eM,...n]:n,uncategorized:r.slice(500,1e3),totalKeywords:r.length}},[e,R,ej,L,eM]),{visibleClusters:eE,spilledFromSmall:eR}=(0,a.useMemo)(()=>{if(!ed)return{visibleClusters:eN,spilledFromSmall:[]};let e=eN.filter(e=>"#f97316"===e.color||e.tags.length>=5),t=eN.filter(e=>"#f97316"!==e.color&&e.tags.length<5);return 0===t.length?{visibleClusters:eN,spilledFromSmall:[]}:{visibleClusters:e,spilledFromSmall:t.flatMap(e=>e.tags).sort((e,t)=>t.count-e.count)}},[eN,ed]),e$=(0,a.useMemo)(()=>{let t=new Map;if(!e||0===e.length)return t;let r=ec(eo),n=new Map;for(let e of eE)n.set(e.name,new Set(e.tags.map(e=>e.tag.toLowerCase().replace(/#/g,"").trim())));for(let a of e){let e=a[r];if("number"!=typeof e||e<2)continue;let l=[...a.tags||[],...a.hashtags||[]].map(e=>e.toLowerCase().replace(/#/g,"").trim());for(let[r,a]of n)if(l.some(e=>a.has(e))){let n=t.get(r)||{count:0,sum:0};n.count++,n.sum+=e,t.set(r,n)}}return t},[e,eE,eo,ec]),eV=(0,a.useMemo)(()=>{if(0===eR.length)return eS;let e=new Set(eS.map(e=>e.tag.toLowerCase().replace(/#/g,"").trim()));return[...eS,...eR.filter(t=>{let r=t.tag.toLowerCase().replace(/#/g,"").trim();return!e.has(r)&&(e.add(r),!0)})].sort((e,t)=>
1t.count-e.count)},[eS,eR]),{minPerf:eT,maxPerf:eA}=(0,a.useMemo)(()=>{let e=[...eE.flatMap(e=>e.tags.map(e=>e[et])),...eV.map(e=>e[et])].filter(e=>e>0);return{minPerf:Math.min(...e,0),maxPerf:Math.max(...e,1)}},[eE,eV,et]),{clusterLayouts:e_,fillBubbles:eF,containerR:eP}=(0,a.useMemo)(()=>{if(!eE.length&&!eV.length)return{clusterLayouts:[],fillBubbles:[],containerR:400};let e=Math.max(...eE.flatMap(e=>e.tags.map(e=>e.count)),...eV.map(e=>e.count),1),t=eE.map(t=>{let r=t.tags.map(t=>Math.max(4,Math.round(5+45*Math.sqrt(t.count/e)))),{circles:n,boundR:a}=function(e){if(!e.length)return{circles:[],boundR:0};let t=1/0,r=-1/0,n=1/0,a=-1/0;for(let l of e)t=Math.min(t,l.x-l.r),r=Math.max(r,l.x+l.r),n=Math.min(n,l.y-l.r),a=Math.max(a,l.y+l.r);let l=(t+r)/2,s=(n+a)/2,o=e.map(e=>({x:e.x-l,y:e.y-s,r:e.r})),i=0;for(let e of o)i=Math.max(i,Math.sqrt(e.x*e.x+e.y*e.y)+e.r);return{circles:o,boundR:i+.5}}(h(r,1.5));return{cluster:t,innerPacked:n,tagRadii:r,naturalR:a}}),r=t.map(e=>e.naturalR),n=h(r,5).map((e,t)=>({...e,r:r[t]})),a=1/0,l=-1/0,s=1/0,o=-1/0;for(let e of n)a=Math.min(a,e.x-e.r),l=Math.max(l,e.x+e.r),s=Math.min(s,e.y-e.r),o=Math.max(o,e.y+e.r);let i=(a+l)/2,c=(s+o)/2,d=function(e,t){if(!e.length)return[];let r=0;for(let t of e)r=Math.max(r,Math.sqrt(t.x*t.x+t.y*t.y)+t.r);
1if(r<=415)return e;let n=t/r;return e.map(e=>({x:e.x*n,y:e.y*n,r:e.r*n}))}(n.map(e=>({x:e.x-i,y:e.y-c,r:e.r})),415),g=t.map((e,t)=>{let r=d[t]||{x:0,y:0,r:e.naturalR},n=function(e,t,r){if(!e.length||0===t)return e;let n=r/t;return e.map(e=>({x:e.x*n,y:e.y*n,r:e.r*n}))}(e.innerPacked,e.naturalR,r.r),a=0;for(let e of n)a=Math.max(a,Math.sqrt(e.x*e.x+e.y*e.y)+e.r);return{...e,cx:r.x,cy:r.y,displayR:a+1,scaledInner:n}}),m=[];if(eV.length>0){let t=[];for(let e of g)t.push({x:e.cx,y:e.cy,r:e.displayR});let r=0;for(let e of g)r=Math.max(r,Math.sqrt(e.cx**2+e.cy**2)+e.displayR);let n=r,a=.6*n,l=e=>1.618033988749895*e*360%360*Math.PI/180,s=(e,t,r,l)=>{let s=Math.sqrt(e*e+t*t);if(s+r>n+.5||s<a)return!1;for(let n of l){if(0===n.r)continue;let a=e-n.x,l=t-n.y;if(a*a+l*l<(r+n.r+1)**2)return!1}return!0},o=(e,t,r)=>{let n=1/0;for(let a of r){if(0===a.r)continue;let r=e-a.x,l=t-a.y,s=Math.sqrt(r*r+l*l)-a.r;s<n&&(n=s)}return n},i=[...eV].sort((e,t)=>t.count-e.count);for(let r=0;r<i.length;r++){let c=i[r],d=Math.max(3.5,Math.round(3.5+14*Math.sqrt(c.count/e))),g=u[(3*r+7)%u.length],h=0,x=0,f=-1/0;for(let e=0;e<8;e++){let i=n-d-e*(1.5*d+1);if(i<a)break;for(let e=0;e<150;e++){let n=l(r)+2.4*e,a=Math.cos(n)*i,u=Math.sin(n)*i;if(!s(a,u,d,t))continue;let c=2*o(a,u,t)+.3*Math.sqrt(a*a+u*u);c>f&&(f=c,h=a,x=u)}if(f>0)break}if(f<0)for(let e=0;e<Math.min(t.length,60);e++){if(0===t[e].r)continue;let n=t[e].r+d+1.5;for(let a=0;a<40;a++){let i=l(60*r+40*e+a)+2.4*a,u=t[e].x+Math.cos(i)*n,c=t[e].y+Math.sin(i)*n;if(!s(u,c,d,t))continue;let g=2*o(u,c,t)+.3*Math.sqrt(u*u+c*c);g>f&&(f=g,h=u,x=c)}}f>-1/0&&(t.push({x:h,y:x,r:d}),m.push({...c,x:h,y:x,r:d,color:g}))}}let x=0;for(let e of g)x=Math.max(x,Math.sqrt(e.cx**2+e.cy**2)+e.displayR);for(let e of m)x=Math.max(x,Math.sqrt(e.x**2+e.y**2)+e.r);return{clusterLayouts:g,fillBubbles:m,containerR:Math.max(420,x+1)}},[eE,eS]),ez=(0,a.useCallback)(async()=>{if(ep.current)try{let{default:e}=await r.e(14316).then(r.t.bind(r,54264,23)),t=await e(ep.current,{backgroundColor:"#000",scale:2}),n=document.createElement("a");n.download="bubble-chart.png",n.href=t.toDataURL("image/png"),n.click()}catch{alert("Export failed. Install html2canvas: npm i html2canvas")}},[]),eK=(0,a.useCallback)(()=>{let e=[["Tag","Count","Avg Views","Avg Likes","Engagement %","Cluster","Trend %","CPC","Search Volume"]];for(let t of eN)for(let r of t.tags){let n=eC.get(r.tag.toLowerCase());e.push([r.tag,String(r.count),String(r.avgViews),String(r.avgLikes),String(r.engagement),t.name,null!=r.trend?String(r.trend):"",n?.cpc||"",n?.vol!=null?String(n.vol):""])}for(let t of eS){let r=eC.get(t.tag.toLowerCase());e.push([t.tag,String(t.count),String(t.avgViews),String(t.avgLikes),String(t.engagement),"(uncategorized)",null!=t.trend?String(t.trend):"",r?.cpc||"",r?.vol!=null?String(r.vol):""])}let t=new Blob([e.map(e=>e.map(e=>`"${e.replace(/"/g,'""')}"`).join(",")).join("\n")],{type:"text/csv"}),r=document.createElement("a");r.download="bubble-chart-tags.csv",r.href=URL.createObjectURL(t),r.click(),URL.revokeObjectURL(r.href)},[eN,eS,eC]),[eU,eI]=(0,a.useState)(null),[eO,eD]=(0,a.useState)(null),eB=(0,a.useRef)(null),eY=(0,a.useCallback)(e=>{eB.current=e},[]),eX=(0,a.useRef)(null),eq=(0,a.useMemo)(()=>{let e=new Map;for(let t of R)for(let r of t.tags)e.set(r.tag,t.name);return e},[R]),eW=(0,a.useCallback)(e=>{for(let t of Object.values(o))if(e===t.channelKeywords||e.startsWith("+")&&e.endsWith(" "+t.moreSuffix))return!0;return!!("Channel Keywords"===e||e.startsWith("+")&&e.endsWith(" more"))},[]),eH=(0,a.useCallback)((e,t,r,n)=>{(t!==r||null===t)&&$(a=>{let l=a.map(e=>({...e,tags:[...e.tags]}));if(null!==t&&(l=l.map(r=>r.name!==t?r:{...r,tags:r.tags.filter(t=>t.tag!==e)}).filter(e=>e.tags.length>0)),null!==r){let t=l.findIndex(e=>e.name===r);t>=0&&!l[t].tags.find(t=>t.tag===e)&&(l[t]={...l[t],tags:[...l[t].tags,{tag:e,count:n}]})}else l.find(t=>t.name===e)||l.push({name:e,tags:[{tag:e,count:n}]});return Y(l),l})},[Y]),eG=(0,a.useCallback)((e,t,r,n)=>{null!==r&&eW(r)||(eX.current={tag:t,fromCluster:r,count:n,startX:e.clientX,startY:e.clientY,activated:!1},e.preventDefault())},[eW]),eJ=(0,a.useCallback)((e,t)=>{let r=ep.current?.getBoundingClientRect();return r?{x:e-r.left-eP,y:t-r.top-eP,rect:r}:null},[eP]),eQ=(0,a.useCallback)((e,t)=>{for(let r of e_){if(eW(r.cluster.name))continue;let n=e-r.cx,a=t-r.cy;if(n*n+a*a<r.displayR*r.displayR)return r.cluster.name}return null},[e_,eW]);(0,a.useEffect)(()=>{let e=e=>{if(!eX.current)return;if(!eX.current.activated){let t=e.clientX-eX.current.startX,r=e.clientY-eX.current.startY;
1if(t*t+r*r<25)return;eX.current.activated=!0}let t=eJ(e.clientX,e.clientY);if(!t||!eX.current)return;let r=!!t.rect&&e.clientX>=t.rect.left&&e.clientX<=t.rect.right&&e.clientY>=t.rect.top&&e.clientY<=t.rect.bottom;eI({tag:eX.current.tag,fromCluster:eX.current.fromCluster,count:eX.current.count,currentX:t.x,currentY:t.y}),r?eD(eQ(t.x,t.y)||"__empty__"):eD(null)},t=e=>{let t=eX.current;if(eX.current=null,t&&t.activated){let r=eJ(e.clientX,e.clientY);if(r&&e.clientX>=r.rect.left&&e.clientX<=r.rect.right&&e.clientY>=r.rect.top&&e.clientY<=r.rect.bottom&&r){let e=eQ(r.x,r.y);eH(t.tag,t.fromCluster,e,t.count)}else if(eB.current){let e=eB.current;e!==t.fromCluster&&eH(t.tag,t.fromCluster,e,t.count)}}eI(null),eD(null),eB.current=null};return window.addEventListener("mousemove",e),window.addEventListener("mouseup",t),()=>{window.removeEventListener("mousemove",e),window.removeEventListener("mouseup",t)}},[eJ,eQ,eH]);let eZ=(e,t)=>{let r=eC.get(e.tag.toLowerCase()),a=e.tag.toLowerCase().replace(/#/g,"").trim(),l=en?ea.get(a):void 0;return(0,n.jsxs)("div",{className:"absolute bottom-full mb-2 left-1/2 -translate-x-1/2 bg-card border border-border rounded-lg px-3 py-2 text-xs pointer-events-none whitespace-nowrap z-[100] shadow-xl",children:[(0,n.jsxs)("div",{className:"font-semibold text-foreground flex items-center gap-1",children:[e.tag,null!=e.trend&&0!==e.trend&&(0,n.jsxs)("span",{className:e.trend>0?"text-green-400":"text-red-400",children:[e.trend>0?"â":"â",Math.abs(e.trend),"%"]})]}),(0,n.jsxs)("div",{className:"text-muted-foreground mt-0.5",children:[e.count," videos \xb7 ",i(e.avgViews)," avg views \xb7 ",i(e.avgLikes)," avg likes"]}),e.engagement>0&&(0,n.jsxs)("div",{className:"text-muted-foreground",children:[e.engagement,"% engagement"]}),t&&(0,n.jsx)("div",{className:"text-muted-foreground",children:t}),l&&(0,n.jsxs)("div",{className:"text-muted-foreground mt-0.5 border-t border-border pt-0.5",children:["Best rank: ",(0,n.jsxs)("span",{style:{color:d(l.rank)},className:"font-semibold",children:["#",l.rank]}),l.keyword&&(0,n.jsxs)("span",{children:[" \xb7 via â",l.keyword,"â"]})]}),r&&(null!=r.vol||r.cpc)&&(0,n.jsxs)("div",{className:"text-muted-foreground mt-0.5 border-t border-border pt-0.5",children:[null!=r.vol&&(0,n.jsxs)("span",{children:["Vol: ",i(r.vol),"/mo"]}),null!=r.vol&&r.cpc&&(0,n.jsx)("span",{children:" \xb7 "}),r.cpc&&(0,n.jsxs)("span",{children:["CPC: $",r.cpc]})]})]})};if(!eN.length&&!eS.length)return(0,n.jsx)("div",{className:"text-sm text-muted-foreground text-center py-8",children:"Not enough tag data for bubble chart"});let e0=2*eP;return(0,n.jsxs)("div",{className:"space-y-4",children:[(0,n.jsxs)("div",{className:"flex items-center gap-2 flex-wrap",children:[(0,n.jsxs)("p",{className:"text-xs text-muted-foreground",children:[eE.length," clusters \xb7 ",eL," keywords",eS.length>0&&(0,n.jsxs)("span",{title:eF.length!==eS.length?`${eF.length-eS.length} additional outer-ring bubbles from collapsed small clusters`:void 0,children:[" \xb7 ",eS.length," unclassified"]})]}),v.length>0&&(0,n.jsx)("div",{className:"inline-flex rounded-md border border-border overflow-hidden ml-2",children:["video","channel","both"].map(e=>(0,n.jsx)("button",{type:"button",onClick:()=>E(e),className:`text-[10px] px-2 py-0.5 transition-colors ${L===e?"bg-blue-600 text-white":"bg-muted text-muted-foreground hover:text-foreground"} ${"video"!==e?"border-l border-border":""}`,title:"video"===e?"Show aggregated video tags only":"channel"===e?"Show Channel Keywords only":"Show both â Channel Keywords on top",children:"video"===e?"Video Tags":"channel"===e?"Channel Tags":"Both"},e))}),(0,n.jsx)("div",{className:"flex-1"}),"idle"!==O&&(0,n.jsxs)("span",{className:`text-[10px] px-2 py-0.5 rounded border transition-colors inline-flex items-center gap-1 ${"saving"===O?"bg-amber-500/15 border-amber-500/40 text-amber-300":"saved"===O?"bg-emerald-500/15 border-emerald-500/40 text-emerald-300":"bg-red-500/15 border-red-500/40 text-red-300"}`,title:"saving"===O?"Saving + reclassifying videosâ¦":"saved"===O?"Saved. Videos re-classified.":"Save failed â try again or check console.",children:["saving"===O&&(0,n.jsx)("span",{className:"inline-block h-1.5 w-1.5 rounded-full bg-amber-400 animate-pulse"}),"saved"===O&&"â ","error"===O&&"â ","saving"===O?"Savingâ¦":"saved"===O?"Saved":"Save failed"]}),(0,n.jsx)("button",{onClick:()=>em(e=>!e),className:`text-[10px] px-2 py-0.5 rounded border transition-colors ${eh?"bg-blue-600/20 border-blue-500/40 text-blue-300":"bg-muted border-border text-muted-foreground hover:text-foreground"}`,children:eh?"Fill On":"Fill Off"}),(0,n.jsx)("button",{onClick:()=>ee(e=>
1"category"===e?"performance":"performance"===e&&en?"rank":"category"),className:`text-[10px] px-2 py-0.5 rounded border transition-colors ${"performance"===Z?"bg-emerald-600/20 border-emerald-500/40 text-emerald-300":"rank"===Z?"bg-amber-600/20 border-amber-500/40 text-amber-300":"bg-muted border-border text-muted-foreground hover:text-foreground"}`,title:en?"Click to cycle: Category â Performance â Best Rank":"Click to toggle Category / Performance",children:"category"===Z?"Category":"rank"===Z?"Best Rank":c[et]}),"performance"===Z&&(0,n.jsxs)("select",{value:et,onChange:e=>er(e.target.value),className:"text-[10px] bg-muted border border-border rounded px-1.5 py-0.5 text-foreground",children:[(0,n.jsx)("option",{value:"avgViews",children:"Avg Views"}),(0,n.jsx)("option",{value:"avgLikes",children:"Avg Likes"}),(0,n.jsx)("option",{value:"engagement",children:"Engagement %"})]}),(0,n.jsxs)("button",{onClick:()=>es(e=>"off"===e?"number":"number"===e?"shade":"off"),className:`text-[10px] px-2 py-0.5 rounded border transition-colors ${"number"===el?"bg-blue-600/20 border-blue-500/40 text-blue-300":"shade"===el?"bg-blue-600/30 border-blue-500/60 text-blue-200":"bg-muted border-border text-muted-foreground hover:text-foreground"}`,title:"Cycle outlier-multiplier overlay: Off â Number (write the multiplier in each bubble) â Shade (darken bubbles where the multiplier is high)",children:["\xd7Stats: ","off"===el?"Off":"number"===el?"Number":"Shade"]}),"off"!==el&&(0,n.jsxs)("select",{value:eo,onChange:e=>ei(e.target.value),className:"text-[10px] bg-muted border border-border rounded px-1.5 py-0.5 text-foreground",title:"Which x-stat to surface",children:[(0,n.jsx)("option",{value:"xViews",children:"\xd7Views"}),(0,n.jsx)("option",{value:"xLikes",children:"\xd7Likes"}),(0,n.jsx)("option",{value:"xComments",children:"\xd7Comments"}),(0,n.jsx)("option",{value:"xEng",children:"\xd7Engagement"})]}),eN.filter(e=>e.tags.length<5).length>1&&(0,n.jsx)("button",{onClick:()=>eg(e=>!e),className:"text-[10px] px-2 py-0.5 rounded border border-border text-muted-foreground hover:text-foreground transition-colors",children:ed?"Expand All":"Collapse Small"}),(0,n.jsx)("button",{onClick:ez,className:"text-[10px] px-2 py-0.5 rounded border border-border text-muted-foreground hover:text-foreground transition-colors",children:"PNG"}),(0,n.jsx)("button",{onClick:eK,className:"text-[10px] px-2 py-0.5 rounded border border-border text-muted-foreground hover:text-foreground transition-colors",children:"CSV"}),(0,n.jsx)("button",{onClick:()=>ef(e=>!e),className:`text-[10px] w-5 h-5 rounded-full border transition-colors flex items-center justify-center ${ex?"bg-blue-600 border-blue-500 text-white":"border-border text-muted-foreground hover:text-foreground"}`,title:"How to read this chart",children:"?"})]}),ex&&(0,n.jsxs)("div",{className:"bg-muted/30 border border-border rounded-lg p-4 text-xs text-muted-foreground space-y-3",children:[(0,n.jsxs)("div",{className:"flex items-center justify-between",children:[(0,n.jsxs)("div",{className:"flex items-center gap-2",children:[(0,n.jsx)("h4",{className:"text-sm font-semibold text-foreground",children:"How to Read This Chart"}),(0,n.jsx)(l.b,{helpKey:"bubble-chart-help",lang:W})]}),(0,n.jsx)("button",{onClick:()=>ef(!1),className:"text-muted-foreground hover:text-foreground",children:"x"})]}),(0,n.jsxs)("div",{className:"grid sm:grid-cols-2 gap-3",children:[(0,n.jsxs)("div",{children:[(0,n.jsx)("h5",{className:"font-medium text-foreground mb-1",children:"Bubble Size"}),(0,n.jsx)("p",{children:"Each bubble represents a tag/keyword. Larger bubbles = more videos use this tag. A tag appearing in 50 videos is much larger than one in 5."})]}),(0,n.jsxs)("div",{children:[(0,n.jsx)("h5",{className:"font-medium text-foreground mb-1",children:"Clusters (Colored Groups)"}),(0,n.jsx)("p",{children:"Tags are grouped into thematic clusters by AI categorization. The cluster border shows the group boundary. Click a cluster to filter by those tags."})]}),(0,n.jsxs)("div",{children:[(0,n.jsx)("h5",{className:"font-medium text-foreground mb-1",children:"Fill Bubbles (Outer Ring)"}),(0,n.jsx)("p",{children:"Small colorful bubbles around the edges are uncategorized tags that didn't fit any cluster. Hover to see details."})]}),(0,n.jsxs)("div",{children:[(0,n.jsx)("h5",{className:"font-medium text-foreground mb-1",children:"Trend Arrows"}),(0,n.jsx)("p",{children:"Hover a bubble to see trend data. Green arrow up = tag used more in the last 3 months vs. prior 3 months. Red arrow down = declining usage."})]}),(0,n.jsxs)("div",{children:[(0,n.jsx)("h5",{className:"font-medium text-foreground mb-1",children:"Color Modes"}),(0,n.jsxs)("p",{children:[(0,n.jsx)("strong",{children:"Category:"})," Each cluster has its own color. ",(0,n.jsx)("strong",{children:"Performance:"})," Colors show metrics â green = high value, red = low. Choose between Avg Views, Avg Likes, or Engagement %."]})]}),(0,n.jsxs)("div",{children:[(0,n.jsx)("h5",{className:"font-medium text-foreground mb-1",children:"CPC & Search Volume"}),(0,n.jsx)("p",{children:"If keyword research data exists, hovering shows monthly search volume and cost-per-click from Keywords Everywhere â useful for SEO prioritization."})]})]}),(0,n.jsxs)("div",{className:"border-t border-border pt-2",children:[(0,n.jsx)("h5",{className:"font-medium text-foreground mb-1",children:"What Can You Learn?"}),(0,n.jsxs)("ul",{className:"list-disc pl-4 space-y-1",children:[(0,n.jsxs)("li",{children:[(0,n.jsx)("strong",{children:"Content gaps:"}
1)," Small clusters with high engagement may be underserved topics worth exploring"]}),(0,n.jsxs)("li",{children:[(0,n.jsx)("strong",{children:"Over-used tags:"})," Very large bubbles with low views suggest saturated keywords"]}),(0,n.jsxs)("li",{children:[(0,n.jsx)("strong",{children:"Trending topics:"})," Tags with green arrows are growing â consider creating more content around them"]}),(0,n.jsxs)("li",{children:[(0,n.jsx)("strong",{children:"SEO opportunities:"})," Tags with high search volume but low CPC are cheap to target"]}),(0,n.jsxs)("li",{children:[(0,n.jsx)("strong",{children:"Channel identity:"})," The largest cluster reveals what your channel is primarily known for"]})]})]})]}),(0,n.jsx)("div",{className:"flex justify-center overflow-visible",children:(0,n.jsxs)("div",{ref:ep,className:"relative",style:{width:e0,height:e0},children:[eh&&eF.map(e=>{let t=H===e.tag,r=eU?.tag===e.tag,a="performance"===Z?g(e[et],eT,eA):"rank"===Z?d(ea.get(e.tag.toLowerCase().replace(/#/g,"").trim())?.rank??null):e.color;return(0,n.jsxs)("div",{className:"absolute rounded-full transition-all duration-150",style:{width:2*e.r,height:2*e.r,left:eP+e.x-e.r,top:eP+e.y-e.r,backgroundColor:a,opacity:r?.2:t?1:.5,transform:t&&!r?"scale(1.2)":"scale(1)",zIndex:t?50:1,cursor:eU?"grabbing":"grab",touchAction:"none"},onMouseDown:t=>eG(t,e.tag,null,e.count),onMouseEnter:()=>G(e.tag),onMouseLeave:()=>G(null),children:[t&&!eU&&eZ(e),t&&!eU&&e.r>=4&&(0,n.jsx)("button",{type:"button",title:"Promote to own cluster",onMouseDown:e=>e.stopPropagation(),onClick:t=>{t.stopPropagation(),eH(e.tag,null,null,e.count)},className:"absolute -top-2 -right-2 w-5 h-5 rounded-full bg-blue-600 hover:bg-blue-500 text-white text-[11px] flex items-center justify-center shadow-lg z-[60] border border-white/30",style:{cursor:"pointer"},children:"+"})]},`fill-${e.tag}`)}),e_.map(t=>{var r;let a=J===t.cluster.name,l=null!=eU&&eO===t.cluster.name;eW(t.cluster.name);let s=t.cluster.color,o=Math.max(1.5,Math.min(3,t.displayR/50)),i=!!p,u=(r=t.cluster.name,!!S&&!S.has((r||"").trim().toLowerCase()));return(0,n.jsxs)("div",{style:{opacity:u?.25:1,transition:"opacity 200ms ease"},children:[t.cluster.tags.length>1&&(0,n.jsx)("div",{className:`absolute rounded-full ${i?"cursor-pointer":"pointer-events-none"}`,style:{width:(t.displayR+o)*2,height:(t.displayR+o)*2,left:eP+t.cx-t.displayR-o,top:eP+t.cy-t.displayR-o,border:`${l?o+2:o}px solid ${s}${l?"ff":a?"40":"22"}`,backgroundColor:l?`${s}18`:"transparent",zIndex:2,boxShadow:l?`0 0 28px ${s}80`:void 0},onClick:()=>p?.(t.cluster.name,t.cluster.tags.map(e=>e.tag))}),t.scaledInner.map((r,a)=>{let l=t.cluster.tags[a];if(!l)return null;let o=r.r,u=eP+t.cx+r.x,c=eP+t.cy+r.y,h=H===l.tag,m=eU?.tag===l.tag,x=l[eu(eo)],f="number"==typeof x?x:null,w=null!=f&&f>=2,y="performance"===Z?g(l[et],eT,eA):"rank"===Z?d(ea.get(l.tag.toLowerCase().replace(/#/g,"").trim())?.rank??null):l.colorOverride||s,v="shade"===el&&w?function(e,t=25){if(!/^#[0-9a-f]{6}$/i.test(e))return e;let[r,n,a]=function(e){let t=e.replace("#",""),r=parseInt(t.slice(0,2),16)/255,n=parseInt(t.slice(2,4),16)/255,a=parseInt(t.slice(4,6),16)/255,l=Math.max(r,n,a),s=Math.min(r,n,a),o=0,i=0,u=(l+s)/2;if(l!==s){let e=l-s;i=u>.5?e/(2-l-s):e/(l+s),o=(l===r?(n-a)/e+6*(n<a):l===n?(a-r)/e+2:(r-n)/e+4)*60}return[o,100*i,100*u]}(e),l=Math.max(8,a-t);return`hsl(${r.toFixed(1)}, ${n.toFixed(1)}%, ${l.toFixed(1)}%)`}(y,Math.min(35,10+(f??0)*4)):y,k=eq.get(l.tag)??t.cluster.name,C=!eW(k),j="number"===el&&w&&o>=11;return(0,n.jsxs)("div",{className:`absolute rounded-full transition-all duration-150 ${"shade"===el&&w?"ring-1 ring-white/40":""}`,style:{width:2*o,height:2*o,left:u-o,top:c-o,backgroundColor:v,opacity:m?.2:h?1:.85,transform:h&&!m?"scale(1.08)":"scale(1)",zIndex:h?50:5,boxShadow:h&&!m?`0 0 16px ${v}90`:"0 1px 2px rgba(0,0,0,0.2)",cursor:eU?"grabbing":C?"grab":i?"pointer":"default",touchAction:C?"none":void 0},onMouseDown:e=>{C&&eG(e,l.tag,k,l.count)},onMouseEnter:()=>{G(l.tag),Q(t.cluster.name)},onMouseLeave:()=>{G(null),Q(null)},onClick:()=>{if(!eU){if(b){let t=l.tag.toLowerCase(),r=null;
1for(let n of e){if(!n.id)continue;let e=(n.tags||[]).map(e=>e.toLowerCase()),a=(n.hashtags||[]).map(e=>e.toLowerCase());if(!e.includes(t)&&!a.includes(t))continue;let l=n.viewCount??0;(!r||l>r.views)&&(r={id:n.id,title:n.title||"",views:l,likes:n.likeCount??0})}if(r)return void b({videoId:r.id,title:r.title,viewCount:r.views,likeCount:r.likes})}p?.(t.cluster.name,t.cluster.tags.map(e=>e.tag))}},children:[j&&(0,n.jsx)("span",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",fontSize:Math.max(9,Math.min(.9*o,18)),color:"#ffffff",fontWeight:800,textShadow:"0 1px 3px rgba(0,0,0,0.85), 0 0 6px rgba(0,0,0,0.7)",pointerEvents:"none"},children:Math.round(f)}),h&&!eU&&eZ(l,t.cluster.name)]},l.tag)}),t.displayR>18&&(0,n.jsx)("div",{className:`absolute flex items-center justify-center ${i?"cursor-pointer":"pointer-events-none"}`,style:{left:eP+t.cx-t.displayR,top:eP+t.cy-t.displayR,width:2*t.displayR,height:2*t.displayR,zIndex:8},onClick:()=>p?.(t.cluster.name,t.cluster.tags.map(e=>e.tag)),children:(0,n.jsx)("span",{style:{fontSize:Math.max(10,Math.min(20,t.displayR/4.1)),color:"#ffffff",fontWeight:700,textShadow:"0 1px 6px rgba(0,0,0,0.9), 0 0 12px rgba(0,0,0,0.7), 0 2px 3px rgba(0,0,0,0.8)",textAlign:"center",maxWidth:1.92*t.displayR,lineHeight:1.15,paddingLeft:2,paddingRight:2,wordBreak:"break-word"},children:t.cluster.name})})]},t.cluster.name)}),eU&&(0,n.jsxs)("div",{className:"absolute rounded-full pointer-events-none",style:{left:eP+eU.currentX-18,top:eP+eU.currentY-18,width:36,height:36,backgroundColor:"#3b82f6",boxShadow:"0 0 24px rgba(59,130,246,0.6), 0 0 0 2px rgba(255,255,255,0.4)",zIndex:1e3,opacity:.92},children:[(0,n.jsx)("div",{className:"absolute -top-7 left-1/2 -translate-x-1/2 whitespace-nowrap bg-gray-900 text-white text-[11px] px-2 py-0.5 rounded shadow-xl border border-white/10",children:eU.tag}),eO&&(0,n.jsx)("div",{className:"absolute top-full mt-1 left-1/2 -translate-x-1/2 whitespace-nowrap bg-gray-900 text-white text-[10px] px-2 py-0.5 rounded shadow-xl border border-white/10",children:"__empty__"===eO?`+ new cluster "${eU.tag}"`:`â ${eO}`})]})]})}),(0,n.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-1.5",children:[eE.map(e=>{let t=V===e.name,r=U===e.name,a=e$.get(e.name);return(0,n.jsxs)("div",{className:`flex items-center gap-2 text-xs p-1.5 rounded transition-colors ${r?"bg-primary/10 border border-primary/40":eU&&!eW(e.name)?"bg-blue-500/10 border-2 border-dashed border-blue-500/50":"hover:bg-muted/50 border border-transparent"} ${!t?"cursor-pointer":"cursor-default"}`,onMouseEnter:()=>{Q(e.name),eU&&!eW(e.name)&&eU.fromCluster!==e.name&&eY(e.name)},onMouseLeave:()=>{Q(null),eB.current===e.name&&eY(null)},onClick:()=>{t||I(t=>t===e.name?null:e.name)},children:[(0,n.jsx)("div",{className:"w-3 h-3 rounded-full shrink-0",style:{backgroundColor:e.color}}),t?(0,n.jsx)("input",{autoFocus:!0,className:"flex-1 bg-background border border-border rounded px-1 text-xs text-white",value:A,onChange:e=>_(e.target.value),onBlur:()=>{X(e.name,A),T(null)},onKeyDown:t=>{"Enter"===t.key?(X(e.name,A),T(null)):"Escape"===t.key&&T(null)},onClick:e=>e.stopPropagation()}):(0,n.jsx)("span",{className:"truncate flex-1 font-medium",title:"Click to see tags \xb7 Double-click to rename",onDoubleClick:t=>{t.stopPropagation(),T(e.name),_(e.name)},children:e.name}),(0,n.jsxs)("span",{className:"text-muted-foreground shrink-0",children:[e.tags.length," tags"]}),(0,n.jsxs)("span",{className:"text-muted-foreground shrink-0",children:[e.totalCount,"\xd7"]}),a&&a.count>0&&(0,n.jsxs)("span",{className:"rounded bg-blue-600 text-white px-1 py-px font-semibold tabular-nums leading-none shrink-0",title:`${a.count} outlier video${1===a.count?"":"s"} on ${eo} \xb7 sum ${a.sum.toFixed(0)}\xd7`,children:["\xd7",a.count," \xb7 Σ",a.sum.toFixed(0)]})]},e.name)}),eS.length>0&&(()=>{let e="__unclassified__"===U,t=eS.reduce((e,t)=>e+t.count,0);return(0,n.jsxs)("div",{className:`flex items-center gap-2 text-xs p-1.5 rounded transition-colors cursor-pointer ${e?"bg-primary/10 border border-primary/40":"hover:bg-muted/50 border border-dashed border-border/60"}`,onMouseEnter:()=>Q("__unclassified__"),onMouseLeave:()=>Q(null),onClick:()=>I(e=>"__unclassified__"===e?null:"__unclassified__"),title:"Tags the AI categorizer didn't assign to any topic cluster â click to inspect, drag any bubble onto a cluster to assign it",children:[(0,n.jsx)("div",{className:"w-3 h-3 rounded-full shrink-0 border border-dashed border-muted-foreground"}),(0,n.jsx)("span",{className:"truncate flex-1 font-medium text-muted-foreground italic",children:N.unclassified}
1),(0,n.jsxs)("span",{className:"text-muted-foreground shrink-0",children:[eS.length," tags"]}),(0,n.jsxs)("span",{className:"text-muted-foreground shrink-0",children:[t,"\xd7"]})]})})()]}),(U||J)&&(R.length>0||eS.length>0)&&(()=>{let e=U||J;if(!e)return null;let t="__unclassified__"===e,r=t?N.unclassified:e,a=t?eS:eE.find(t=>t.name===e)?.tags??[];if(0===a.length)return null;let l=t?"#9ca3af":eE.find(t=>t.name===e)?.color??"#9ca3af",s=U===e;return(0,n.jsxs)("div",{className:`rounded border p-2 text-xs ${s?"border-primary/40 bg-primary/5":"border-border bg-muted/20"}`,children:[(0,n.jsxs)("div",{className:"flex items-center justify-between mb-1",children:[(0,n.jsxs)("div",{className:"text-muted-foreground",children:[t?`${N.unclassified} (Tags) `:"Tags in ",(0,n.jsx)("strong",{style:{color:l},children:r}),(0,n.jsxs)("span",{className:"ml-2 text-[10px]",children:["(",a.length," total",t?" \xb7 drag any onto a cluster to assign":" \xb7 double-click any to rename",")"]})]}),(0,n.jsxs)("div",{className:"flex items-center gap-2",children:[p&&!t&&(0,n.jsx)("button",{type:"button",onClick:()=>p(r,a.map(e=>e.tag)),className:"text-[10px] text-primary hover:underline",children:"Filter videos by this cluster â"}),p&&t&&(0,n.jsx)("button",{type:"button",onClick:()=>p(r,a.map(e=>e.tag)),className:"text-[10px] text-primary hover:underline",children:"Filter videos by these tags â"}),s&&(0,n.jsx)("button",{type:"button",onClick:()=>I(null),className:"text-[10px] text-muted-foreground hover:text-foreground",title:"Close pinned panel",children:"â Close"})]})]}),(0,n.jsx)("div",{className:"flex flex-wrap gap-1.5 max-h-48 overflow-y-auto",children:a.map(r=>{if(!t&&F&&F.cluster===e&&F.tag===r.tag)return(0,n.jsx)("input",{autoFocus:!0,className:"bg-background border border-border rounded px-1 text-xs text-white",value:z,onChange:e=>K(e.target.value),onBlur:()=>{q(e,r.tag,z),P(null)},onKeyDown:t=>{"Enter"===t.key?(q(e,r.tag,z),P(null)):"Escape"===t.key&&P(null)}},r.tag);let a=eq.get(r.tag)??e,l=t?null:a,s=eU?.tag===r.tag;return(0,n.jsxs)("span",{className:`bg-background border rounded px-1.5 py-0.5 hover:bg-accent text-white ${t?"border-dashed border-border/60":"border-border"} ${eU?"cursor-grabbing":"cursor-grab"} ${s?"opacity-30":""} select-none`,title:t?`${r.count} videos \xb7 drag onto a cluster (in legend or chart) to assign`:"Drag to another cluster \xb7 Double-click to rename",onMouseDown:e=>{eG(e,r.tag,l,r.count)},onDoubleClick:n=>{t||(n.stopPropagation(),P({cluster:e,tag:r.tag}),K(r.tag))},children:[r.tag," ",(0,n.jsxs)("span",{className:"text-muted-foreground",children:["(",r.count,")"]})]},r.tag)})})]})})(),"performance"===Z&&(0,n.jsxs)("div",{className:"flex items-center gap-2 text-[10px] text-muted-foreground",children:[(0,n.jsxs)("span",{children:["Low ",c[et].toLowerCase()]}),(0,n.jsx)("div",{className:"h-2 w-24 rounded",style:{background:"linear-gradient(to right, #ef4444, #f59e0b, #10b981)"}}),(0,n.jsxs)("span",{children:["High ",c[et].toLowerCase()]})]}),"rank"===Z&&(0,n.jsxs)("div",{className:"flex items-center gap-2 text-[10px] text-muted-foreground flex-wrap",children:[(0,n.jsx)("span",{className:"font-semibold text-foreground",children:"Best rank tier (min across videos using the tag):"}),[{label:"#1-3",color:"#10b981"},{label:"#4-10",color:"#22c55e"},{label:"#11-20",color:"#eab308"},{label:"#21-35",color:"#f97316"},{label:"#36-50",color:"#ef4444"},{label:"no Top-50",color:"#4b5563"}].map(e=>(0,n.jsxs)("span",{className:"inline-flex items-center gap-1",children:[(0,n.jsx)("span",{className:"inline-block h-2 w-2 rounded-full",style:{backgroundColor:e.color}}),e.label]},e.label)),(0,n.jsxs)("span",{className:"text-muted-foreground/70",children:["\xb7 ",ea.size," of ",eL," tags have a tracked rank"]})]})]})}},19497:(e,t,r)=>{r.d(t,{b:()=>m});var n=r(95155),a=r(12115),l=r(35130),s=r(35299),o=r(53511),i=r(85921),u=r(12932),c=r(62332);function d(e,t,r){for(let n=0;n<r.length;n++)e.setUint8(t+n,r.charCodeAt(n))}function g(e){if(!isFinite(e)||e<0)return"0:00";let t=Math.floor(e/60),r=Math.floor(e%60);return`${t}:${r.toString().padStart(2,"0")}`}let h=[.75,1,1.25,1.5,2];function m({helpKey:e,text:t,lang:r="en",compact:m=!0,className:x=""}){let[f,p]=(0,a.useState)(!1),[b,w]=(0,a.useState)(!1),[y,v]=(0,a.useState)(!1),[k,C]=(0,a.useState)(0),[j,M]=(0,a.useState)(0),[N,S]=(0,a.useState)(1),[L,E]=(0,a.useState)(!1),[R,$]=(0,a.useState)(null),V=(0,a.useRef)(null),T=(0,a.useRef)(null);(0,a.useEffect)(()=>{fetch("/api/settings/tts-speed").then(e=>e.json()).then(e=>{e.speed&&S(e.speed)}).catch(()=>{})},[]),(0,a.useEffect)(()=>()=>{V.current&&(V.current.pause(),V.current=null),T.current&&(URL.revokeObjectURL(T.current),T.current=null)},[]);let A=(0,a.useCallback)(async()=>
1{if(!f){if(V.current)return void(y?(V.current.play(),w(!0),v(!1)):b?(V.current.pause(),v(!0)):(V.current.currentTime=0,V.current.play(),w(!0),v(!1)));p(!0),$(null),E(!0);try{let n=await fetch(`/api/help-audio?key=${encodeURIComponent(e)}&lang=${encodeURIComponent(r)}`),a=null,l=0;if(n.ok){let e=await n.json();e.cached&&e.audio&&(a=e.audio,l=e.duration||0)}if(!a){let n=await fetch("/api/help-audio",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({key:e,lang:r,...t?{text:t}:{}})});if(!n.ok)throw Error("Failed to generate audio");let s=await n.json();a=s.audio,l=s.duration||0}if(!a)throw Error("No audio data");let s=Uint8Array.from(atob(a),e=>e.charCodeAt(0)),o=function(e,t=24e3){let r=new ArrayBuffer(44+e.length),n=new DataView(r);return d(n,0,"RIFF"),n.setUint32(4,36+e.length,!0),d(n,8,"WAVE"),d(n,12,"fmt "),n.setUint32(16,16,!0),n.setUint16(20,1,!0),n.setUint16(22,1,!0),n.setUint32(24,t,!0),n.setUint32(28,2*t,!0),n.setUint16(32,2,!0),n.setUint16(34,16,!0),d(n,36,"data"),n.setUint32(40,e.length,!0),new Uint8Array(r,44).set(e),r}(s,24e3),i=new Blob([o],{type:"audio/wav"}),u=URL.createObjectURL(i);T.current=u;let c=new Audio(u);c.playbackRate=N,V.current=c,c.onloadedmetadata=()=>{let e=c.duration&&isFinite(c.duration)?c.duration:l;C(e)},c.ontimeupdate=()=>M(c.currentTime),c.onended=()=>{w(!1),v(!1),M(0)},c.onerror=()=>{$("Audio playback error"),w(!1)},await c.play(),w(!0),v(!1)}catch(e){$(e.message||"TTS error")}finally{p(!1)}}},[e,r,t,f,b,y,N]),_=(0,a.useCallback)(e=>{V.current&&(V.current.currentTime=Math.max(0,Math.min(V.current.duration,V.current.currentTime+e)))},[]),F=(0,a.useCallback)(e=>{if(!V.current||!k)return;let t=e.currentTarget.getBoundingClientRect(),r=Math.max(0,Math.min(1,(e.clientX-t.left)/t.width));V.current.currentTime=r*k},[k]),P=(0,a.useCallback)(()=>{let e=h.indexOf(N),t=h[(e+1)%h.length];S(t),V.current&&(V.current.playbackRate=t),fetch("/api/settings/tts-speed",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({speed:t})}).catch(()=>{})},[N]);return!m||L||b||f?(0,n.jsxs)("div",{className:`flex items-center gap-2 px-2.5 py-1.5 rounded-lg bg-blue-500/10 border border-blue-500/20 ${x}`,children:[(0,n.jsx)("button",{onClick:A,className:"shrink-0",title:b&&!y?"Pause":"Play",children:f?(0,n.jsx)(s.A,{className:"h-4 w-4 text-blue-400 animate-spin"}):b&&!y?(0,n.jsx)(o.A,{className:"h-4 w-4 text-blue-400"}):(0,n.jsx)(i.A,{className:"h-4 w-4 text-blue-400"})}),(L||b)&&k>0&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("button",{onClick:()=>_(-10),className:"text-blue-400 hover:text-blue-300 shrink-0",title:"-10s",children:(0,n.jsx)(u.A,{className:"h-3.5 w-3.5"})}),(0,n.jsx)("span",{className:"text-[10px] text-muted-foreground font-mono w-9 text-right shrink-0",children:g(j)}),(0,n.jsx)("div",{className:"flex-1 min-w-[80px] h-2 bg-muted rounded-full cursor-pointer relative overflow-hidden",onClick:F,children:(0,n.jsx)("div",{className:"h-full bg-blue-400 rounded-full transition-all",style:{width:`${k>0?j/k*100:0}%`}})}),(0,n.jsx)("span",{className:"text-[10px] text-muted-foreground font-mono w-9 shrink-0",children:g(Math.max(0,k-j))}),(0,n.jsx)("button",{onClick:()=>_(10),className:"text-blue-400 hover:text-blue-300 shrink-0",title:"+10s",children:(0,n.jsx)(c.A,{className:"h-3.5 w-3.5"})}),(0,n.jsxs)("button",{onClick:P,className:"text-[10px] px-1.5 py-0.5 rounded bg-blue-500/10 text-blue-400 hover:bg-blue-500/20 font-mono shrink-0",title:"Speed",children:[N,"x"]})]}),f&&(0,n.jsx)("span",{className:"text-[10px] text-blue-400",children:"Generating audio..."}),R&&(0,n.jsx)("span",{className:"text-[10px] text-red-400",children:R})]}):(0,n.jsxs)("button",{onClick:A,className:`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-[11px] font-medium bg-blue-500/10 text-blue-400 hover:bg-blue-500/20 hover:text-blue-300 border border-blue-500/20 transition-colors ${x}`,title:"Listen to this explanation",children:[(0,n.jsx)(l.A,{className:"h-3.5 w-3.5"}),(0,n.jsx)("span",{children:"Listen"})]})}}}]);
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.