@aiquants/contact-map 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -23,6 +23,7 @@ interface ContactMapDirectoryEntry {
23
23
  absolutePath: string;
24
24
  relativePath: string;
25
25
  children?: ContactMapDirectoryEntry[];
26
+ memberCount?: number;
26
27
  personId?: number;
27
28
  title?: string;
28
29
  isPrimary?: boolean;
@@ -34,4 +35,8 @@ interface ContactRecordForTree {
34
35
  department: string | null;
35
36
  title: string | null;
36
37
  }
37
- export { type ContactMapDirectoryEntry as C, DEFAULT_LIST_LAYOUT_SPEC as D, type ResponsiveLayoutSpec as R, type ResponsiveThresholds as a, type ContactRecordForTree as b, DEFAULT_TREE_LAYOUT_SPEC as c, calculateResponsiveThresholds as d, getHysteresisBreakpointState as g };
38
+ type ContactMapTreeNaming = {
39
+ readonly uncategorizedCompany: string;
40
+ readonly unnamedPerson: string;
41
+ };
42
+ export { type ContactMapDirectoryEntry as C, DEFAULT_LIST_LAYOUT_SPEC as D, type ResponsiveLayoutSpec as R, type ResponsiveThresholds as a, type ContactRecordForTree as b, type ContactMapTreeNaming as c, DEFAULT_TREE_LAYOUT_SPEC as d, calculateResponsiveThresholds as e, getHysteresisBreakpointState as g };
@@ -1 +1 @@
1
- var S=(t,n)=>t&&t.trim()||n;var H={\u672C\u90E8:{rank:10,type:"Organization"},\u30AB\u30F3\u30D1\u30CB\u30FC:{rank:10,type:"Organization"},\u672C\u793E:{rank:10,type:"Location"},\u30D6\u30ED\u30C3\u30AF:{rank:11,type:"Location"},\u652F\u5E97:{rank:12,type:"Location"},\u7814\u7A76\u6240:{rank:15,type:"Location"},\u5DE5\u5834:{rank:15,type:"Location"},\u4E8B\u696D\u90E8:{rank:18,type:"Organization"},\u90E8\u9580:{rank:18,type:"Organization"},\u7D71\u62EC\u90E8:{rank:19,type:"Organization"},\u90E8:{rank:20,type:"Organization"},\u958B\u767A:{rank:20,type:"Organization"},\u30B0\u30EB\u30FC\u30D7:{rank:22,type:"Organization"},\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8:{rank:25,type:"Organization"},\u63A8\u9032:{rank:20,type:"Organization"},\u4E8B\u696D\u6240:{rank:25,type:"Location"},\u55B6\u696D\u6240:{rank:28,type:"Location"},\u5BA4:{rank:30,type:"Organization"},\u8AB2:{rank:30,type:"Organization"},\u30BB\u30F3\u30BF\u30FC:{rank:30,type:"Location"},\u30D3\u30B8\u30CD\u30B9\u30D7\u30ED\u30C7\u30E5\u30FC\u30B9\u30BB\u30F3\u30BF\u30FC:{rank:30,type:"Location"},\u30C1\u30FC\u30E0:{rank:40,type:"Organization"},\u4FC2:{rank:50,type:"Organization"},Department:{rank:20,type:"Organization"},Dept:{rank:20,type:"Organization"},"Dept.":{rank:20,type:"Organization"},Division:{rank:20,type:"Organization"},Div:{rank:20,type:"Organization"},"Div.":{rank:20,type:"Organization"},Section:{rank:30,type:"Organization"},Sect:{rank:30,type:"Organization"},"Sect.":{rank:30,type:"Organization"},Unit:{rank:30,type:"Organization"},Group:{rank:22,type:"Organization"},Team:{rank:40,type:"Organization"},Branch:{rank:12,type:"Location"},Office:{rank:28,type:"Location"},Center:{rank:30,type:"Location"},Centre:{rank:30,type:"Location"},HQ:{rank:10,type:"Organization"},Headquarters:{rank:10,type:"Organization"}},k=t=>{for(let[n,i]of Object.entries(H))if(t.endsWith(n))return i;return{rank:99,type:"Other"}},z=t=>k(t).rank,Q=["\u30B0\u30EB\u30FC\u30D7","\u30C1\u30FC\u30E0","Group","Team","\u5BA4","\u8AB2","Unit","Area","\u90E8","Department","Dept","Division","Div","\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8","\u63A8\u9032"],v=t=>Q.find(n=>t.endsWith(n)),X=new Set(["&","Quality","Innovation","R&D","Solutions","Development","Laboratory","and","Food","Beverage"]),J=(t,n)=>n>1&&(t.endsWith("\u652F\u5E97")||t.endsWith("\u672C\u90E8")||t.endsWith("\u4E8B\u696D\u6240")||t.endsWith("\u5DE5\u5834")),Z=(t,n)=>{if(!n)return!0;let i=k(t),r=k(n);if(i.rank<r.rank||t.endsWith("\u672C\u90E8")&&n.endsWith("\u672C\u90E8"))return!1;let p=v(t),f=v(n);return!(p&&f&&p!==f)},x=(t,n)=>{if(!t)return[];if(t==="\u517C")return["\u517C"];if(t==="\u517C\u52D9")return["\u517C"];if(t.startsWith("\u517C ")||t.startsWith("\u517C\u3000")){let r=t.slice(1).trim();return["\u517C",...x(r,n)]}if(t.startsWith("\u517C\u52D9 ")||t.startsWith("\u517C\u52D9\u3000")){let r=t.slice(2).trim();return["\u517C",...x(r,n)]}let i="";for(let r=t.length-1;r>0;r--){if(t[r]!==" ")continue;let p=t.slice(0,r);if(!X.has(p)&&n.has(p)){i=p;break}}if(i){let r=i,p=t.slice(i.length),f=/^\s+(and|&)\s+([A-Za-z0-9]+)/i,b=p.match(f);b&&(r=t.slice(0,i.length+b[0].length));let l=t.slice(r.length),e=["Department","Dept","Division","Div","Section","Sect","Unit","Group","Team","Branch","Office","Center","Centre","HQ","Headquarters"];for(let s of e){let g=new RegExp(`^\\s+${s}\\.?(?=$|[\\s,])`,"i"),c=l.match(g);if(c){r=t.slice(0,r.length+c[0].length);break}}let u=t.slice(r.length).trim();return[r,...x(u,n)]}return[t]},V=(t,n)=>{let r=t.replace(/[\s\u3000]+(?:兼務|兼)[\s\u3000]+/g,"\u3000\u517C\u3000").replace(/^(?:兼務|兼)[\s\u3000]+/,"\u517C\u3000").replace(/[\s\u3000]+(?:兼務|兼)$/,"\u3000\u517C").split(/\u3000/),p=[];for(let f of r){let b=f.trim();b&&p.push(...x(b,n))}return p},A=(t,n)=>{let i=[],r=["\u90E8","\u8AB2","\u5BA4","\u672C\u90E8","\u652F\u5E97","\u55B6\u696D\u6240","\u30B0\u30EB\u30FC\u30D7","\u30C1\u30FC\u30E0","\u30BB\u30F3\u30BF\u30FC","\u30AB\u30F3\u30D1\u30CB\u30FC","\u4E8B\u696D\u6240","\u5DE5\u5834","\u7814\u7A76\u6240","\u4FC2","\u90E8\u9580","\u4E8B\u696D\u90E8","\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8","\u63A8\u9032","\u958B\u767A","Department","Dept","Division","Div","Section","Sect","Unit","Group","Team","Branch","Office","Center","Centre","HQ","Headquarters"],p=t.split(/[\s\u3000,()()[\]]+/).filter(Boolean),f=p.length,b=new Set;for(let l=f;l>=1;l--)for(let e=0;e<=f-l;e++){let u=!1;for(let g=e;g<e+l;g++)if(b.has(g)){u=!0;break}if(u)continue;let s=p.slice(e,e+l).join(" ");if(!(s==="\u517C"||s==="\u517C\u52D9"||s==="\u4FC2"||s==="of"||s==="&"||s==="Quality"||s==="Innovation"||s==="R&D"||s==="Solutions"||s==="Development"||s==="Laboratory"||s==="and"||s==="Food"||s==="Beverage")&&n.allKnownDepartments.has(s)){i.push({name:s,index:e});for(let g=e;g<e+l;g++)b.add(g)}}for(let l=0;l<f;l++){if(b.has(l))continue;let e=p[l];for(e.endsWith("\u9577")&&e.length>1?e=e.slice(0,-1):e.endsWith("\u7D71\u62EC")&&e.length>2&&(e=e.slice(0,-2));;){let c=!1;if(e.startsWith("\u62C5\u5F53")&&e.length>2||e.startsWith("\u5C02\u4EFB")&&e.length>2||e.startsWith("\u517C\u52D9")&&e.length>2?(e=e.slice(2),c=!0):(e.startsWith("\u526F")||e.startsWith("\u517C"))&&e.length>1&&(e=e.slice(1),c=!0),!c)break}if(e.includes("\u30FB")&&!n.allKnownDepartments.has(e)){let c=e.split("\u30FB"),y=c[c.length-1],T=r.find(E=>y.endsWith(E));if(T){for(let E of c){let C=E;r.some(o=>C.endsWith(o))||(C=C+T);let P=e!=="\u517C"&&e!=="\u4FC2"&&e!=="of"&&e!=="&"&&e!=="Quality"&&e!=="Innovation"&&e!=="R&D"&&e!=="Solutions"&&e!=="Development"&&e!=="Laboratory"&&e!=="and"&&e!=="Food"&&e!=="Beverage"&&n.allKnownDepartments.has(C),h=r.some(o=>C.endsWith(o)),a=r.includes(C);(P||h&&!a)&&i.push({name:C,index:l})}continue}}let u=e!=="\u517C"&&e!=="\u4FC2"&&e!=="of"&&e!=="&"&&e!=="Quality"&&e!=="Innovation"&&e!=="R&D"&&e!=="Solutions"&&e!=="Development"&&e!=="Laboratory"&&e!=="and"&&e!=="Food"&&e!=="Beverage"&&n.allKnownDepartments.has(e),s=r.some(c=>e.endsWith(c)),g=r.includes(e);(u||s&&!g)&&i.push({name:e,index:l})}return i.sort((l,e)=>l.index-e.index),i.map(l=>l.name)},L=(t,n)=>{let i=0;for(let r of n)i<t.length&&r===t[i]&&i++;return i===t.length},_={name:"Standard",parse:(t,n,i="full")=>{let r=S(t.department,"");if(!r)return null;let p=V(r,n.allKnownDepartments),f=new Map;for(let e of p)f.set(e,(f.get(e)||0)+1);let b=e=>{let u=[],s=[];for(let g=0;g<e.length;g++){let c=e[g];if(c==="\u517C"){s.length>0&&(u.push(s),s=[]);continue}let y=k(c),T=y.rank,E=f.get(c)||0,C=J(c,E);if(s.length===0)s.push(c);else{let P=s[s.length-1],h=k(P),a=h.rank;if(s.includes(c))u.push(s),s=[c];else{let o=!1;if(C)o=!0;else if(h.type===y.type){let m=v(P),d=v(c);m&&d&&m!==d||P.endsWith("\u672C\u90E8")&&c.endsWith("\u672C\u90E8")||P.endsWith("\u90E8\u9580")&&c.endsWith("\u4E8B\u696D\u90E8")||P.endsWith("\u4E8B\u696D\u90E8")&&c.endsWith("\u90E8\u9580")||P.endsWith("\u90E8\u9580")&&c.endsWith("\u672C\u90E8")||h.type==="Other"&&y.type==="Other"?o=!0:o=a<T}else o=T>=10,o&&h.type==="Location"&&y.type==="Organization"&&a>=T&&e.slice(g+1).includes(P)&&(o=!1);o?s.push(c):(u.push(s),s=[c])}}if(C){let P=g+1<e.length?e[g+1]:void 0;Z(c,P)&&s.length>0&&(u.push(s),s=[])}}return s.length>0&&u.push(s),u},l=[];if(i==="full"&&l.push(...b(p)),i==="pure_org"){let e=p.filter(u=>k(u).type!=="Location");e.length>0&&l.push(...b(e))}if(t.title){let u=/[^\x20-\x7E]/.test(t.title)?/[\s\u3000]*(?:兼務|兼)[\s\u3000]*/:/[,;]|(?:兼務|兼)/,s=t.title.split(u).filter(Boolean),g=[],c=(h,a)=>{let o=z(h),m=z(a),d=o<m;if(!d){let D=v(h),R=v(a);if(D&&R&&D!==R)d=!0;else if(h.endsWith("\u672C\u90E8")&&a.endsWith("\u672C\u90E8"))d=!0;else if(h.endsWith("\u90E8\u9580")&&a.endsWith("\u4E8B\u696D\u90E8")||h.endsWith("\u4E8B\u696D\u90E8")&&a.endsWith("\u90E8\u9580"))d=!0;else if(h.endsWith("\u90E8\u9580")&&a.endsWith("\u672C\u90E8"))d=!0;else{let w=k(h),G=k(a);w.type==="Other"&&G.type==="Other"&&(d=!0)}}return d};for(let h of s){let a=A(h,n);if(a.length===0)continue;let o=[];for(let m of a)if(o.length===0)o.push(m);else{let d=o[o.length-1];if(c(d,m))o.push(m);else{g.push([...o]);let D=!1;for(let R=o.length-2;R>=0;R--){let w=o[R];if(c(w,m)){o=[...o.slice(0,R+1),m],D=!0;break}}D||(o=[m])}}o.length>0&&g.push(o)}let y=[...l],T=h=>s.some(a=>a.includes(h)&&a.length>h.length);for(let h of g){let a=!1;for(let o of l){let m=o.findIndex(d=>h.includes(d));if(m!==-1){let d=o[m],D=h.indexOf(d);if(m>0&&D===0){let R=o.slice(0,m);y.push([...R,...h]),a=!0}else if(D>0&&m===0){let R=h.slice(0,D);y.push([...R,...o]),y.push(h),a=!0}else h.length>o.length-m,a=!0}if(!a){let d=o[o.length-1],D=h[0];c(d,D)&&(y.push([...o,...h]),a=!0)}}a||y.push(h)}let E=[],C=[],P=new Set;for(let h of y){let a=h.join("|");P.has(a)||(P.add(a),C.push(h))}for(let h=0;h<C.length;h++){let a=C[h],o=!1;for(let m=0;m<C.length;m++){if(h===m)continue;let d=C[m];if(d.length>a.length&&d.slice(0,a.length).join("|")===a.join("|")){let D=a[a.length-1];if(!T(D)){o=!0;break}}if(d.length>a.length&&L(a,d)){let D=a[a.length-1];if(!T(D)){o=!0;break}}if(a.length===1&&d.length>0){let D=a[0],R=d[d.length-1];if(D!==R&&R.endsWith(D)){o=!0;break}}}o||E.push(a)}return E.length>0?E:null}if(l.length>0){let e=[];for(let u=0;u<l.length;u++){let s=l[u],g=!1;for(let c=0;c<l.length;c++){if(u===c)continue;let y=l[c];if(y.length>s.length&&L(s,y)){g=!0;break}}g||e.push(s)}return e.length>0?e:null}return null}},F={name:"TitleBased",parse:(t,n,i="full")=>{let r=t.title;if(!r)return null;let p=A(r,n);return p.length>0?[p]:null}};var Y="\u672A\u5206\u985E",$="\u540D\u524D\u672A\u8A2D\u5B9A",ee=[_,F],te=t=>{let n=S(t.full_name,$),i=S(t.title,"");return i.length>0?`${n} (${i})`:n},B=(t,n)=>`${t} (${n.toLocaleString()})`,W=t=>t.sort((n,i)=>n.label.localeCompare(i.label,"ja")),O=(t,n,i)=>{let r=t.get(n);if(r)return r;let p=i();return t.set(n,p),p},N=t=>encodeURIComponent(t.replace(/\//g,"\uFF0F")),q=t=>t.sort((n,i)=>{let r=!!(n.contact.title&&n.contact.title.trim().length>0),p=!!(i.contact.title&&i.contact.title.trim().length>0);return r&&!p?-1:!r&&p?1:n.label.localeCompare(i.label,"ja")}),U=t=>{let n=S(t.contact.full_name,$),i=S(t.contact.title,"");return{name:i?`${n} (${i})`:n,type:"file",absolutePath:t.path,relativePath:t.segment,personId:t.contact.person_id,title:t.contact.title||void 0,isPrimary:t.isPrimary}},K=t=>{let n=W(Array.from(t.children.values())).map(K),i=q([...t.persons]).map(U);return{name:B(t.label,t.personCount),type:"directory",absolutePath:t.path,relativePath:t.segment,children:[...i,...n]}},M=class{constructor(){this.companyMap=new Map;this.processedPersonIds=new Set;this.allDepts=new Set;this.cachedResult=null}appendRecords(n){if(!n||n.length===0)return;let i="full",r=!1;for(let p of n)if(!this.processedPersonIds.has(p.person_id)&&p.department){let f=p.department.split(/\u3000/);for(let b of f){let l=b.trim();if(!l||l==="\u517C"||l==="\u4FC2")continue;if(/[^\x20-\x7E]/.test(l)){let u=l.split(" ").filter(s=>s.length>0&&s!=="\u517C"&&s!=="\u4FC2");for(let s of u)this.allDepts.add(s)}else this.allDepts.add(l)}}for(let p of n){let f=p.person_id;if(!Number.isFinite(f)||this.processedPersonIds.has(f))continue;this.processedPersonIds.add(f),r=!0;let b=S(p.company_name,Y),l=te(p),e=`company:${N(b)}`,u=O(this.companyMap,e,()=>({label:b,segment:e,path:`/${e}`,departments:new Map,persons:[],personCount:0})),s=[],g={allKnownDepartments:this.allDepts};for(let c of ee){let y=c.parse(p,g,i);if(y&&y.length>0){s=y;break}}s.length===0&&s.push([]);for(let c=0;c<s.length;c++){let y=s[c];if(y.length===0){let a=`person:${f}`,o=`${u.path}/${a}`;u.persons.some(d=>d.contact.person_id===f)||u.persons.push({contact:p,label:l,path:o,segment:a,isPrimary:!0});continue}let T=null,E=u.path;if(y.length>0){let a=y[0],o=`department:${N(a)}`;T=O(u.departments,o,()=>({label:a,segment:o,path:`${E}/${o}`,children:new Map,persons:[],personCount:0})),E=T.path,T.personCount+=1;for(let m=1;m<y.length;m++){let d=y[m],D=`department:${N(d)}`;if(!T)throw new Error("Unexpected null currentDepartmentNode");T=O(T.children,D,()=>({label:d,segment:D,path:`${E}/${D}`,children:new Map,persons:[],personCount:0})),E=T.path,T.personCount+=1}}else continue;let C=`person:${f}`,P=`${T.path}/${C}`;T.persons.some(a=>a.contact.person_id===f)||T.persons.push({contact:p,label:l,path:P,segment:C,isPrimary:c===0})}u.personCount+=1}r&&(this.cachedResult=null)}getSnapshot(){if(this.cachedResult)return this.cachedResult;let n={},i=W(Array.from(this.companyMap.values())).map(r=>{let p=W(Array.from(r.departments.values())).map(K),f=q([...r.persons]).map(U),b={name:B(r.label,r.personCount),type:"directory",absolutePath:r.path,relativePath:r.segment,children:[...f,...p]};return n[r.label]=b,b});return this.cachedResult={tree:i,companyMap:n},this.cachedResult}append(n){this.appendRecords(n)}build(){return this.getSnapshot().tree}reset(){this.companyMap.clear(),this.processedPersonIds.clear(),this.allDepts.clear(),this.cachedResult=null}getUniquePersonCount(){return this.processedPersonIds.size}get size(){return this.processedPersonIds.size}};var ne=3e3,j=60,re=700,se=25,ie=t=>{let n=j+t/se;return Math.min(re,Math.max(j,n))};var oe={setTimeout:(t,n)=>setTimeout(t,n),clearTimeout:t=>clearTimeout(t),now:()=>Date.now()},I=class{constructor(n,i=oe){this.postMessage=n;this.timer=i;this.builder=new M;this.pendingRecords=[];this.rawRecords=[];this.activeGeneration=0;this.rebuildEpoch=0;this.lastEmitTime=0;this.emitTimerId=null;this.processTimerId=null;this.isProcessing=!1;this.finalizeRequested=!1}handleMessage(n){switch(n.type){case"RESET_TREE":{this.cancelTimers(),this.activeGeneration=n.generation,this.rebuildEpoch=Math.max(this.rebuildEpoch,n.epochBase)+1,this.builder=new M,this.pendingRecords.length=0,this.rawRecords.length=0,this.lastEmitTime=0,this.finalizeRequested=!1,this.isProcessing=!1;break}case"APPEND_RECORDS":{if(n.generation!==this.activeGeneration)return;for(let i=0;i<n.records.length;i++){let r=n.records[i];this.pendingRecords.push(r),this.rawRecords.push(r)}this.scheduleProcess();break}case"FINALIZE_TREE":{if(n.generation!==this.activeGeneration)return;this.finalizeRequested=!0,this.scheduleProcess();break}}}scheduleProcess(){this.isProcessing||this.processTimerId!==null||(this.processTimerId=this.timer.setTimeout(()=>{this.processTimerId=null,this.processStep()},0))}processStep(){this.isProcessing=!0;let n=Math.min(ne,this.pendingRecords.length);if(n>0){let r=this.pendingRecords.splice(0,n);this.builder.append(r)}if(this.pendingRecords.length>0){this.isProcessing=!1,this.scheduleProcess(),this.scheduleEmit(!1);return}if(this.finalizeRequested){this.finalizeRequested=!1,this.builder=new M,this.builder.append(this.rawRecords),this.rebuildEpoch+=1,this.isProcessing=!1,this.emitNow(!0);return}this.isProcessing=!1,this.scheduleEmit(!0)}scheduleEmit(n){if(this.emitTimerId!==null){n&&(this.timer.clearTimeout(this.emitTimerId),this.emitTimerId=null,this.emitNow(!0));return}let i=this.timer.now(),r=ie(this.builder.getUniquePersonCount()),p=i-this.lastEmitTime;if(p>=r||n)this.emitNow(n);else{let f=r-p;this.emitTimerId=this.timer.setTimeout(()=>{this.emitTimerId=null,this.emitNow(this.pendingRecords.length===0&&!this.finalizeRequested)},f)}}emitNow(n){this.lastEmitTime=this.timer.now();let i=this.builder.build();this.postMessage({type:"TREE_CHUNK",generation:this.activeGeneration,tree:i,consumedRecords:this.rawRecords.length,uniquePersonCount:this.builder.getUniquePersonCount(),isIdle:n,rebuildEpoch:this.rebuildEpoch})}cancelTimers(){this.processTimerId!==null&&(this.timer.clearTimeout(this.processTimerId),this.processTimerId=null),this.emitTimerId!==null&&(this.timer.clearTimeout(this.emitTimerId),this.emitTimerId=null)}dispose(){this.cancelTimers(),this.pendingRecords.length=0,this.rawRecords.length=0}};var ae=new I(t=>{self.postMessage(t)});self.onmessage=t=>{ae.handleMessage(t.data)};
1
+ var M=(e,n)=>e&&e.trim()||n;var j={\u672C\u90E8:{rank:10,type:"Organization"},\u30AB\u30F3\u30D1\u30CB\u30FC:{rank:10,type:"Organization"},\u672C\u793E:{rank:10,type:"Location"},\u30D6\u30ED\u30C3\u30AF:{rank:11,type:"Location"},\u652F\u5E97:{rank:12,type:"Location"},\u7814\u7A76\u6240:{rank:15,type:"Location"},\u5DE5\u5834:{rank:15,type:"Location"},\u4E8B\u696D\u90E8:{rank:18,type:"Organization"},\u90E8\u9580:{rank:18,type:"Organization"},\u7D71\u62EC\u90E8:{rank:19,type:"Organization"},\u90E8:{rank:20,type:"Organization"},\u958B\u767A:{rank:20,type:"Organization"},\u30B0\u30EB\u30FC\u30D7:{rank:22,type:"Organization"},\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8:{rank:25,type:"Organization"},\u63A8\u9032:{rank:20,type:"Organization"},\u4E8B\u696D\u6240:{rank:25,type:"Location"},\u55B6\u696D\u6240:{rank:28,type:"Location"},\u5BA4:{rank:30,type:"Organization"},\u8AB2:{rank:30,type:"Organization"},\u30BB\u30F3\u30BF\u30FC:{rank:30,type:"Location"},\u30D3\u30B8\u30CD\u30B9\u30D7\u30ED\u30C7\u30E5\u30FC\u30B9\u30BB\u30F3\u30BF\u30FC:{rank:30,type:"Location"},\u30C1\u30FC\u30E0:{rank:40,type:"Organization"},\u4FC2:{rank:50,type:"Organization"},Department:{rank:20,type:"Organization"},Dept:{rank:20,type:"Organization"},"Dept.":{rank:20,type:"Organization"},Division:{rank:20,type:"Organization"},Div:{rank:20,type:"Organization"},"Div.":{rank:20,type:"Organization"},Section:{rank:30,type:"Organization"},Sect:{rank:30,type:"Organization"},"Sect.":{rank:30,type:"Organization"},Unit:{rank:30,type:"Organization"},Group:{rank:22,type:"Organization"},Team:{rank:40,type:"Organization"},Branch:{rank:12,type:"Location"},Office:{rank:28,type:"Location"},Center:{rank:30,type:"Location"},Centre:{rank:30,type:"Location"},HQ:{rank:10,type:"Organization"},Headquarters:{rank:10,type:"Organization"}},k=e=>{for(let[n,s]of Object.entries(j))if(e.endsWith(n))return s;return{rank:99,type:"Other"}},z=e=>k(e).rank,G=["\u30B0\u30EB\u30FC\u30D7","\u30C1\u30FC\u30E0","Group","Team","\u5BA4","\u8AB2","Unit","Area","\u90E8","Department","Dept","Division","Div","\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8","\u63A8\u9032"],v=e=>G.find(n=>e.endsWith(n)),H=new Set(["&","Quality","Innovation","R&D","Solutions","Development","Laboratory","and","Food","Beverage"]),Q=(e,n)=>n>1&&(e.endsWith("\u652F\u5E97")||e.endsWith("\u672C\u90E8")||e.endsWith("\u4E8B\u696D\u6240")||e.endsWith("\u5DE5\u5834")),X=(e,n)=>{if(!n)return!0;let s=k(e),r=k(n);if(s.rank<r.rank||e.endsWith("\u672C\u90E8")&&n.endsWith("\u672C\u90E8"))return!1;let p=v(e),f=v(n);return!(p&&f&&p!==f)},x=(e,n)=>{if(!e)return[];if(e==="\u517C")return["\u517C"];if(e==="\u517C\u52D9")return["\u517C"];if(e.startsWith("\u517C ")||e.startsWith("\u517C\u3000")){let r=e.slice(1).trim();return["\u517C",...x(r,n)]}if(e.startsWith("\u517C\u52D9 ")||e.startsWith("\u517C\u52D9\u3000")){let r=e.slice(2).trim();return["\u517C",...x(r,n)]}let s="";for(let r=e.length-1;r>0;r--){if(e[r]!==" ")continue;let p=e.slice(0,r);if(!H.has(p)&&n.has(p)){s=p;break}}if(s){let r=s,p=e.slice(s.length),f=/^\s+(and|&)\s+([A-Za-z0-9]+)/i,b=p.match(f);b&&(r=e.slice(0,s.length+b[0].length));let l=e.slice(r.length),t=["Department","Dept","Division","Div","Section","Sect","Unit","Group","Team","Branch","Office","Center","Centre","HQ","Headquarters"];for(let i of t){let g=new RegExp(`^\\s+${i}\\.?(?=$|[\\s,])`,"i"),c=l.match(g);if(c){r=e.slice(0,r.length+c[0].length);break}}let h=e.slice(r.length).trim();return[r,...x(h,n)]}return[e]},J=(e,n)=>{let r=e.replace(/[\s\u3000]+(?:兼務|兼)[\s\u3000]+/g,"\u3000\u517C\u3000").replace(/^(?:兼務|兼)[\s\u3000]+/,"\u517C\u3000").replace(/[\s\u3000]+(?:兼務|兼)$/,"\u3000\u517C").split(/\u3000/),p=[];for(let f of r){let b=f.trim();b&&p.push(...x(b,n))}return p},_=(e,n)=>{let s=[],r=["\u90E8","\u8AB2","\u5BA4","\u672C\u90E8","\u652F\u5E97","\u55B6\u696D\u6240","\u30B0\u30EB\u30FC\u30D7","\u30C1\u30FC\u30E0","\u30BB\u30F3\u30BF\u30FC","\u30AB\u30F3\u30D1\u30CB\u30FC","\u4E8B\u696D\u6240","\u5DE5\u5834","\u7814\u7A76\u6240","\u4FC2","\u90E8\u9580","\u4E8B\u696D\u90E8","\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8","\u63A8\u9032","\u958B\u767A","Department","Dept","Division","Div","Section","Sect","Unit","Group","Team","Branch","Office","Center","Centre","HQ","Headquarters"],p=e.split(/[\s\u3000,()()[\]]+/).filter(Boolean),f=p.length,b=new Set;for(let l=f;l>=1;l--)for(let t=0;t<=f-l;t++){let h=!1;for(let g=t;g<t+l;g++)if(b.has(g)){h=!0;break}if(h)continue;let i=p.slice(t,t+l).join(" ");if(!(i==="\u517C"||i==="\u517C\u52D9"||i==="\u4FC2"||i==="of"||i==="&"||i==="Quality"||i==="Innovation"||i==="R&D"||i==="Solutions"||i==="Development"||i==="Laboratory"||i==="and"||i==="Food"||i==="Beverage")&&n.allKnownDepartments.has(i)){s.push({name:i,index:t});for(let g=t;g<t+l;g++)b.add(g)}}for(let l=0;l<f;l++){if(b.has(l))continue;let t=p[l];for(t.endsWith("\u9577")&&t.length>1?t=t.slice(0,-1):t.endsWith("\u7D71\u62EC")&&t.length>2&&(t=t.slice(0,-2));;){let c=!1;if(t.startsWith("\u62C5\u5F53")&&t.length>2||t.startsWith("\u5C02\u4EFB")&&t.length>2||t.startsWith("\u517C\u52D9")&&t.length>2?(t=t.slice(2),c=!0):(t.startsWith("\u526F")||t.startsWith("\u517C"))&&t.length>1&&(t=t.slice(1),c=!0),!c)break}if(t.includes("\u30FB")&&!n.allKnownDepartments.has(t)){let c=t.split("\u30FB"),y=c[c.length-1],D=r.find(P=>y.endsWith(P));if(D){for(let P of c){let C=P;r.some(a=>C.endsWith(a))||(C=C+D);let E=t!=="\u517C"&&t!=="\u4FC2"&&t!=="of"&&t!=="&"&&t!=="Quality"&&t!=="Innovation"&&t!=="R&D"&&t!=="Solutions"&&t!=="Development"&&t!=="Laboratory"&&t!=="and"&&t!=="Food"&&t!=="Beverage"&&n.allKnownDepartments.has(C),u=r.some(a=>C.endsWith(a)),o=r.includes(C);(E||u&&!o)&&s.push({name:C,index:l})}continue}}let h=t!=="\u517C"&&t!=="\u4FC2"&&t!=="of"&&t!=="&"&&t!=="Quality"&&t!=="Innovation"&&t!=="R&D"&&t!=="Solutions"&&t!=="Development"&&t!=="Laboratory"&&t!=="and"&&t!=="Food"&&t!=="Beverage"&&n.allKnownDepartments.has(t),i=r.some(c=>t.endsWith(c)),g=r.includes(t);(h||i&&!g)&&s.push({name:t,index:l})}return s.sort((l,t)=>l.index-t.index),s.map(l=>l.name)},L=(e,n)=>{let s=0;for(let r of n)s<e.length&&r===e[s]&&s++;return s===e.length},A={name:"Standard",parse:(e,n,s="full")=>{let r=M(e.department,"");if(!r)return null;let p=J(r,n.allKnownDepartments),f=new Map;for(let t of p)f.set(t,(f.get(t)||0)+1);let b=t=>{let h=[],i=[];for(let g=0;g<t.length;g++){let c=t[g];if(c==="\u517C"){i.length>0&&(h.push(i),i=[]);continue}let y=k(c),D=y.rank,P=f.get(c)||0,C=Q(c,P);if(i.length===0)i.push(c);else{let E=i[i.length-1],u=k(E),o=u.rank;if(i.includes(c))h.push(i),i=[c];else{let a=!1;if(C)a=!0;else if(u.type===y.type){let m=v(E),d=v(c);m&&d&&m!==d||E.endsWith("\u672C\u90E8")&&c.endsWith("\u672C\u90E8")||E.endsWith("\u90E8\u9580")&&c.endsWith("\u4E8B\u696D\u90E8")||E.endsWith("\u4E8B\u696D\u90E8")&&c.endsWith("\u90E8\u9580")||E.endsWith("\u90E8\u9580")&&c.endsWith("\u672C\u90E8")||u.type==="Other"&&y.type==="Other"?a=!0:a=o<D}else a=D>=10,a&&u.type==="Location"&&y.type==="Organization"&&o>=D&&t.slice(g+1).includes(E)&&(a=!1);a?i.push(c):(h.push(i),i=[c])}}if(C){let E=g+1<t.length?t[g+1]:void 0;X(c,E)&&i.length>0&&(h.push(i),i=[])}}return i.length>0&&h.push(i),h},l=[];if(s==="full"&&l.push(...b(p)),s==="pure_org"){let t=p.filter(h=>k(h).type!=="Location");t.length>0&&l.push(...b(t))}if(e.title){let h=/[^\x20-\x7E]/.test(e.title)?/[\s\u3000]*(?:兼務|兼)[\s\u3000]*/:/[,;]|(?:兼務|兼)/,i=e.title.split(h).filter(Boolean),g=[],c=(u,o)=>{let a=z(u),m=z(o),d=a<m;if(!d){let T=v(u),R=v(o);if(T&&R&&T!==R)d=!0;else if(u.endsWith("\u672C\u90E8")&&o.endsWith("\u672C\u90E8"))d=!0;else if(u.endsWith("\u90E8\u9580")&&o.endsWith("\u4E8B\u696D\u90E8")||u.endsWith("\u4E8B\u696D\u90E8")&&o.endsWith("\u90E8\u9580"))d=!0;else if(u.endsWith("\u90E8\u9580")&&o.endsWith("\u672C\u90E8"))d=!0;else{let I=k(u),K=k(o);I.type==="Other"&&K.type==="Other"&&(d=!0)}}return d};for(let u of i){let o=_(u,n);if(o.length===0)continue;let a=[];for(let m of o)if(a.length===0)a.push(m);else{let d=a[a.length-1];if(c(d,m))a.push(m);else{g.push([...a]);let T=!1;for(let R=a.length-2;R>=0;R--){let I=a[R];if(c(I,m)){a=[...a.slice(0,R+1),m],T=!0;break}}T||(a=[m])}}a.length>0&&g.push(a)}let y=[...l],D=u=>i.some(o=>o.includes(u)&&o.length>u.length);for(let u of g){let o=!1;for(let a of l){let m=a.findIndex(d=>u.includes(d));if(m!==-1){let d=a[m],T=u.indexOf(d);if(m>0&&T===0){let R=a.slice(0,m);y.push([...R,...u]),o=!0}else if(T>0&&m===0){let R=u.slice(0,T);y.push([...R,...a]),y.push(u),o=!0}else u.length>a.length-m,o=!0}if(!o){let d=a[a.length-1],T=u[0];c(d,T)&&(y.push([...a,...u]),o=!0)}}o||y.push(u)}let P=[],C=[],E=new Set;for(let u of y){let o=u.join("|");E.has(o)||(E.add(o),C.push(u))}for(let u=0;u<C.length;u++){let o=C[u],a=!1;for(let m=0;m<C.length;m++){if(u===m)continue;let d=C[m];if(d.length>o.length&&d.slice(0,o.length).join("|")===o.join("|")){let T=o[o.length-1];if(!D(T)){a=!0;break}}if(d.length>o.length&&L(o,d)){let T=o[o.length-1];if(!D(T)){a=!0;break}}if(o.length===1&&d.length>0){let T=o[0],R=d[d.length-1];if(T!==R&&R.endsWith(T)){a=!0;break}}}a||P.push(o)}return P.length>0?P:null}if(l.length>0){let t=[];for(let h=0;h<l.length;h++){let i=l[h],g=!1;for(let c=0;c<l.length;c++){if(h===c)continue;let y=l[c];if(y.length>i.length&&L(i,y)){g=!0;break}}g||t.push(i)}return t.length>0?t:null}return null}},F={name:"TitleBased",parse:(e,n,s="full")=>{let r=e.title;if(!r)return null;let p=_(r,n);return p.length>0?[p]:null}};var Z=["uncategorizedCompany","unnamedPerson"],V=e=>{if(typeof e!="object"||e===null)throw new RangeError(`[contact-map] tree naming must be an object; got ${e===null?"null":typeof e}`);for(let n of Z){let s=e[n];if(typeof s!="string"||s.trim()==="")throw new RangeError(`[contact-map] tree naming.${n} must be a non-blank string; got ${typeof s=="string"?JSON.stringify(s):s===null?"null":typeof s}`)}},Y=[A,F],ee=(e,n)=>{let s=M(e.full_name,n),r=M(e.title,"");return r.length>0?`${s} (${r})`:s},W=e=>e.sort((n,s)=>n.label.localeCompare(s.label,"ja")),N=(e,n,s)=>{let r=e.get(n);if(r)return r;let p=s();return e.set(n,p),p},O=e=>encodeURIComponent(e.replace(/\//g,"\uFF0F")),q=e=>e.sort((n,s)=>{let r=!!(n.contact.title&&n.contact.title.trim().length>0),p=!!(s.contact.title&&s.contact.title.trim().length>0);return r&&!p?-1:!r&&p?1:n.label.localeCompare(s.label,"ja")}),B=e=>({name:e.label,type:"file",absolutePath:e.path,relativePath:e.segment,personId:e.contact.person_id,title:e.contact.title||void 0,isPrimary:e.isPrimary}),$=e=>{let n=W(Array.from(e.children.values())).map($),s=q([...e.persons]).map(B);return{name:e.label,type:"directory",absolutePath:e.path,relativePath:e.segment,children:[...s,...n],memberCount:e.personCount}},S=class{constructor(n){this.companyMap=new Map;this.processedPersonIds=new Set;this.allDepts=new Set;this.cachedResult=null;V(n),this.naming=n}appendRecords(n){if(!n||n.length===0)return;let s="full",r=!1;for(let p of n)if(!this.processedPersonIds.has(p.person_id)&&p.department){let f=p.department.split(/\u3000/);for(let b of f){let l=b.trim();if(!l||l==="\u517C"||l==="\u4FC2")continue;if(/[^\x20-\x7E]/.test(l)){let h=l.split(" ").filter(i=>i.length>0&&i!=="\u517C"&&i!=="\u4FC2");for(let i of h)this.allDepts.add(i)}else this.allDepts.add(l)}}for(let p of n){let f=p.person_id;if(!Number.isFinite(f)||this.processedPersonIds.has(f))continue;this.processedPersonIds.add(f),r=!0;let b=M(p.company_name,this.naming.uncategorizedCompany),l=ee(p,this.naming.unnamedPerson),t=`company:${O(b)}`,h=N(this.companyMap,t,()=>({label:b,segment:t,path:`/${t}`,departments:new Map,persons:[],personCount:0})),i=[],g={allKnownDepartments:this.allDepts};for(let c of Y){let y=c.parse(p,g,s);if(y&&y.length>0){i=y;break}}i.length===0&&i.push([]);for(let c=0;c<i.length;c++){let y=i[c];if(y.length===0){let o=`person:${f}`,a=`${h.path}/${o}`;h.persons.some(d=>d.contact.person_id===f)||h.persons.push({contact:p,label:l,path:a,segment:o,isPrimary:!0});continue}let D=null,P=h.path;if(y.length>0){let o=y[0],a=`department:${O(o)}`;D=N(h.departments,a,()=>({label:o,segment:a,path:`${P}/${a}`,children:new Map,persons:[],personCount:0})),P=D.path,D.personCount+=1;for(let m=1;m<y.length;m++){let d=y[m],T=`department:${O(d)}`;if(!D)throw new Error("Unexpected null currentDepartmentNode");D=N(D.children,T,()=>({label:d,segment:T,path:`${P}/${T}`,children:new Map,persons:[],personCount:0})),P=D.path,D.personCount+=1}}else continue;let C=`person:${f}`,E=`${D.path}/${C}`;D.persons.some(o=>o.contact.person_id===f)||D.persons.push({contact:p,label:l,path:E,segment:C,isPrimary:c===0})}h.personCount+=1}r&&(this.cachedResult=null)}getSnapshot(){if(this.cachedResult)return this.cachedResult;let n={},s=W(Array.from(this.companyMap.values())).map(r=>{let p=W(Array.from(r.departments.values())).map($),f=q([...r.persons]).map(B),b={name:r.label,type:"directory",absolutePath:r.path,relativePath:r.segment,children:[...f,...p],memberCount:r.personCount};return n[r.label]=b,b});return this.cachedResult={tree:s,companyMap:n},this.cachedResult}append(n){this.appendRecords(n)}build(){return this.getSnapshot().tree}reset(){this.companyMap.clear(),this.processedPersonIds.clear(),this.allDepts.clear(),this.cachedResult=null}getUniquePersonCount(){return this.processedPersonIds.size}get size(){return this.processedPersonIds.size}};var te=3e3,U=60,ne=700,re=25,se=e=>{let n=U+e/re;return Math.min(ne,Math.max(U,n))};var ie={setTimeout:(e,n)=>setTimeout(e,n),clearTimeout:e=>clearTimeout(e),now:()=>Date.now()},w=class{constructor(n,s=ie){this.postMessage=n;this.timer=s;this.naming=null;this.builder=null;this.pendingRecords=[];this.rawRecords=[];this.activeGeneration=0;this.rebuildEpoch=0;this.lastEmitTime=0;this.emitTimerId=null;this.processTimerId=null;this.isProcessing=!1;this.finalizeRequested=!1}handleMessage(n){switch(n.type){case"RESET_TREE":{let s=new S(n.naming);this.cancelTimers(),this.activeGeneration=n.generation,this.rebuildEpoch=Math.max(this.rebuildEpoch,n.epochBase)+1,this.builder=s,this.naming=n.naming,this.pendingRecords.length=0,this.rawRecords.length=0,this.lastEmitTime=0,this.finalizeRequested=!1,this.isProcessing=!1;break}case"APPEND_RECORDS":{if(n.generation!==this.activeGeneration)return;this.requireBuilder();for(let s=0;s<n.records.length;s++){let r=n.records[s];this.pendingRecords.push(r),this.rawRecords.push(r)}this.scheduleProcess();break}case"FINALIZE_TREE":{if(n.generation!==this.activeGeneration)return;this.requireBuilder(),this.finalizeRequested=!0,this.scheduleProcess();break}}}requireBuilder(){if(this.builder===null)throw new Error("[contact-map] tree worker received a generation message before RESET_TREE delivered the fallback names");return this.builder}requireNaming(){if(this.naming===null)throw new Error("[contact-map] tree worker has no fallback names: RESET_TREE was never received");return this.naming}scheduleProcess(){this.isProcessing||this.processTimerId!==null||(this.processTimerId=this.timer.setTimeout(()=>{this.processTimerId=null,this.processStep()},0))}processStep(){this.isProcessing=!0;let n=Math.min(te,this.pendingRecords.length);if(n>0){let r=this.pendingRecords.splice(0,n);this.requireBuilder().append(r)}if(this.pendingRecords.length>0){this.isProcessing=!1,this.scheduleProcess(),this.scheduleEmit(!1);return}if(this.finalizeRequested){this.finalizeRequested=!1;let r=new S(this.requireNaming());r.append(this.rawRecords),this.builder=r,this.rebuildEpoch+=1,this.isProcessing=!1,this.emitNow(!0);return}this.isProcessing=!1,this.scheduleEmit(!0)}scheduleEmit(n){if(this.emitTimerId!==null){n&&(this.timer.clearTimeout(this.emitTimerId),this.emitTimerId=null,this.emitNow(!0));return}let s=this.timer.now(),r=se(this.requireBuilder().getUniquePersonCount()),p=s-this.lastEmitTime;if(p>=r||n)this.emitNow(n);else{let f=r-p;this.emitTimerId=this.timer.setTimeout(()=>{this.emitTimerId=null,this.emitNow(this.pendingRecords.length===0&&!this.finalizeRequested)},f)}}emitNow(n){this.lastEmitTime=this.timer.now();let s=this.requireBuilder(),r=s.build();this.postMessage({type:"TREE_CHUNK",generation:this.activeGeneration,tree:r,consumedRecords:this.rawRecords.length,uniquePersonCount:s.getUniquePersonCount(),isIdle:n,rebuildEpoch:this.rebuildEpoch})}cancelTimers(){this.processTimerId!==null&&(this.timer.clearTimeout(this.processTimerId),this.processTimerId=null),this.emitTimerId!==null&&(this.timer.clearTimeout(this.emitTimerId),this.emitTimerId=null)}dispose(){this.cancelTimers(),this.pendingRecords.length=0,this.rawRecords.length=0}};var ae=new w(e=>{self.postMessage(e)});self.onmessage=e=>{ae.handleMessage(e.data)};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiquants/contact-map",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "description": "Reusable contact-map feature package: shared types/schemas, React (Router v7 / v8) UI with virtual scrolling + tree view + incremental Web Worker + fuzzy search + resize panels, and a drizzle (mssql) server layer with DI ports.",
5
5
  "sideEffects": [
6
6
  "**/*.css"
@@ -59,12 +59,12 @@
59
59
  "tailwind-merge": "^3.5.0"
60
60
  },
61
61
  "devDependencies": {
62
- "@aiquants/directory-tree": "^3.11.1",
62
+ "@aiquants/directory-tree": "^3.12.0",
63
63
  "@aiquants/fuzzy-search": "^2.2.1",
64
64
  "@aiquants/resize-panels": "^2.0.1",
65
- "@aiquants/select-box": "^0.9.2",
65
+ "@aiquants/select-box": "^0.11.0",
66
66
  "@aiquants/swipe-overlay": "^1.2.5",
67
- "@aiquants/virtualscroll": "^3.5.0",
67
+ "@aiquants/virtualscroll": "^3.7.0",
68
68
  "@tailwindcss/cli": "^4.1.18",
69
69
  "@testing-library/jest-dom": "^6.9.1",
70
70
  "@testing-library/react": "^16.3.2",
@@ -85,12 +85,12 @@
85
85
  "zod": "^3.25.76"
86
86
  },
87
87
  "peerDependencies": {
88
- "@aiquants/directory-tree": "^3.11.1",
88
+ "@aiquants/directory-tree": "^3.12.0",
89
89
  "@aiquants/fuzzy-search": "^2.2.1",
90
90
  "@aiquants/resize-panels": "^2.0.1",
91
- "@aiquants/select-box": "^0.9.2",
91
+ "@aiquants/select-box": "^0.11.0",
92
92
  "@aiquants/swipe-overlay": "^1.2.5",
93
- "@aiquants/virtualscroll": "^3.5.0",
93
+ "@aiquants/virtualscroll": "^3.7.0",
94
94
  "drizzle-orm": ">=1.0.0-beta.4 <2.0.0",
95
95
  "react": ">=18",
96
96
  "react-dom": ">=18",