PageSourceSearch

https://xynergy.ai/_next/static/chunks/6205-e61343b65d87faa5.js

js xynergy.ai collected 2026-10-05 16:01:42 UTC 47,992 bytes, 1 lines download raw bytes

1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[6205],{2134:(e,t,n)=>{"use strict";function a(e){let t=e.getFullYear(),n=e.getMonth();return{start:new Date(t,n,1,0,0,0,0),end:new Date(t,n+1,0,23,59,59,999)}}function r(e){if(!e)return null;try{let{Timestamp:t}=n(20752);if(e instanceof t)return e.toDate()}catch{}if(e instanceof Date)return isNaN(e.getTime())?null:new Date(e.getTime());if("string"==typeof e){let t=new Date(e);return isNaN(t.getTime())?null:t}if("object"==typeof e){if("toDate"in e&&"function"==typeof e.toDate)try{let t=e.toDate();if(t instanceof Date&&!isNaN(t.getTime()))return t}catch{}if("seconds"in e&&"number"==typeof e.seconds&&"nanoseconds"in e&&"number"==typeof e.nanoseconds)try{let{Timestamp:t}=n(20752),a=new t(e.seconds,e.nanoseconds).toDate();if(a instanceof Date&&!isNaN(a.getTime()))return a}catch{}}return null}function o(){let e=new Date,t=e.getFullYear(),n=String(e.getMonth()+1).padStart(2,"0"),a=String(e.getDate()).padStart(2,"0");return`${t}-${n}-${a}`}function i(e=30){let t=new Date;return new Date(Date.UTC(t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDate()+e)).toISOString().split("T")[0]}function l(e=30){let t=new Date,n=new Date(t.getFullYear(),t.getMonth(),t.getDate()+e),a=n.getFullYear(),r=String(n.getMonth()+1).padStart(2,"0"),o=String(n.getDate()).padStart(2,"0");return`${a}-${r}-${o}`}function s(e){let[t,n,a]=e.split("-").map(Number);return new Date(Date.UTC(t,n-1,a))}function u(e,t,n,a){return e&&t&&n&&a?e.filter(e=>{let r=a(e);return!(!r||!(r instanceof Date)||isNaN(r.getTime()))&&r>=t&&r<=n}):[]}function c(e){let t=new Date(Date.UTC(e.getFullYear(),e.getMonth(),e.getDate())),n=t.getUTCDay()||7;t.setUTCDate(t.getUTCDate()+4-n);let a=new Date(Date.UTC(t.getUTCFullYear(),0,1));return Math.ceil(((t.getTime()-a.getTime())/864e5+1)/7)}n.d(t,{$L:()=>u,OG:()=>r,QW:()=>c,Qv:()=>a,SD:()=>s,ll:()=>l,o0:()=>i,ri:()=>o})},2687:(e,t,n)=>{"use strict";n.d(t,{AQ:()=>o,Bi:()=>i,F$:()=>u,HI:()=>a,I2:()=>s,K8:()=>r,Xd:()=>l});let a=["salary","business","bonus","insurance","dividend","rent","interest","sales","filial","pension","alimony","other_income"],r=["food","home","transportation","education","investment","beauty","entertainment","other"],o={food:["外食","食材","飲料","零食","外送","其他餐飲"],home:["房租/房貸","水電瓦斯","網路/電信","家具家電","日用品","清潔用品","其他居家"],transportation:["大眾運輸","計程車/叫車","油費","停車費","保養維修","保險","其他交通"],education:["學費","書籍","補習/課程","文具用品","其他教育"],investment:["股票","基金","債券","儲蓄","其他投資"],beauty:["化妝品","保養品","服飾","配件","美髮","其他美容"],entertainment:["電影","音樂","遊戲","旅遊","運動","其他娛樂"],other:["醫療","保險","稅務","禮金","其他"]},i={food:"餐飲食品",home:"居家生活",transportation:"交通運輸",education:"教育學習",investment:"投資理財",beauty:"美容服飾",entertainment:"休閒娛樂",other:"其他支出",salary:"薪資",business:"執行業務",bonus:"獎金",insurance:"保險金",dividend:"股利",rent:"租金收入",interest:"利息收入",sales:"營業收入",filial:"孝養金",pension:"撫恤金",alimony:"贍養費",other_income:"其他收入",未分類:"未分類"},l=e=>a.includes(e),s=e=>r.includes(e),u=e=>i[e]||e||"未分類"},10412:(e,t,n)=>{"use strict";n.d(t,{Nb:()=>l,Yz:()=>s});var a=n(15418);let r=a.k5(["manual","estimate","ai","import","line","mobile","recurring","migrated"]),o=a.k5(["income","expense"]),i=a.Ik({legacyBalanceId:a.Yj().optional(),confidence:a.k5(["high","medium","low"]).optional(),extractionModel:a.Yj().optional()}).strict();a.Ik({userId:a.Yj().min(1,"userId 不能為空"),type:o,amount:a.ai().positive("金額必須大於 0"),currency:a.Yj().min(1).default("TWD"),accountId:a.Yj().min(1,"accountId 不能為空"),category:a.Yj().min(1,"category 不能為空"),date:a.Yj().regex(/^\d{4}-\d{2}-\d{2}$/,"日期格式必須為 YYYY-MM-DD"),description:a.Yj().max(500).optional(),source:r.default("manual"),isEstimate:a.zM().optional(),documentId:a.Yj().min(1).optional(),meta:i.optional(),createdAt:a.bz(),updatedAt:a.bz()});let l=a.Ik({type:o,amount:a.ai().positive("金額必須大於 0"),currency:a.Yj().min(1).optional(),accountId:a.Yj().min(1),category:a.Yj().min(1),date:a.Yj().regex(/^\d{4}-\d{2}-\d{2}$/),description:a.Yj().max(500).optional(),source:r.optional(),isEstimate:a.zM().optional(),documentId:a.Yj().min(1).optional(),meta:i.optional()});function s(e){return e.slice(0,7)}},15203:(e,t,n)=>{"use strict";n.d(t,{k:()=>l});var a=n(85047),r=n(31615),o=n(82623),i=n(34961);let l=r.forwardRef(({className:e,value:t,...n},r)=>(0,a.jsx)(o.bL,{ref:r,className:(0,i.cn)("relative h-4 w-full overflow-hidden rounded-full bg-secondary",e),...n,children:(0,a.jsx)(o.C1,{className:"h-full w-full flex-1 bg-primary transition-all",style:{transform:`translateX(-${100-(t||0)}%)`}})}));l.displayName=o.bL.displayName}
1,15974:(e,t,n)=>{"use strict";n.d(t,{KM:()=>s,OX:()=>u});var a=n(24571),r=n(15418),o=n(76458),i=n(18654);let l=r.g1(r.Yj(),r.zM());function s(e){let t=l.safeParse(e);return t.success?t.data:{}}async function u(e,t){if(o.db&&e&&t)try{let n=(0,a.doc)(o.db,o.USERS,e);await (0,a.mZ)(n,{[`onboarding.dataTaskFlags.${t}`]:!0,updatedAt:(0,a.serverTimestamp)()}),(0,i.fH)("已標記資料任務完成",{uid:e,taskId:t})}catch(e){throw(0,i.vV)("標記資料任務完成失敗:",e),e}}},21016:(e,t,n)=>{"use strict";n.d(t,{Fc:()=>s,TN:()=>c,XL:()=>u});var a=n(85047),r=n(31615),o=n(63610),i=n(34961);let l=(0,o.F)("relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",{variants:{variant:{default:"bg-background text-foreground",destructive:"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive"}},defaultVariants:{variant:"default"}}),s=r.forwardRef(({className:e,variant:t,...n},r)=>(0,a.jsx)("div",{ref:r,role:"alert",className:(0,i.cn)(l({variant:t}),e),...n}));s.displayName="Alert";let u=r.forwardRef(({className:e,...t},n)=>(0,a.jsx)("h5",{ref:n,className:(0,i.cn)("mb-1 font-medium leading-none tracking-tight",e),...t}));u.displayName="AlertTitle";let c=r.forwardRef(({className:e,...t},n)=>(0,a.jsx)("div",{ref:n,className:(0,i.cn)("text-sm [&_p]:leading-relaxed",e),...t}));c.displayName="AlertDescription"},21363:(e,t,n)=>{"use strict";n.d(t,{D0:()=>i,oL:()=>l});var a=n(58661),r=n(47026);function o(e,t,n,a){let r=[],o=e;for(let e of(o-=a.reduce((e,t)=>e+t.minimumPayment,0),n)){if(o<=0)break;let n=t.find(t=>t.id===e);if(!n)continue;let i=a.find(t=>t.liabilityId===e)?.minimumPayment||0;n.value;let l=Math.max(0,n.value-i);if(l>0){let t=Math.min(o,l);r.push({liabilityId:e,monthlyPayment:Math.round((i+t)*100)/100}),o-=t}else r.push({liabilityId:e,monthlyPayment:i})}for(let e of t){if(n.includes(e.id))continue;let t=a.find(t=>t.liabilityId===e.id)?.minimumPayment||0;r.push({liabilityId:e.id,monthlyPayment:t})}return r}function i(e){let t,{liabilities:n,monthlyBudget:r,strategy:i}=e,l=n.filter(e=>(Number(e.value)||0)>0);if(0===l.length)return{monthlyBudget:r,strategy:i,liabilityPlans:[],monthlyDetails:[],totalMonths:0,totalInterest:0,totalPayment:0,summary:{totalLiabilities:0,averageMonthlyPayment:0,completionDate:new Date().toISOString()}};let s=function(e,t,n){var a,r,i,l,s,u;if(0===t.length)return[];let c=t.map(e=>({liabilityId:e.id,minimumPayment:e.minimumPayment})),d=c.reduce((e,t)=>e+t.minimumPayment,0);if(e<d){let t=e/d;return c.map(e=>({liabilityId:e.liabilityId,monthlyPayment:Math.round(e.minimumPayment*t*100)/100}))}switch(n.type){case"proportional":default:return function(e,t,n){let a=[],r=e-n.reduce((e,t)=>e+t.minimumPayment,0),o=t.reduce((e,t)=>e+t.value,0);if(0===o)return n.map(e=>({liabilityId:e.liabilityId,monthlyPayment:e.minimumPayment}));for(let e of t){let t=n.find(t=>t.liabilityId===e.id)?.minimumPayment||0,i=e.value/o*r;a.push({liabilityId:e.id,monthlyPayment:Math.round((t+i)*100)/100})}return a}(e,t,c);case"priority":return o(e,t,n.priorityOrder||[],c);case"high-interest":let m;return a=e,r=t,i=c,m=[...r].sort((e,t)=>t.annualRate-e.annualRate).map(e=>e.id),o(a,r,m,i);case"low-balance":let h;return l=e,s=t,u=c,h=[...s].sort((e,t)=>e.value-t.value).map(e=>e.id),o(l,s,h,u);case"custom":return function(e,t,n,a){let r=[],o=0;for(let e of t){let t=n[e.id],i=a.find(t=>t.liabilityId===e.id)?.minimumPayment||0;if(void 0!==t){let n=Math.max(i,t);r.push({liabilityId:e.id,monthlyPayment:Math.round(100*n)/100}),o+=n}}if(o>e){let t=e/o;return r.map(e=>({...e,monthlyPayment:Math.round(e.monthlyPayment*t*100)/100}))}for(let e of t){if(void 0!==n[e.id])continue;let t=a.find(t=>t.liabilityId===e.id)?.minimumPayment||0;r.push({liabilityId:e.id,monthlyPayment:t}),o+=t}return r}(e,t,n.customAllocations||{},c)}}(r,l,i),u=[];for(let e of l){let t=s.find(t=>t.liabilityId===e.id);if(!t)continue;let n=function(e,t){if(0===e.loanTerm){let n=e.annualRate/100/12,a=e.value*n,r=[],o=[],i=0,l=0,s=e.value;for(let e=1;e<=600;e++){let a=s*n,u=Math.max(0,Math.min(t-a,s));s=Math.max(0,s-u),i+=a,l+=u,r.push({month:e,principal:Math.round(100*u)/100,interest:Math.round(100*a)/100,payment:Math.round(100*t)/100,remainingBalance:Math.round(100*s)/100}),o.push({month:e,principalPaid:Math.round(100*l)/100,interestPaid:Math.round(100*i)/100,remainingBalance:Math.round(100*s)/100})}let u={monthlyPayment:Math.round(100*Math.max(t,a))/100,totalPayment:1/0,totalInterest:1/0,loanTerm:0,repaymentMethod:e.repaymentMethod,repaymentSchedule:r,monthlyData:o};
1return{liabilityId:e.id,liabilityName:e.name,loanResult:u,completionMonth:-1,totalInterest:1/0,totalPayment:1/0}}let n={loanAmount:e.value,annualRate:e.annualRate,loanTerm:e.loanTerm,repaymentMethod:e.repaymentMethod,loanType:"personal-loan"},r=(0,a.OM)(n),o=e.value,i=e.annualRate/100/12,l=0,s=0,u=0,c=2*r.repaymentSchedule.length,d=[],m=[],h=0,p=0;for(;o>.01&&l<c;){l++;let e=o*i,n=Math.min(t-e,o);if(o=Math.max(0,o-n),s+=e,u+=t,h+=n,p+=e,d.push({month:l,principal:Math.round(100*n)/100,interest:Math.round(100*e)/100,payment:Math.round(100*t)/100,remainingBalance:Math.round(100*o)/100}),m.push({month:l,principalPaid:Math.round(100*h)/100,interestPaid:Math.round(100*p)/100,remainingBalance:Math.round(100*o)/100}),o<=.01)break}let f=l,y={...r,monthlyPayment:Math.round(100*t)/100,totalPayment:Math.round(100*u)/100,totalInterest:Math.round(100*s)/100,repaymentSchedule:d,monthlyData:m};return{liabilityId:e.id,liabilityName:e.name,loanResult:y,completionMonth:f,totalInterest:Math.round(100*s)/100,totalPayment:Math.round(100*u)/100}}(e,t.monthlyPayment);u.push(n)}let c=[],d=u.map(e=>e.completionMonth).filter(e=>e>0),m=d.length>0?Math.max(...d):600,h=new Date(l[0]?.startDate||new Date().toISOString());for(let e=1;e<=m;e++){let t=new Date(h);t.setMonth(t.getMonth()+e-1);let n={month:e,date:t.toISOString(),allocations:[],totalPayment:0,totalPrincipal:0,totalInterest:0};for(let t of u){if(t.completionMonth>0&&e>t.completionMonth)continue;let a=t.loanResult.repaymentSchedule[e-1];if(!a)continue;let r=s.find(e=>e.liabilityId===t.liabilityId);r&&(t.completionMonth>0&&a.remainingBalance<=.01||(n.allocations.push({liabilityId:t.liabilityId,liabilityName:t.liabilityName,payment:Math.min(r.monthlyPayment,a.payment),principal:a.principal,interest:a.interest,remainingBalance:a.remainingBalance}),n.totalPayment+=a.payment,n.totalPrincipal+=a.principal,n.totalInterest+=a.interest))}c.push(n)}let p=u.some(e=>-1===e.completionMonth),f=p?1/0:u.reduce((e,t)=>t.totalInterest===1/0?1/0:e+t.totalInterest,0),y=p?1/0:u.reduce((e,t)=>t.totalPayment===1/0?1/0:e+t.totalPayment,0),g=l.reduce((e,t)=>e+t.value,0),b=p?null:((t=new Date(h)).setMonth(t.getMonth()+m),t);return{monthlyBudget:r,strategy:i,liabilityPlans:u,monthlyDetails:c,totalMonths:m,totalInterest:Math.round(100*f)/100,totalPayment:Math.round(100*y)/100,summary:{totalLiabilities:Math.round(100*g)/100,averageMonthlyPayment:Math.round(100*r)/100,completionDate:b?b.toISOString():new Date().toISOString()}}}function l(e,t=2.5,n=20,a="equal-payment"){let o=(0,r.A7)(e.value,e.currency);return{id:e.id,name:e.name,value:o,currency:e.currency,annualRate:e.annualRate??t,loanTerm:e.loanTerm??n,repaymentMethod:e.repaymentMethod??a,minimumPayment:e.minimumPayment??0,startDate:e.startDate}}},28710:(e,t,n)=>{"use strict";n.d(t,{U:()=>r,f:()=>a});let a={hasWill:!1,hasAdvanceDirective:!1,hasGuardianship:!1},r="financial/summary"},30834:e=>{e.exports={svg:"LogoLoader_svg__K_m18",bgCircle:"LogoLoader_bgCircle__I9a0P",ringOuter:"LogoLoader_ringOuter__MOHXw",ringInner:"LogoLoader_ringInner__f3O_A",triTop:"LogoLoader_triTop__GNYgx",triBl:"LogoLoader_triBl__rI1Ka",triBr:"LogoLoader_triBr__uR9KW",orbit1:"LogoLoader_orbit1__fs26i",orbit2:"LogoLoader_orbit2__XhKZ2",orbit3:"LogoLoader_orbit3__e4hO3",orbitCounter:"LogoLoader_orbitCounter__vpKzS",triOutlineTop:"LogoLoader_triOutlineTop__mDP5N",triOutlineBl:"LogoLoader_triOutlineBl__iVjAO",triOutlineBr:"LogoLoader_triOutlineBr__v3z0a",comet:"LogoLoader_comet__mL9zX",cometThin:"LogoLoader_cometThin__WPzgT",orbit:"LogoLoader_orbit__NJhb0",bgShift:"LogoLoader_bgShift__b2JcU",rotCw:"LogoLoader_rotCw__eCgi_",rotCcw:"LogoLoader_rotCcw__G86Ks",triFlyTop:"LogoLoader_triFlyTop__dt_UM",triFlyBl:"LogoLoader_triFlyBl__BHPtH",triFlyBr:"LogoLoader_triFlyBr__6mkHr",orbitCw:"LogoLoader_orbitCw__SzhUp",orbitCcw:"LogoLoader_orbitCcw__EK7PG",outline:"LogoLoader_outline__9LjpJ",olBgIn:"LogoLoader_olBgIn__z4VpU",olRingOuter:"LogoLoader_olRingOuter__GGZ7h",olRingInner:"LogoLoader_olRingInner__xanAk",olTriStrokeTop:"LogoLoader_olTriStrokeTop__Rw8NR",olTriStrokeBl:"LogoLoader_olTriStrokeBl__VjX5L",olTriStrokeBr:"LogoLoader_olTriStrokeBr___wAAB",triFillTop:"LogoLoader_triFillTop__5VxIo",olTriFillTop:"LogoLoader_olTriFillTop__GD8CV",triFillBl:"LogoLoader_triFillBl__yQQYX",olTriFillBl:"LogoLoader_olTriFillBl__YAGZS",triFillBr:"LogoLoader_triFillBr__jIkwr",olTriFillBr:"LogoLoader_olTriFillBr__mpbgE",cometGroup:"LogoLoader_cometGroup__k9pBP",olCometIn:"LogoLoader_olCometIn__6KPhH",comet1:"LogoLoader_comet1__Uig7S",comet2:"LogoLoader_comet2__swgHT"}},38187:(e,t,n)=>{"use strict";n.d(t,{E:()=>s});var a=n(85047),r=n(31615),o=n(63610),i=n(34961);let l=(0,o.F)("inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",{variants:{variant:{default:"border-transparent bg-primary text-primary-foreground hover:bg-primary/80",secondary:"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",destructive:"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",outline:"text-foreground"}},defaultVariants:{variant:"default"}}),s=r.forwardRef(({className:e,variant:t,...n},r)=>(0,a.jsx)("div",{ref:r,className:(0,i.cn)(l({variant:t}),e),...n}));s.displayName="Badge"},41482:(e,t,n)=>{"use strict";n.d(t,{JV:()=>o,Ps:()=>s,ng:()=>i});let a={twd:1,usd:31.5,jpy:.22,eur:34.2},r=["stocks","bonds","funds"];function o(e,t=e=>Number(e)||0){if(!e?.length)return 0;let n=new Map;for(let a of e){if("income"!==a.type&&"expense"!==a.type)continue;let e=t(a.amount??0,a.currency??"TWD");if(!Number.isFinite(e)||e<=0)continue;let r="string"==typeof a.date?a.date.slice(0,7):"",o=`${a.type}|${String(a.accountId??"")}|${r}`,i=n.get(o)??{type:a.type,detailed:0,estimate:0};!0===a.isEstimate?i.estimate+=e:i.detailed+=e,n.set(o,i)}let a=0,r=0;for(let e of n.values()){let t=e.detailed>0?e.detailed:e.estimate;"income"===e.type?a+=t:r+=t}return Math.round((a-r)*100)/100}function i(e,t,n){let a=o(e,n),r=function(e,t){if(!e?.length)return 0;let n=0;for(let a of e)"cash"===String(a.type)&&(n+=t(a.value??0,a.currency));return n}(t,n);return{ledgerCash:a,openingCashAssets:r,totalCash:Math.round((a+r)*100)/100}}function l(e){let t=new Map;for(let n of e)0!==n.amount&&t.set(n.type,(t.get(n.type)??0)+n.amount);return Array.from(t.entries()).map(([e,t])=>({type:e,amount:t})).sort((e,t)=>
1t.amount-e.amount)}function s(e){var t;let n=e.convert??(t=e.rates??a,(e,n)=>{var a,r,o;let i;return a=e,r=n,o=t,("number"==typeof a&&Number.isFinite(a)?a:Number(a)||0)*o["usd"===(i=String(r??"").toLowerCase())||"jpy"===i||"eur"===i?i:"twd"]}),o=e.investments??[],s=e.assets??[],{totalCash:u,ledgerCash:c,openingCashAssets:d}=i(e.ledgerEntries,s,n),m=s.filter(e=>"cash"!==e.type),h=m.map(e=>({type:String(e.type??"other"),amount:n(function(e,t){if(r.includes(String(e.type))){let n=t.find(t=>t.accountId===e.accountId&&t.symbol===e.name);if(n)return(n.quantity||0)*(n.price||0)}return e.value||0}(e,o),e.currency)})),p=h.reduce((e,t)=>e+t.amount,0),f=new Set(m.filter(e=>r.includes(String(e.type))).map(e=>`${e.accountId??""}__${e.name??""}`)),y=o.filter(e=>!f.has(`${e.accountId??""}__${e.symbol??""}`)).reduce((e,t)=>e+n((t.quantity||0)*(t.price||0),t.currency),0),g=(e.liabilities??[]).map(e=>({type:String(e.type??"other"),amount:n(e.value,e.currency)})),b=g.reduce((e,t)=>e+t.amount,0),M=u+p+y;return{totalCash:u,ledgerCash:c,openingCashAssets:d,otherAssetsTotal:p,standaloneInvestmentTotal:y,totalAssets:M,totalLiabilities:b,netWorth:M-b,assetsByType:l([{type:"cash",amount:u},...h,{type:"investment",amount:y}]),liabilitiesByType:l(g)}}},43174:(e,t,n)=>{"use strict";function a(e){return e.type?e.type:e.symbol?4===e.symbol.length&&/^\d{4}$/.test(e.symbol)?"stocks":e.symbol.startsWith("00")||e.symbol.startsWith("01")||e.symbol.includes("-")||!/^\d+$/.test(e.symbol)?"funds":"stocks":e.name&&e.name.includes("基金")?"funds":null}function r(e){switch(e){case"stocks":return{name:"股票",color:"#3b82f6"};case"bonds":return{name:"債券",color:"#10b981"};case"realestate":return{name:"不動產",color:"#f59e0b"};case"funds":return{name:"基金",color:"#ec4899"};default:return{name:"其他",color:"#8b5cf6"}}}n.d(t,{GR:()=>a,H0:()=>r})}
1,45713:(e,t,n)=>{"use strict";n.d(t,{WK:()=>i,clearFinancialSummaryCached:()=>s,ys:()=>l});let a=new Map,r="financial_summary_";function o(e){return`${r}${e}`}function i(e){let t=a.get(e);if(t)return t.data;let n=function(e){try{let t=sessionStorage.getItem(o(e));if(!t)return;let n=JSON.parse(t);if(!n?.data?.rawData)return;return n}catch{return}}(e);if(n)return a.set(e,n),n.data}function l(e,t){let n={data:t,cachedAt:Date.now()};a.set(e,n);try{sessionStorage.setItem(o(e),JSON.stringify(n))}catch{}}function s(e){if(e){a.delete(e);try{sessionStorage.removeItem(o(e))}catch{}return}a.clear();try{let e=[];for(let t=0;t<sessionStorage.length;t++){let n=sessionStorage.key(t);n?.startsWith(r)&&e.push(n)}e.forEach(e=>sessionStorage.removeItem(e))}catch{}}},54306:(e,t,n)=>{"use strict";n.d(t,{default:()=>d});var a=n(85047),r=n(31615),o=n(34961),i=n(30834),l=n.n(i);let s="0,-90 -39,-22.5 39,-22.5",u="-78,45 0,45 -39,-22.5",c="0,45 78,45 39,-22.5";function d({variant:e="orbit",size:t=96,text:n="",fullScreen:i=!1,className:m}){let h=(0,r.useId)().replace(/:/g,""),p=`xll-bg-${h}`,f=`xll-gold-${h}`,y=(0,a.jsxs)("svg",{className:(0,o.cn)(l().svg,l()[e]),viewBox:"-160 -160 320 320",width:t,height:t,role:"img","aria-label":"鑫世紀理財載入中",children:[(0,a.jsxs)("defs",{children:[(0,a.jsxs)("linearGradient",{id:p,x1:"0%",y1:"0%",x2:"100%",y2:"100%",children:[(0,a.jsx)("stop",{offset:"0%",stopColor:"#3B82F6"}),(0,a.jsx)("stop",{offset:"50%",stopColor:"#7C3AED"}),(0,a.jsx)("stop",{offset:"100%",stopColor:"#8B5CF6"})]}),(0,a.jsxs)("linearGradient",{id:f,x1:"0%",y1:"0%",x2:"0%",y2:"100%",children:[(0,a.jsx)("stop",{offset:"0%",stopColor:"#FBBF24"}),(0,a.jsx)("stop",{offset:"100%",stopColor:"#EAB308"})]})]}),(0,a.jsx)("circle",{className:l().bgCircle,cx:"0",cy:"0",r:"148",fill:`url(#${p})`}),"orbit"===e?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("circle",{className:l().ringOuter,cx:"0",cy:"0",r:"110",fill:"none",stroke:`url(#${f})`,strokeWidth:"5"}),(0,a.jsx)("circle",{className:l().ringInner,cx:"0",cy:"0",r:"100",fill:"none",stroke:`url(#${f})`,strokeWidth:"2.5",opacity:"0.7"}),(0,a.jsx)("circle",{className:(0,o.cn)(l().comet,l().orbit1),cx:"0",cy:"0",r:"110",transform:"rotate(-90)"}),(0,a.jsx)("circle",{className:(0,o.cn)(l().comet,l().cometThin,l().orbit2),cx:"0",cy:"0",r:"110",transform:"rotate(-90)"}),(0,a.jsx)("circle",{className:(0,o.cn)(l().comet,l().cometThin,l().orbit3),cx:"0",cy:"0",r:"110",transform:"rotate(-90)"}),(0,a.jsx)("circle",{className:(0,o.cn)(l().comet,l().cometThin,l().orbitCounter),cx:"0",cy:"0",r:"100",transform:"rotate(-90)"}),(0,a.jsx)("polygon",{className:l().triTop,points:s,fill:`url(#${f})`}),(0,a.jsx)("polygon",{className:l().triBl,points:u,fill:`url(#${f})`}),(0,a.jsx)("polygon",{className:l().triBr,points:c,fill:`url(#${f})`})]}):(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("circle",{cx:"0",cy:"0",r:"148",fill:"none",stroke:"rgba(125,150,255,0.2)",strokeWidth:"1"}),(0,a.jsx)("circle",{className:l().ringOuter,cx:"0",cy:"0",r:"110",fill:"none",stroke:`url(#${f})`,strokeWidth:"5",strokeLinecap:"round"}),(0,a.jsx)("circle",{className:l().ringInner,cx:"0",cy:"0",r:"100",fill:"none",stroke:`url(#${f})`,strokeWidth:"2.5",strokeLinecap:"round",opacity:"0.7"}),(0,a.jsx)("polygon",{className:l().triOutlineTop,points:s,pathLength:100,fill:"none",stroke:"#FBBF24",strokeWidth:"2.5",strokeLinejoin:"round"}),(0,a.jsx)("polygon",{className:l().triOutlineBl,points:u,pathLength:100,fill:"none",stroke:"#FBBF24",strokeWidth:"2.5",strokeLinejoin:"round"}),(0,a.jsx)("polygon",{className:l().triOutlineBr,points:c,pathLength:100,fill:"none",stroke:"#FBBF24",strokeWidth:"2.5",strokeLinejoin:"round"}),(0,a.jsx)("polygon",{className:l().triFillTop,points:s,fill:`url(#${f})`}),(0,a.jsx)("polygon",{className:l().triFillBl,points:u,fill:`url(#${f})`}),(0,a.jsx)("polygon",{className:l().triFillBr,points:c,fill:`url(#${f})`}),(0,a.jsxs)("g",{className:l().cometGroup,children:[(0,a.jsx)("circle",{className:(0,o.cn)(l().comet,l().comet1),cx:"0",cy:"0",r:"110",transform:"rotate(-90)"}),(0,a.jsx)("circle",{className:(0,o.cn)(l().comet,l().cometThin,l().comet2),cx:"0",cy:"0",r:"100",transform:"rotate(-90)"})]})]})]}),g=(0,a.jsxs)("div",{className:(0,o.cn)("flex flex-col items-center justify-center gap-4 text-center",m),children:[(0,a.jsx)("div",{style:{width:t,height:t},children:y}),n?(0,a.jsx)("p",{className:"text-muted-foreground text-sm",children:n}):null]});return i?(0,a.jsx)("div",{className:"flex min-h-screen items-center justify-center bg-background",children:g}):g}},54501:(e,t,n)=>{"use strict";n.d(t,{Nj:()=>s,Nv:()=>c,ZG:()=>
1o,aS:()=>u,mn:()=>d});var a,r=n(2687),o=((a={}).WORK="work",a.PASSIVE="passive",a.SOCIAL="social",a.OTHER="other",a);let i={salary:"salaryIncome",business:"selfEmploymentIncome",bonus:"bonusIncome",insurance:"insuranceIncome",dividend:"dividendIncome",rent:"rentIncome",interest:"interestIncome",sales:"salesIncome",filial:"filialIncome",pension:"pensionIncome",alimony:"alimonyIncome",other_income:"otherIncome"},l={salary:"work",business:"work",bonus:"work",dividend:"passive",interest:"passive",rent:"passive",insurance:"other",sales:"other",filial:"other",pension:"other",alimony:"other",other_income:"other"},s={salaryIncome:!1,selfEmploymentIncome:!1,bonusIncome:!1,insuranceIncome:!0,dividendIncome:!1,rentIncome:!1,interestIncome:!1,salesIncome:!1,filialIncome:!0,pensionIncome:!0,alimonyIncome:!0,otherIncome:!1,laborInsurance:!0,laborPension:!0};function u(e){return i[e]||null}function c(e){return l[e]||"other"}function d(e){let t={salaryIncome:"salary",selfEmploymentIncome:"business",bonusIncome:"bonus",insuranceIncome:"insurance",dividendIncome:"dividend",rentIncome:"rent",interestIncome:"interest",salesIncome:"sales",filialIncome:"filial",pensionIncome:"pension",alimonyIncome:"alimony",otherIncome:"other_income",laborInsurance:"勞保",laborPension:"勞退"}[e];return"勞保"===t||"勞退"===t?t:r.Bi[t]||t||"未分類"}},58661:(e,t,n)=>{"use strict";n.d(t,{Eq:()=>d,OM:()=>s,Wq:()=>c,Xc:()=>u});var a=n(15418);let r=a.Ik({loanAmount:a.ai().positive("貸款金額必須大於 0"),annualRate:a.ai().min(0,"年利率不能為負數").max(100,"年利率不能超過 100%"),loanTerm:a.ai().int("貸款期限必須為整數").min(0,"貸款期限不能為負數").max(50,"貸款期限最多 50 年"),repaymentMethod:a.k5(["equal-payment","equal-principal"],{message:"還款方式必須為本息平均攤還或本金平均攤還"}),loanType:a.k5(["mortgage","car-loan","personal-loan"],{message:"貸款類型必須為房貸、車貸或信貸"}),startDate:a.Yj().optional()}),o=a.Ik({month:a.ai().int("提前還款月份必須為整數").min(1,"提前還款月份必須大於 0"),amount:a.ai().positive("提前還款金額必須大於 0")}),i=a.Ik({startMonth:a.ai().int("開始月份必須為整數").min(1,"開始月份必須大於 0"),rate:a.ai().min(0,"利率不能為負數").max(100,"利率不能超過 100%")}),l=a.Ik({periods:a.YO(i).min(1,"至少需要一個利率段").refine(e=>{let t=[...e].sort((e,t)=>e.startMonth-t.startMonth);for(let e=0;e<t.length-1;e++)if(t[e].startMonth===t[e+1].startMonth)return!1;return!0},{message:"利率段的開始月份不能重疊"})});function s(e){let t,{loanAmount:n,annualRate:a,loanTerm:o,repaymentMethod:i}=r.parse(e);if(0===o){let e=a/100/12,t=n*e,r=[],o=[],l=0;for(let a=1;a<=600;a++){let i=n*e;r.push({month:a,principal:0,interest:Math.round(100*i)/100,payment:Math.round(100*t)/100,remainingBalance:Math.round(100*n)/100}),l+=i,o.push({month:a,principalPaid:0,interestPaid:Math.round(100*l)/100,remainingBalance:Math.round(100*n)/100})}return{monthlyPayment:Math.round(100*t)/100,totalPayment:1/0,totalInterest:1/0,loanTerm:0,repaymentMethod:i,repaymentSchedule:r,monthlyData:o}}let l=12*o,s=a/100/12,u=[],c=0,d=0;if("equal-payment"===i){if(1e-4>Math.abs(s))t=n/l;else{let e=Math.pow(1+s,l);t=s*e*n/(e-1)}let e=n;for(let n=1;n<=l;n++){let a=e*s,r=t-a;e=Math.max(0,e-r),u.push({month:n,principal:Math.round(100*r)/100,interest:Math.round(100*a)/100,payment:Math.round(100*t)/100,remainingBalance:Math.round(100*e)/100}),c+=t,d+=a}}else{let e=n/l;t=e+n*s;let a=n;for(let t=1;t<=l;t++){let n=a*s,r=e+n;a=Math.max(0,a-e),u.push({month:t,principal:Math.round(100*e)/100,interest:Math.round(100*n)/100,payment:Math.round(100*r)/100,remainingBalance:Math.round(100*a)/100}),c+=r,d+=n}}let m=[],h=0,p=0;return u.forEach(e=>{h+=e.principal,p+=e.interest,m.push({month:e.month,principalPaid:Math.round(100*h)/100,interestPaid:Math.round(100*p)/100,remainingBalance:e.remainingBalance})}),{monthlyPayment:Math.round(100*t)/100,totalPayment:Math.round(100*c)/100,totalInterest:Math.round(100*d)/100,loanTerm:o,repaymentMethod:i,repaymentSchedule:u,monthlyData:m}}function u(e,t){let n=o.parse(t),a=s(e);if(n.month>a.repaymentSchedule.length)throw Error("提前還款月份不能超過貸款期限");let r=n.month-1,i=a.repaymentSchedule[r].remainingBalance;if(n.amount>i)throw Error("提前還款金額不能超過剩餘本金");let l=i-n.amount,u=a.repaymentSchedule.length-n.month;if(u<=0){let t=[],o=0,i=0;for(let e=0;e<r;e++){let n=a.repaymentSchedule[e];o+=n.principal,i+=n.interest,t.push(n)}o+=n.amount,t.push({month:n.month,principal:n.amount,interest:0,payment:n.amount,remainingBalance:0});let l=[],s=0,u=0;
1return t.forEach(e=>{s+=e.principal,u+=e.interest,l.push({month:e.month,principalPaid:Math.round(100*s)/100,interestPaid:Math.round(100*u)/100,remainingBalance:e.remainingBalance})}),{monthlyPayment:a.monthlyPayment,totalPayment:o+i,totalInterest:i,loanTerm:e.loanTerm,repaymentMethod:e.repaymentMethod,repaymentSchedule:t,monthlyData:l}}e.annualRate;let c=s({...e,loanAmount:l,loanTerm:Math.ceil(u/12)}),d=[],m=0,h=0;for(let e=0;e<r;e++){let t=a.repaymentSchedule[e];m+=t.principal,h+=t.interest,d.push(t)}let p=a.repaymentSchedule[r];m+=n.amount,h+=p.interest,d.push({month:n.month,principal:n.amount,interest:p.interest,payment:n.amount+p.interest,remainingBalance:l}),c.repaymentSchedule.forEach((e,t)=>{d.push({...e,month:n.month+t+1}),m+=e.principal,h+=e.interest});let f=[],y=0,g=0;return d.forEach(e=>{y+=e.principal,g+=e.interest,f.push({month:e.month,principalPaid:Math.round(100*y)/100,interestPaid:Math.round(100*g)/100,remainingBalance:e.remainingBalance})}),{monthlyPayment:a.monthlyPayment,totalPayment:m+h,totalInterest:h,loanTerm:e.loanTerm,repaymentMethod:e.repaymentMethod,repaymentSchedule:d,monthlyData:f}}function c(e,t){let n=l.parse(t),a=12*e.loanTerm,r=[...n.periods].sort((e,t)=>e.startMonth-t.startMonth);if(1!==r[0].startMonth)throw Error("第一個利率段必須從第 1 個月開始");for(let e of r)if(e.startMonth>a)throw Error(`利率段開始月份 ${e.startMonth} 不能超過貸款期限 ${a} 個月`);let o=[],i=0,s=0,u=e.loanAmount;for(let t=0;t<r.length;t++){let n=r[t],l=r[t+1],c=(l?l.startMonth-1:a)-n.startMonth+1;if(c<=0)throw Error(`利率段 ${t+1} 的月份範圍無效`);let d=a-n.startMonth+1,m=n.rate/100/12;if("equal-payment"===e.repaymentMethod){let e;if(1e-4>Math.abs(m))e=u/d;else{let t=Math.pow(1+m,d);e=m*t*u/(t-1)}for(let t=1;t<=c;t++){let a=n.startMonth+t-1,r=u*m,l=e-r;u=Math.max(0,u-l),o.push({month:a,principal:Math.round(100*l)/100,interest:Math.round(100*r)/100,payment:Math.round(100*e)/100,remainingBalance:Math.round(100*u)/100}),i+=e,s+=r}}else{let e=u/d;for(let t=1;t<=c;t++){let a=n.startMonth+t-1,r=u*m,l=e+r;u=Math.max(0,u-e),o.push({month:a,principal:Math.round(100*e)/100,interest:Math.round(100*r)/100,payment:Math.round(100*l)/100,remainingBalance:Math.round(100*u)/100}),i+=l,s+=r}}}let c=[],d=0,m=0;return o.forEach(e=>{d+=e.principal,m+=e.interest,c.push({month:e.month,principalPaid:Math.round(100*d)/100,interestPaid:Math.round(100*m)/100,remainingBalance:e.remainingBalance})}),{monthlyPayment:o[0]?.payment||0,totalPayment:Math.round(100*i)/100,totalInterest:Math.round(100*s)/100,loanTerm:e.loanTerm,repaymentMethod:e.repaymentMethod,repaymentSchedule:o,monthlyData:c}}function d(e){return{plans:e.map(e=>({name:e.name,result:s(e.input)}))}}a.Ik({month:a.ai().int("利率變動月份必須為整數").min(1,"利率變動月份必須大於 0"),newRate:a.ai().min(0,"新利率不能為負數").max(100,"新利率不能超過 100%")})},66140:(e,t,n)=>{"use strict";n.d(t,{h:()=>l,z:()=>i});var a=n(10412),r=n(88467);function o(e,t){return`${e}::${t}`}function i(e,t){let n=e.filter(e=>e.type===t&&!e.isEstimate),i=e.filter(e=>e.type===t&&!0===e.isEstimate),l=new Map;for(let e of n){if(!e.date||!e.accountId)continue;let n=(0,a.Yz)(e.date),r=Number(e.amount);if(!Number.isFinite(r)||r<=0)continue;let i=o(String(e.accountId),n),s=l.get(i);s?s.amount+=r:l.set(i,{amount:r,category:String(e.category||("income"===t?"other_income":"other")),currency:String(e.currency||"TWD"),month:n,accountId:String(e.accountId)})}let s=new Map;for(let e of i)e.date&&e.accountId&&s.set(o(String(e.accountId),(0,a.Yz)(e.date)),e);let u=[];for(let e of l.values()){let n=Math.round(100*e.amount)/100,a=s.get(o(e.accountId,e.month)),i=a?Number(a.amount):NaN;a?.id&&Number.isFinite(i)&&.005>Math.abs(i-n)||u.push({kind:"upsertEstimate",existingId:a?.id,type:t,accountId:e.accountId,category:e.category,amount:n,date:(0,r.Gz)(e.month),currency:e.currency})}return u}function l(e,t){let n=e.filter(e=>e.type===t&&!e.isEstimate),i=e.filter(e=>e.type===t&&!0===e.isEstimate),l=new Set;for(let e of n)e.date&&e.accountId&&l.add(o(String(e.accountId),(0,a.Yz)(e.date)));let s=[],u=new Set;for(let e of i){if(!e.date||!e.accountId)continue;let n=(0,a.Yz)(e.date),i=o(String(e.accountId),n);if(l.has(i)||u.has(i))continue;u.add(i);let c=Number(e.amount);Number.isFinite(c)&&!(c<=0)&&s.push({kind:"createDetailed",type:t,accountId:String(e.accountId),category:String(e.category||("income"===t?"other_income":"other")),amount:Math.round(100*c)/100,date:(0,r.Gz)(n),currency:String(e.currency||"TWD"),description:"由每月估計遷移"})}return s}},88467:(e,t,n)=>{"use strict";n.d(t,{$9:()=>u,Gz:()=>d,KP:()=>m,NJ:()=>c,gR:()=>s,lz:()=>l,s$:()=>i,sM:()=>o});var a=n(10412);function r(e){return!0===e.isEstimate}function o(e,t,n){let r=0;for(let o of e){if(o.type!==n||!o.date||(0,a.Yz)(o.date)!==t)continue;let e=Number(o.amount);Number.isFinite(e)&&e>0&&(r+=e)}return Math.round(100*r)/100}function i(e,t,n){let o=new Map;for(let i of e){if(i.type!==n||!i.date||(0,a.Yz)(i.date)!==t)continue;let e=Number(i.amount);if(!Number.isFinite(e)||e<=0)continue;let l=String(i.accountId??"")||"__none__",s=o.get(l)??{detailed:0,estimate:0};r(i)?s.estimate+=e:s.detailed+=e,o.set(l,s)}let i=0;for(let e of o.values())i+=e.detailed>0?e.detailed:e.estimate;return Math.round(100*i)/100}function l(e,t,n){let o=new Map;for(let i of e){if(i.type!==n||!i.date||(0,a.Yz)(i.date)!==t)continue;let e=Number(i.amount);if(!Number.isFinite(e)||e<=0)continue;let l=String(i.category??"other"),s=o.get(l)??{detailed:0,estimate:0};r(i)?s.estimate+=e:s.detailed+=e,o.set(l,s)}let i=new Map;for(let[e,t]of o)i.set(e,Math.round((t.detailed>0?t.detailed:t.estimate)*100)/100);return i}function s(e,t){return t.map(t=>({month:t,income:i(e,t,"income"),expense:i(e,t,"expense")}))}function u(e,t=new Date){let n=[],a=new Date(t.getFullYear(),t.getMonth(),1);for(let t=0;t<e;t++){let e=a.getFullYear(),t=String(a.getMonth()+1).padStart(2,"0");n.push(`${e}-${t}`),a.setMonth(a.getMonth()-1)}return n}function c(e=new Date){let t=e.getFullYear(),n=String(e.getMonth()+1).padStart(2,"0"),a=String(e.getDate()).padStart(2,"0");return`${t}-${n}-${a}`}function d(e){return`${e}-01`}function m(e,t){return"simple"===t?e.filter(e=>r(e)):e.filter(e=>!r(e))}}
1,89088:(e,t,n)=>{"use strict";n.d(t,{$_:()=>o,BS:()=>i});var a=n(67227);n(31615),n(73521);var r=n(28710);function o(e){return e?[r.U,e]:null}async function i(e){e&&await (0,a.j)(o(e))}},90481:(e,t,n)=>{"use strict";n.d(t,{v:()=>R,P:()=>G});var a=n(85047),r=n(31615),o=n(57376),i=n(19548),l=n(76458),s=n(24571),u=n(2134),c=n(21363),d=n(54501),m=n(47026),h=n(10055),p=n(43174);let f=["stocks","bonds","funds","real-estate","crypto","insurance","other-asset"],y="investment",g={stocks:"stocks",funds:"funds",bonds:"bonds",realestate:"real-estate",other:"other-asset"};function b(e){return(0,m.A7)(Number(e.value)||0,(0,m.WC)(e.currency||"twd"))}function M(e,t,n){Number.isFinite(n)&&!(n<=0)&&e.set(t,(e.get(t)||0)+n)}function _(e){let t=0;for(let n of e.values())t+=n;return t}var I=n(41482),v=n(96813);let x=["credit-card","credit_card_debt","personal-loan","personal_loan","student-loan","student_loan","margin-loan","bank-loan"],w=["cash","stocks","bonds","funds"],F={totalAssets:0,totalLiabilities:0,netWorth:0,monthlyIncome:0,monthlyExpenses:0,monthlyBalance:0,lastMonthBalance:0,monthlyChangePercent:0,expenseRatio:0,debtRatio:0,emergencyFundProgress:0,housingExpenseRatio:0,financialFreedomProgress:0,savingsRate:0,investmentRatio:0,debtToIncomeRatio:0,netWorthGrowthRate:0,averageMonthlyIncome:0,averageMonthlyExpenses:0,monthlyInterestExpense:0,monthlyMinimumDebtPayment:0,debtToIncomeEvaluable:!0,housingExpenses:0,totalCashFromAccounts:0,emergencyFundCoverageMonths:0,leverageRatio:0,liquidAssetsTotal:0,shortTermLiabilitiesTotal:0,currentRatio:0,investmentDiversification:0,excessCashRatio:0,emergencyFundTargetAmount:0};var L=n(94277),S=n(61325),P=n(13130),N=n(7786),T=n(15974),D=n(28710);async function B(e){if(!l.db)return{};try{let t=await (0,s.getDoc)((0,s.doc)(l.db,"users",e));if(!t.exists())return{};let n=t.data()?.onboarding;return(0,T.KM)(n?.dataTaskFlags)}catch{return{}}}async function E(e){if(!e)throw Error("請先登入");if(!l.db)throw Error("Firestore 尚未初始化");try{let t=(0,s.P)((0,s.rJ)(l.db,"accounts"),(0,s._M)("userId","==",e)),n=(await (0,s.GG)(t)).docs.map(e=>({id:e.id,...e.data()})),a=(0,s.P)((0,s.rJ)(l.db,"account_monthly_balances"),(0,s._M)("userId","==",e)),r=(await (0,s.GG)(a)).docs.map(e=>({id:e.id,...e.data()})),o=(0,s.P)((0,s.rJ)(l.db,"ledger_entries"),(0,s._M)("userId","==",e)),T=(await (0,s.GG)(o)).docs.map(e=>({id:e.id,...e.data()})),E=(0,s.P)((0,s.rJ)(l.db,"investments"),(0,s._M)("userId","==",e)),k=(await (0,s.GG)(E)).docs.map(e=>({id:e.id,...e.data()})),j=(0,s.P)((0,s.rJ)(l.db,"income_distribution_rules"),(0,s._M)("userId","==",e)),A=(await (0,s.GG)(j)).docs.map(e=>({id:e.id,...e.data()})),$=(0,s.P)((0,s.rJ)(l.db,"monthly_unallocated"),(0,s._M)("userId","==",e)),C=(await (0,s.GG)($)).docs.map(e=>({month:e.data().month,amount:Number(e.data().amount)||0})),R=(0,s.P)((0,s.rJ)(l.db,"transactions"),(0,s._M)("userId","==",e)),G=(await (0,s.GG)(R)).docs.map(e=>({id:e.id,...e.data()})),Y=(await (0,s.GG)((0,s.P)((0,s.rJ)(l.db,"assets"),(0,s._M)("userId","==",e)))).docs.map(e=>({id:e.id,...e.data()})),O=(await (0,s.GG)((0,s.P)((0,s.rJ)(l.db,"liabilities"),(0,s._M)("userId","==",e)))).docs.map(e=>({id:e.id,...e.data()})),W=[],z=[],U=[],J={...D.f};try{let[t,n,a,r,o,i]=await Promise.all([(0,s.GG)((0,s.P)((0,s.rJ)(l.db,"goals"),(0,s._M)("userId","==",e))),(0,s.GG)((0,s.P)((0,s.rJ)(l.db,"insurancePolicies"),(0,s._M)("userId","==",e))),(0,L.IG)(e),S.b.hasWill(e),P.m.hasAdvanceDirective(e),N.s.hasMandate(e)]);W=t.docs.map(e=>({id:e.id,...e.data()})),z=n.docs.map(e=>({id:e.id,...e.data()})),U=a,J={hasWill:r,hasAdvanceDirective:o,hasGuardianship:i}}catch(n){let t=n instanceof Error?n:Error(String(n));i.Cp(t,{level:"warning",extra:{message:"補抓資料缺漏判斷來源失敗",userId:e},tags:{source:"fetchFinancialDetails.fetchDataCompletenessSources"}})}let K=null,q=(0,s.doc)(l.db,"financial_indicators",`${e}_emergency_fund`);try{let t=await (0,s.getDoc)(q);if(t.exists()){let n=t.data();if(!n.userId)try{await (0,s.mZ)(q,{userId:e,updatedAt:s.Timestamp.now()})}catch(t){i.Cp(t instanceof Error?t:Error(String(t)),{level:"error",extra:{message:"更新緊急基金資料時發生錯誤",userId:e},tags:{source:"fetchFinancialDetails.emergencyFund.updateMissingUserId"}})}K={userId:n.userId||e,target:n.target||0,current:n.current||0,createdAt:n.createdAt||s.Timestamp.now(),updatedAt:n.updatedAt||s.Timestamp.now()}}else try{let t={userId:e,target:0,current:0,createdAt:s.Timestamp.now(),updatedAt:s.Timestamp.now()};await (0,s.setDoc)(q,t),K=t}catch{K={userId:e,target:0,current:0,createdAt:s.Timestamp.now(),updatedAt:s.Timestamp.now()}}}catch(t){i.Cp(t instanceof Error?t:Error(String(t)),{level:"error",extra:{message:"讀取緊急基金資料時發生錯誤",userId:e},tags:{source:"fetchFinancialDetails.emergencyFund.read"}}),K={userId:e,target:0,current:0,createdAt:s.Timestamp.now(),updatedAt:s.Timestamp.now()}}let V=null,H=await (0,s.GG)((0,s.P)((0,s.rJ)(l.db,"goals"),(0,s._M)("userId","==",e),(0,s._M)("type","==","financial_freedom")));H.empty||(V=H.docs[0].data().targetAmount);let X=await B(e),Z={transactions:G,assets:Y,liabilities:O,accounts:n,monthlyBalances:r,ledgerEntries:T,investments:k,goals:W,insurancePolicies:z,trusts:U,hasWill:J.hasWill,hasAdvanceDirective:J.hasAdvanceDirective,hasGuardianship:J.hasGuardianship,emergencyFund:K,financialFreedomGoalValue:V,allDistributionRules:A,monthlyUnallocatedList:C,taxDocuments:[],dataTask
1Flags:X},Q=Z.accounts?.length?function(e){let{transactions:t,assets:n,liabilities:a,accounts:r,investments:o,emergencyFund:i,ledgerEntries:l=[]}=e;if(!r||0===r.length)return{...F};let s=new Date,L=(0,u.Qv)(s),S=L.start,P=L.end,N=(0,u.$L)(t,S,P,e=>(0,u.OG)(e.date)),T=(0,I.Ps)({assets:n,liabilities:a,investments:o,ledgerEntries:l,convert:(e,t)=>(0,m.A7)(Number(e)||0,(0,m.WC)(String(t??"twd")))}),D=T.totalAssets,B=T.totalLiabilities,E=T.netWorth,k=T.totalCash,j=s.toISOString().slice(0,7),A=new Date(s.getFullYear(),s.getMonth()-1,1),$=`${A.getFullYear()}-${String(A.getMonth()+1).padStart(2,"0")}`,C=(0,v.s$)(l,j,"income"),R=(0,v.s$)(l,j,"expense"),G=(0,v.lz)(l,j,"expense").get("home")??0,Y=(0,v.$9)(12,s),O=(0,v.gR)(l,Y),W=Y.length>0?O.reduce((e,t)=>e+t.income,0)/Y.length:0,z=Y.length>0?O.reduce((e,t)=>e+t.expense,0)/Y.length:0,U=C-R,J=(0,v.s$)(l,$,"income")-(0,v.s$)(l,$,"expense"),K=0!==J?(U-J)/Math.abs(J)*100:100*(0!==U),q=0!==C?R/C*100:0,V=0!==D?B/D*100:0,H=6*R,X=0!==H?(n.find(e=>"emergency_fund"===e.type)?.value||0)/H*100:0,Z=0!==C?G/C*100:0,Q=N.filter(e=>"income"===e.type),ee=Q.filter(e=>(0,d.Nv)(e.category||"")===d.ZG.WORK).reduce((e,t)=>e+(t.amount||0),0),et=Q.filter(e=>(0,d.Nv)(e.category||"")!==d.ZG.WORK).reduce((e,t)=>e+(t.amount||0),0),en=0;ee>0?en=et/ee*100:et>0&&(en=100);let ea=function(e,t){let n=new Map;for(let t of f){let a=e.filter(e=>e.type===t).reduce((e,t)=>e+b(t),0);M(n,t,a)}let a=e.filter(e=>e.type===y).reduce((e,t)=>e+b(t),0);for(let e of(M(n,y,a),t||[])){let t=(0,p.GR)(e),a=null!=t?g[t]??"other-asset":"other-asset",r=(0,h.jU)({quantity:Number(e.quantity)||0,price:Number(e.price)||0});M(n,a,(0,m.A7)(r,(0,m.WC)(e.currency||"twd")))}return n}(n,o),er=_(ea),eo=0!==C?(C-R)/C*100:0,ei=0!==D?er/D*100:0,el=a.filter(e=>(Number(e.value)||0)>0).map(e=>(0,c.oL)(e)),es=(0,c.D0)({liabilities:el,monthlyBudget:0,strategy:{type:"proportional"}}),eu=es.monthlyDetails[0]?.totalInterest??0,ec=a.filter(e=>(Number(e.value)||0)>0),ed=0===ec.length||ec.every(e=>{let t=e.minimumPayment;return null!=t&&Number.isFinite(Number(t))}),em=ec.reduce((e,t)=>{let n=Number(t.minimumPayment);return e+(Number.isFinite(n)?n:0)},0),eh=ed&&0!==C?em/C*100:0,ep=D-B-U,ef=0!==ep?(E-ep)/Math.abs(ep)*100:0,ey=z>0?+(k/z).toFixed(1):0,eg=i?.target!=null&&i.target>0?i.target:6*z,eb=k+n.filter(e=>{let t=e.type;return w.includes(t)&&"cash"!==t}).reduce((e,t)=>e+(0,m.A7)(Number(t.value)||0,(0,m.WC)(t.currency||"twd")),0),eM=a.filter(e=>x.includes(String(e.type))).reduce((e,t)=>e+(0,m.A7)(Number(t.value)||0,(0,m.WC)(t.currency||"twd")),0),e_=E>0?B/E*100:0,eI=eM>0?eb/eM*100:0,ev=function(e){let t=_(e);if(t<=0)return 0;let n=0;for(let a of e.values()){let e=a/t;n+=e*e}return(1-n)*100}(ea),ex=eg>0?k/eg*100:0;return{totalAssets:+D.toFixed(2),totalLiabilities:+B.toFixed(2),netWorth:+E.toFixed(2),monthlyIncome:+C.toFixed(2),monthlyExpenses:+R.toFixed(2),monthlyBalance:+U.toFixed(2),lastMonthBalance:+J.toFixed(2),monthlyChangePercent:+K.toFixed(2),expenseRatio:+q.toFixed(2),debtRatio:+V.toFixed(2),emergencyFundProgress:+Math.min(100,Math.max(0,X)).toFixed(2),housingExpenseRatio:+Z.toFixed(2),financialFreedomProgress:+Math.min(100,Math.max(0,en)).toFixed(2),savingsRate:+Math.max(0,eo).toFixed(2),investmentRatio:+ei.toFixed(2),debtToIncomeRatio:+eh.toFixed(2),netWorthGrowthRate:+ef.toFixed(2),averageMonthlyIncome:"number"!=typeof W||Number.isNaN(W)?0:+W.toFixed(2),averageMonthlyExpenses:"number"!=typeof z||Number.isNaN(z)?0:+z.toFixed(2),monthlyInterestExpense:+eu.toFixed(2),monthlyMinimumDebtPayment:+em.toFixed(2),debtToIncomeEvaluable:ed,housingExpenses:+G.toFixed(2),totalCashFromAccounts:+k.toFixed(2),emergencyFundCoverageMonths:ey,emergencyFundTargetAmount:+eg.toFixed(2),leverageRatio:+e_.toFixed(2),liquidAssetsTotal:+eb.toFixed(2),shortTermLiabilitiesTotal:+eM.toFixed(2),currentRatio:+eI.toFixed(2),investmentDiversification:+Math.min(100,Math.max(0,ev)).toFixed(2),excessCashRatio:+ex.toFixed(2)}}({transactions:Z.transactions,assets:Z.assets,liabilities:Z.liabilities,accounts:Z.accounts,monthlyBalances:Z.monthlyBalances,ledgerEntries:Z.ledgerEntries??[],investments:Z.investments,emergencyFund:Z.emergencyFund,allDistributionRules:Z.allDistributionRules,monthlyUnallocatedList:Z.monthlyUnallocatedList}):{...F};return{rawData:Z,financialSummary:Q}}catch(n){let t=n instanceof Error?n:Error(String(n));if(i.Cp(t,{level:"error",extra:{message:"讀取財務資料失敗",userId:e},tags:{source:"fetchFinancialDetails"}}),n instanceof Error){if(n.message.includes("permission-denied"))throw Error("沒有權限讀取財務資料");if(n.message.includes("not-found"))throw Error("找不到財務資料");if(n.message.includes("unauthenticated"))throw Error("請先登入");throw Error(`讀取財務資料時發生錯誤:${n.message}`)}throw t}}var k=n(45713),j=n(89088);let A={transactions:[],assets:[],liabilities:[],accounts:[],monthlyBalances:[],ledgerEntries:[],investments:[],goals:[],insurancePolicies:[],trusts:[],hasWill:!1,hasAdvanceDirective:!1,hasGuardianship:!1,emergencyFund:null,financialFreedomGoalValue:null,allDistributionRules:[],monthlyUnallocatedList:[],taxDocuments:[],dataTask
1Flags:{}};var $=n(73521);let C=(0,r.createContext)(void 0);function R({children:e}){let{user:t,viewingUserId:n}=(0,$.A)(),i=n||t?.uid,{rawData:l,financialSummary:s,isLoading:u,isHydratedFromCache:c,isSummaryResolved:d,error:m,refetch:h}=(({currentUser:e})=>{let t=e?.uid??null,n=(0,r.useRef)(null),a=(0,r.useMemo)(()=>{if(t)return(0,k.WK)(t)},[t]),i=(0,j.$_)(t),{data:l,error:s,isLoading:u,isValidating:c,mutate:d}=(0,o.Ay)(i,async([,e])=>E(e),{revalidateOnFocus:!1,revalidateOnReconnect:!0,dedupingInterval:6e4,keepPreviousData:!0,fallbackData:a,onSuccess:e=>{t&&(0,k.ys)(t,e)}});(0,r.useEffect)(()=>{if(!t){n.current=null;return}!c&&l&&(n.current=t)},[t,c,l]);let m=!!(a||l),h=!!(t&&(c||u)&&n.current!==t),p=(0,r.useMemo)(()=>!!t&&(!!a?.rawData||!!(l?.rawData&&!c&&!u)),[t,a,l,c,u]),f=(0,r.useMemo)(()=>l?.rawData?l.rawData:a?.rawData?a.rawData:A,[l,a]),y=(0,r.useMemo)(()=>l?.financialSummary?l.financialSummary:a?.financialSummary?a.financialSummary:null,[l,a]),g=s instanceof Error?s:s?Error(String(s)):null,b=(0,r.useCallback)(async()=>{t&&await d()},[t,d]);return{financialSummary:y??{...F},rawData:f,isLoading:h,isHydratedFromCache:m,isSummaryResolved:p,error:g,refetch:b,mutate:d}})({currentUser:(0,r.useMemo)(()=>i?{uid:i}:null,[i])}),p=(0,r.useMemo)(()=>({rawData:l,financialSummary:s,isLoading:u,isHydratedFromCache:c,isSummaryResolved:d,error:m,refetch:h}),[l,s,u,c,d,m,h]);return(0,a.jsx)(C.Provider,{value:p,children:e})}function G(){let e=(0,r.useContext)(C);if(void 0===e)throw Error("useFinancialData must be used within a FinancialDataProvider");return e}},96813:(e,t,n)=>{"use strict";n.d(t,{kf:()=>s,KP:()=>u.KP,Gz:()=>u.Gz,gR:()=>u.gR,$9:()=>u.$9,lz:()=>u.lz,sM:()=>u.sM,s$:()=>u.s$,NJ:()=>u.NJ});var a=n(24571),r=n(76458),o=n(10412),i=n(27703);function l(e){let t={};for(let[n,a]of Object.entries(e))void 0!==a&&(t[n]=a);return t}function s(){return{async list(e,t){try{if(!r.db)throw Error("Firestore 尚未初始化");if(!e)throw Error("用戶 ID 未提供");let n=[(0,a._M)("userId","==",e),(0,a.My)("date","desc")];t?.type&&n.splice(1,0,(0,a._M)("type","==",t.type)),t?.limit&&n.push((0,a.AB)(t.limit));let o=(await (0,a.GG)((0,a.P)((0,a.rJ)(r.db,i.l7),...n))).docs.map(e=>{var t,n;return t=String(e.id),n=e.data(),{id:t,userId:String(n.userId??""),type:n.type,amount:Number(n.amount)||0,currency:String(n.currency??"TWD"),accountId:String(n.accountId??""),category:String(n.category??""),date:String(n.date??""),description:null!=n.description?String(n.description):void 0,source:n.source??"manual",isEstimate:!0===n.isEstimate||void 0,documentId:null!=n.documentId?String(n.documentId):void 0,meta:n.meta,createdAt:n.createdAt,updatedAt:n.updatedAt}});return{ok:!0,data:o}}catch(e){return{ok:!1,error:e instanceof Error?e.message:"list_ledger_failed"}}},async add(e,t){try{if(!r.db)throw Error("Firestore 尚未初始化");if(!e)throw Error("用戶 ID 未提供");let n=o.Nb.parse(t),s=a.Timestamp.now(),u=l({userId:e,type:n.type,amount:n.amount,currency:n.currency??"TWD",accountId:n.accountId,category:n.category,date:n.date,description:n.description,source:n.source??"manual",isEstimate:n.isEstimate,documentId:n.documentId,meta:n.meta,createdAt:s,updatedAt:s}),c=await (0,a.gS)((0,a.rJ)(r.db,i.l7),u);return{ok:!0,data:c.id}}catch(e){return{ok:!1,error:e instanceof Error?e.message:"add_ledger_failed"}}},async update(e,t,n){try{if(!r.db)throw Error("Firestore 尚未初始化");if(!e||!t)throw Error("參數不足");let o=l({...n,updatedAt:a.Timestamp.now()});if("amount"in o&&("number"!=typeof o.amount||o.amount<=0))throw Error("金額必須大於 0");return await (0,a.mZ)((0,a.doc)(r.db,i.l7,t),o),{ok:!0}}catch(e){return{ok:!1,error:e instanceof Error?e.message:"update_ledger_failed"}}},async remove(e){try{if(!r.db)throw Error("Firestore 尚未初始化");if(!e)throw Error("id 未提供");return await (0,a.kd)((0,a.doc)(r.db,i.l7,e)),{ok:!0}}catch(e){return{ok:!1,error:e instanceof Error?e.message:"remove_ledger_failed"}}}}}var u=n(88467);n(66140)}}]);

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.