const sn={PING:"ping",GET_RUNTIME_STATE:"get_runtime_state",GET_JOBS:"get_jobs",GET_CANDIDATE_PROFILE:"get_candidate_profile",GET_AI_SETTINGS:"get_ai_settings",SAVE_CANDIDATE_PROFILE:"save_candidate_profile",SAVE_AI_SETTINGS:"save_ai_settings",TEST_AI_CONNECTION:"test_ai_connection",REFRESH_OFFICIAL_WALLET:"refresh_official_wallet",ENSURE_OFFICIAL_TRIAL:"ensure_official_trial",ENHANCE_CANDIDATE_PROFILE:"enhance_candidate_profile",ENHANCE_PROFILE_MODULE:"enhance_profile_module",ANALYZE_JOB:"analyze_job",ANALYZE_JOBS:"analyze_jobs",ANALYZE_UNANALYZED_JOBS:"analyze_unanalyzed_jobs",SAVE_JOB_ANALYSIS:"save_job_analysis",GENERATE_RESUME_DRAFT:"generate_resume_draft",CLEAR_JOB_ANALYSES:"clear_job_analyses",CLEAR_ALL_DATA:"clear_all_data",RAW_CAPTURE_OBSERVED:"raw_capture_observed"},_e=new Set(["cookie","cookies","authorization","token","requestHeaders","responseBody","description","jd"]);function Pe(e){if(e)return Object.fromEntries(Object.entries(e).map(([t,n])=>_e.has(t)?[t,"[redacted]"]:[t,n]))}function $(e,t){const n={...t,meta:Pe(t.meta)},r=`[job-collector][${n.module}][${n.action}]`;(e==="debug"?console.debug:console[e])(r,n.message,n.meta??{})}function $e(){return{debug:e=>$("debug",e),info:e=>$("info",e),warn:e=>$("warn",e),error:e=>$("error",e)}}const Ce={VITE_OFFICIAL_BILLING_ORIGIN:"https://billing.gobicowboy.cn",VITE_OFFICIAL_MODEL_BASE_URL:"https://model-api.gobicowboy.cn/v1"},le=Ce,pe=Oe(le.VITE_OFFICIAL_MODEL_BASE_URL,"https://model.example.invalid/v1"),Te=new URL(pe).origin,cn=je(le.VITE_OFFICIAL_BILLING_ORIGIN,"https://billing.example.invalid");function Oe(e,t){return(e?.trim()||t).replace(/\/$/,"")}function je(e,t){const n=e?.trim()||t;return new URL(n).origin}var Re={providerId:"official",providerLabel:"求职助手",baseUrl:"https://model-api.gobicowboy.cn/v1",apiKey:"",model:"",activeMode:"official",customProfile:{providerId:"deepseek",providerLabel:"DeepSeek",baseUrl:"https://api.deepseek.com/v1",apiKey:"",model:"deepseek-v4-flash",connectionStatus:"untested"}};const ln=Re,Le={providerId:"official",providerLabel:"求职助手",baseUrl:pe,apiKey:"",model:"",connectionStatus:"untested"},De={providerId:"deepseek",providerLabel:"DeepSeek",baseUrl:"https://api.deepseek.com/v1",apiKey:"",model:"deepseek-v4-flash",connectionStatus:"untested"};function E(e){return e.providerId==="official"||e.baseUrl.startsWith(Te)}function D(e){return!!(e.providerId&&e.baseUrl&&e.apiKey&&(E(e)||e.model))}function Ne(e){return N(e).activeMode??"official"}function pn(e,t=Ne(e)){return t==="official"?"求职助手官方服务":`自定义模型-${J(e,"custom").providerLabel||"未命名模型"}`}function N(e){const t=e.activeMode??(E(e)?"official":"custom"),n=K(e),r={...Le,...e.officialProfile,...t==="official"?n:{}},i={...De,...e.customProfile,...t==="custom"?n:{}};return{...e,...t==="official"?r:i,activeMode:t,officialProfile:r,customProfile:i}}function J(e,t){const n=N(e);return t==="official"?n.officialProfile:n.customProfile}function un(e,t,n){const r=N(e),i={...J(r,t),...n},o=t==="official"?{...r,officialProfile:i}:{...r,customProfile:i};return r.activeMode===t?{...o,...K(i)}:o}function dn(e,t){const n=N(e),r=J(n,t);return{...n,...K(r),activeMode:t}}function K(e){return{providerId:e.providerId,providerLabel:e.providerLabel,baseUrl:e.baseUrl,apiKey:e.apiKey,model:e.model,connectionStatus:e.connectionStatus,lastTestedAt:e.lastTestedAt,lastTestError:e.lastTestError}}const ze=[{id:"personal",label:"个人资料",helper:"结构化填写",aiPolishable:!1},{id:"work",label:"工作经历",helper:"可用 AI 润色",aiPolishable:!0},{id:"projects",label:"项目经历",helper:"可用 AI 润色",aiPolishable:!0},{id:"education",label:"教育经历",helper:"可用 AI 润色",aiPolishable:!0},{id:"skills",label:"技能优势",helper:"可用 AI 润色",aiPolishable:!0},{id:"summary",label:"个人摘要",helper:"可用 AI 润色",aiPolishable:!0}],Fe=`

---

`;function mn(e){return(e??[]).filter(t=>t.trim()).join(Fe)}function hn(e){return e.trim()?e.split(/\n\s*---\s*\n/u).filter(t=>t.trim()):[]}const ue={personal:["name","profilePhotoDataUrl","age","phone","email","currentCity","targetRoles","targetCities","remotePreference","salaryExpectation"],work:["workExperiences"],projects:["projectExperiences"],education:["educationExperiences"],skills:["skills","strengths","avoidKeywords"],summary:["resumeSummary"]};function Ue(e){return ze.map(t=>Be(e,t.id))}function fn(e){const t=Ue(e),n=t.filter(r=>r.status==="completed").length;return{completed:n,total:t.length,percentage:Math.round(n/t.length*100)}}function de(e,t){const n={};for(const r of ue[t])ve(n,r,e[r]);return n}function Be(e,t){const n=Ge(e,t),r=n.filter(Boolean).length,i=ue[t].some(o=>x(e[o],o==="remotePreference"));return{id:t,status:i?r===n.length?"completed":"in_progress":"pending",completedFields:r,requiredFields:n.length}}function Ge(e,t){switch(t){case"personal":return[x(e.name),x(e.phone)||x(e.email),x(e.currentCity),x(e.targetRoles)];case"work":return[x(e.workExperiences)];case"projects":return[x(e.projectExperiences)];case"education":return[x(e.educationExperiences)];case"skills":return[x(e.skills),x(e.strengths)];case"summary":return[x(e.resumeSummary)]}}function x(e,t=!1){return t?!1:Array.isArray(e)?e.some(n=>typeof n=="string"&&n.trim().length>0):typeof e=="string"&&e.trim().length>0}function ve(e,t,n){Object.assign(e,{[t]:n})}const me="2026.07.30.2",Je=8192,Ke={personal:'{"name":"","profilePhotoDataUrl":"","age":"","phone":"","email":"","currentCity":"","targetRoles":[],"targetCities":[],"remotePreference":"any","salaryExpectation":""}',work:'{"workExperiences":["完整工作经历文本"]}',projects:'{"projectExperiences":["完整项目经历文本"]}',education:'{"educationExperiences":["学校｜专业｜时间\\n学历及其他事实"]}',skills:'{"skills":[],"strengths":[],"avoidKeywords":[]}',summary:'{"resumeSummary":""}'},Ve={personal:"只提取明确出现的个人信息和求职偏好，不猜测缺失内容。",work:["不要判断或拆分公司数量、任职阶段，也不要强制补齐公司、职位或时间字段。","所有工作经历内容合并为 workExperiences 中唯一的一个字符串；数组长度必须为 1，禁止返回对象或 content 等嵌套字段。","在这个完整字符串内整理段落和换行，使职责、关键行动和成果清晰可读。","必须在不增加事实的前提下进行可感知改写：删除口语和重复表达，使用准确动词，突出职责范围、协作对象、交付物和已有数字。","原文没有明确写出的“上线、成功、提升效率、主导、全权负责”等结果或责任程度一律不得补充。"].join(`
`),projects:["不要判断或拆分项目数量，也不要强制补齐项目名称、时间或担任角色。","所有项目内容合并为 projectExperiences 中唯一的一个字符串；数组长度必须为 1，禁止返回对象或 content 等嵌套字段。","在这个完整字符串内整理段落和换行，使背景、职责、关键行动和成果清晰可读。","“能力关键词”“技术方法”“技术栈”“作品集地址”等信息按原文语义保留，不要猜测它属于哪个项目。","必须在不增加事实的前提下进行可感知改写：删除口语和重复表达，使用准确动词，突出本人贡献、交付物和已有数字。","原文没有明确写出的“上线、成功、提升效率、主导、全权负责”等结果或责任程度一律不得补充。"].join(`
`),education:"识别所有学校或教育阶段，每段教育经历必须成为 educationExperiences 的一个独立数组元素，不得合并。",skills:"技能、优势和避雷关键词分别归入对应数组；去重并统一名称，不得新增用户未提供的能力。",summary:"重写为 3—5 句可直接放入简历的职业摘要，突出定位、核心能力和真实成果，不得照抄原文。"};function qe(e){const t=k(e,"request"),n=k(t.job,"job"),r=he(k(t.profile,"profile"));return V(n.id,"job_id"),{temperature:.2,enableThinking:!1,system:["你是一个职位分析助手。","根据用户画像和一个职位，输出严格可解析的 JSON 对象。","不得编造用户经历；信息不足时降低 confidence 并说明风险。","scoreOverall 为 0 到 5；recommendation 只能是 apply、consider、skip。","salaryFit 只能是 low、ok、good、unknown。","locationFit 只能是 match、acceptable、mismatch、unknown。","confidence 只能是 low、medium、high。","数组字段必须是字符串数组，只返回 JSON，不要 Markdown 或解释。"].join(`
`),user:["分析这个职位是否值得用户投递，并给出差距和下一步行动。",`用户画像: ${JSON.stringify(r)}`,`职位数据: ${JSON.stringify(n)}`,'必须返回：{"scoreOverall":4.2,"recommendation":"apply","roleType":"","matchedSkills":[],"missingSkills":[],"hardStops":[],"softGaps":[],"strengths":[],"risks":[],"salaryFit":"unknown","locationFit":"unknown","summary":"","nextAction":"","confidence":"medium"}'].join(`

`)}}function He(e){const t=k(e,"request"),n=k(t.bucket,"bucket"),r=he(k(t.profile,"profile")),i=k(t.template,"template");if(!Array.isArray(t.jobs)||t.jobs.length===0)throw new Error("JOBS_REQUIRED");return V(n.id,"bucket_id"),{temperature:.45,enableThinking:!0,thinkingBudget:Je,system:["你是资深中文简历策略顾问和写作者。","根据用户真实画像、目标职位簇和模板规划，生成一份中文一页简历草稿。","以目标岗位语言重排真实经历，允许职能转译，但禁止编造公司、学校、时间、业绩、职责或证书。","每条经历使用动作、场景、方法和结果组织；没有数字时不得捏造数字。","只返回 JSON，不要 Markdown 或解释。","优先返回 sections；sections[].kind 只能是 paragraph、list、experience、tags。","paragraph 使用 content；list 使用 bullets；experience 使用 items；tags 使用 tags。","栏目、顺序和篇幅必须遵守传入的模板规划。"].join(`
`),user:["生成一份包装到位但事实诚实的简历草稿。",`用户画像: ${JSON.stringify(r)}`,`简历策略: ${JSON.stringify(n)}`,`目标职位: ${JSON.stringify(t.jobs)}`,`模板规划: ${JSON.stringify(i)}`,"返回对象至少包含 title、sections、summary、skillGroups、workExperiences、projectExperiences、educationExperiences、keywords。"].join(`

`)}}function We(e){const t=k(e,"request"),n=V(t.text,"text"),r=Qe(t.moduleId),i=r?Ke[r]:void 0;return{temperature:.2,enableThinking:!1,system:["你是求职画像结构化与简历润色助手。","把用户提供的事实整理为严格 JSON，禁止编造经历。","不确定的信息使用空字符串或空数组。","remotePreference 只能是 remote、hybrid、onsite、any。",r?`本次只处理 ${r} 模块，只能返回指定字段，不得把内容放进其他画像字段。`:"本次处理完整画像。",r?Ve[r]:"",r?"只要用户输入非空，指定模块的结果也必须非空；无法进一步润色时原样保留事实，不得返回空数组或空字符串。":"无法确认的信息可以留空，但不得丢弃用户明确提供的事实。","只返回 JSON，不要 Markdown 或解释。"].join(`
`),user:[r?`润色并结构化画像模块 ${r}。`:"整理下面的用户描述。",n,i?`严格按这个 JSON 结构返回：${i}`:"返回字段：name,profilePhotoDataUrl,age,phone,email,currentCity,targetRoles,targetCities,remotePreference,salaryExpectation,skills,strengths,workExperiences,projectExperiences,educationExperiences,avoidKeywords,resumeSummary。"].join(`

`)}}function Ye(e){return{...e,temperature:.35,system:[e.system,"上一轮没有生成可用改写。本轮必须重新理解输入，并返回非空且经过实质改写的目标模块。"].join(`
`),user:[e.user,"重新输出。禁止返回空数组；禁止原样复制整段输入。工作或项目模块必须把全部内容放在数组中唯一的一个字符串内；教育模块仍可按学校或阶段拆分。"].join(`

`)}}function Qe(e){if(!(e===void 0||e==="")){if(e==="personal"||e==="work"||e==="projects"||e==="education"||e==="skills"||e==="summary")return e;throw new Error("MODULE_ID_INVALID")}}function k(e,t){if(!e||typeof e!="object"||Array.isArray(e))throw new Error(`${t.toUpperCase()}_REQUIRED`);return e}function V(e,t){if(typeof e!="string"||!e.trim())throw new Error(`${t.toUpperCase()}_REQUIRED`);return e.trim()}function he(e){const{profilePhotoDataUrl:t,...n}=e;return n}async function Ze(e){const t=await fetch(`${e.baseUrl.replace(/\/$/,"")}/wallet`,{headers:{Authorization:`Bearer ${e.apiKey}`},cache:"no-store"}),n=await t.json().catch(()=>({}));if(!t.ok)throw fe(t.status,n.error);const r=n.wallet?.balance??n.balances?.find(i=>i.resource==="job.assistant.credit")?.balance;return{accountId:n.wallet?.accountId,keyPrefix:n.wallet?.keyPrefix,remainingCredits:r,updatedAt:new Date().toISOString()}}async function q(e,t,n,r={}){const i=r.timeoutMs??9e4,o=r.requestId??crypto.randomUUID(),c=`${e.baseUrl.replace(/\/$/,"")}/${t}`,s=Date.now()+i,p=new AbortController,l=setTimeout(()=>p.abort(),i);try{for(;;){const a=await fetch(c,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`,"X-Request-Id":o},body:JSON.stringify(n),signal:p.signal}),u=await a.json().catch(()=>({})),f=et(a.headers.get("X-Credits-Remaining"))??u.wallet?.balance??u.usage?.remaining??u.balance;if(f!==void 0&&await tt(r.onWalletUpdate,{accountId:u.wallet?.accountId,keyPrefix:u.wallet?.keyPrefix,remainingCredits:f,updatedAt:new Date().toISOString()}),a.status===409&&u.error==="REQUEST_IN_PROGRESS"&&Date.now()+750<s){await Xe(750,p.signal);continue}if(!a.ok)throw fe(a.status,u.error);if(!u.result)throw new Error("官方服务没有返回业务结果。");return u.result}}catch(a){throw a instanceof Error&&(a.name==="AbortError"||/aborted/i.test(a.message))?new Error(`请求超时（${Math.round(i/1e3)} 秒）。请稍后重试。`):a}finally{clearTimeout(l)}}function Xe(e,t){return new Promise((n,r)=>{const i=setTimeout(n,e);t.addEventListener("abort",()=>{clearTimeout(i),r(new DOMException("Aborted","AbortError"))},{once:!0})})}function fe(e,t){return e===402||t==="INSUFFICIENT_CREDITS"?new Error("求职助手次数已用完，请先购买次数后再试。"):e===401?new Error("求职助手凭证无效或尚未激活，请检查凭证或支付状态。"):e===409||t==="REQUEST_IN_PROGRESS"?new Error("同一请求仍在处理中，请稍后重试。"):new Error(t||`官方服务请求失败（${e}）`)}function et(e){if(e===null||e.trim()==="")return;const t=Number(e);return Number.isFinite(t)&&t>=0?t:void 0}async function tt(e,t){if(e)try{await e(t)}catch{}}const B=$e(),nt="default-profile",G=me,T=18e4,rt=12e3;async function it(e,t){const n=JSON.stringify({capability:"job-analysis",jobId:e.id,jobUpdatedAt:e.lastUpdatedAt,profileId:t.id,profileUpdatedAt:t.updatedAt,promptVersion:G}),r=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(n));return`job-analysis-${Array.from(new Uint8Array(r),o=>o.toString(16).padStart(2,"0")).join("")}`}async function H(e,t,n){const r=new AbortController,i=`${e.baseUrl.replace(/\/$/,"")}/chat/completions`,o=new Error(`请求超时（${Math.round(n/1e3)} 秒）。请检查 Base URL、网络或 API 是否可用。`),c=setTimeout(()=>r.abort(),n),s={"Content-Type":"application/json"};e.apiKey&&(s.Authorization=`Bearer ${e.apiKey}`);const p=fetch(i,{method:"POST",headers:s,body:JSON.stringify(t),signal:r.signal}),l=new Promise((a,u)=>{setTimeout(()=>u(o),n+50)});try{return await Promise.race([p,l])}catch(a){throw a===o||a instanceof Error&&(a.name==="AbortError"||/aborted/i.test(a.message))?o:a instanceof TypeError?new Error(`无法连接 API（${i}）。请检查 Base URL 是否正确，以及扩展 host_permissions 是否包含该域名。`):a}finally{clearTimeout(c)}}async function gn(e){if(!D(e))throw new Error("请先填写供应商、Base URL、模型名称和 API Key。");if(E(e)){const r=await Ze(e);return B.info({module:"analysis",action:"ai_connection_tested",message:"Tested managed AI service connection.",meta:{provider:"official",model:"managed"}}),r}const t=await H(e,{model:e.model,temperature:0,max_tokens:32,...Y(e),messages:[{role:"user",content:"请只回复 OK。"}]},rt);if(!t.ok){const r=(await t.text()).slice(0,240);throw new Error(`连接失败（${t.status}）${r?`：${r}`:""}`)}if(!(await t.json()).choices?.[0]?.message)throw new Error("连接成功，但接口没有返回有效的模型消息。");B.info({module:"analysis",action:"ai_connection_tested",message:"Tested AI provider connection.",meta:{provider:e.providerId,model:e.model}})}async function xn(e,t,n,r){if(!D(n))throw new Error("请先在 API 设置中配置供应商、Base URL、模型名称和 API Key。");let i;if(E(n)){const c=await it(e,t);i=await q(n,"job-analysis",{job:e,profile:t},{timeoutMs:T,requestId:c,onWalletUpdate:r})}else{const c=qe({job:e,profile:t}),s=await H(n,{model:n.model,temperature:c.temperature,...Y(n),response_format:{type:"json_object"},messages:[{role:"system",content:c.system},{role:"user",content:c.user}]},T);if(!s.ok){const a=(await s.text()).slice(0,240);throw new Error(`AI 请求失败（${s.status}）${a?`：${a}`:""}`)}const l=(await s.json()).choices?.[0]?.message?.content;if(!l)throw new Error("AI provider returned an empty completion.");i=W(l)}const o=ct(i);return B.info({module:"analysis",action:"job_analyzed",message:"Analyzed one job with AI provider.",meta:{provider:n.providerId,model:E(n)?"managed":n.model,jobId:e.id}}),{id:at(e.id,t.id,G),jobId:e.id,profileId:t.id,provider:n.providerId,model:E(n)?"managed":n.model,promptVersion:G,analyzedAt:new Date().toISOString(),...o}}async function ot(e,t,n,r){if(!D(t))throw new Error("请先在 API 设置中配置供应商、Base URL、模型名称和 API Key。");if(E(t)){const c=await q(t,"profile-enhancement",{text:e,...n?{moduleId:n}:{}},{timeoutMs:T,onWalletUpdate:r});return te(c)}const i=async(c=!1)=>{const s=We({text:e,...n?{moduleId:n}:{}}),p=c?Ye(s):s,l=await H(t,{model:t.model,temperature:p.temperature,...Y(t),response_format:{type:"json_object"},messages:[{role:"system",content:p.system},{role:"user",content:p.user}]},T);if(!l.ok){const b=(await l.text()).slice(0,240);throw new Error(`AI 请求失败（${l.status}）${b?`：${b}`:""}`)}const u=(await l.json()).choices?.[0]?.message?.content;if(!u)throw new Error("AI provider returned an empty completion.");return te(W(u))};let o=await i();return n&&!st(o,n)&&(o=await i(!0)),o}async function bn(e,t,n,r){const i=await ot(t,n,e,r);return de(i,e)}function yn(e,t,n){const r=new Map(t.map(l=>[l.id,l])),i=new Map,o=new Map;for(const l of e){const a=r.get(l.jobId);for(const u of g(a?.skills??[]))i.set(u,(i.get(u)??0)+1);for(const u of g(l.missingSkills))o.set(u,(o.get(u)??0)+1)}const c=Math.max(e.length,1),s=ee(i,c),p=ee(o,c);return{id:`${n}:${new Date().toISOString()}`,profileId:n,jobCount:e.length,generatedAt:new Date().toISOString(),topRequiredSkills:s,topMissingSkills:p,recommendedFocus:p.slice(0,5).map(l=>l.skill)}}function wn(){const e=new Date().toISOString();return{id:nt,age:"",phone:"",email:"",currentCity:"",targetRoles:[],targetCities:[],remotePreference:"any",skills:[],strengths:[],workExperiences:[],projectExperiences:[],educationExperiences:[],avoidKeywords:[],resumeSummary:"",createdAt:e,updatedAt:e}}function at(e,t,n){return`${e}:${t}:${n}`}function W(e){const t=e.match(/```(?:json)?\s*([\s\S]*?)```/i),n=t?t[1]:e,r=n.indexOf("{"),i=n.lastIndexOf("}");if(r===-1||i===-1||i<=r)throw new Error("AI response did not contain a JSON object.");return JSON.parse(n.slice(r,i+1))}function Y(e){return e.providerId==="deepseek"||e.baseUrl.includes("api.deepseek.com")?{thinking:{type:"disabled"}}:e.providerId==="bailian"||e.baseUrl.includes("dashscope.aliyuncs.com")?{enable_thinking:!1}:{}}function st(e,t){const n=de(e,t);return Object.values(n).some(r=>Array.isArray(r)?r.some(i=>typeof i=="string"&&i.trim()):typeof r=="string"&&r.trim())}function ct(e){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("AI JSON payload is not a valid object.");const t=e;return{scoreOverall:lt(t.scoreOverall),recommendation:pt(t.recommendation),roleType:C(t.roleType,"未分类职位"),matchedSkills:g(t.matchedSkills),missingSkills:g(t.missingSkills),hardStops:g(t.hardStops),softGaps:g(t.softGaps),strengths:g(t.strengths),risks:g(t.risks),salaryFit:ut(t.salaryFit),locationFit:dt(t.locationFit),summary:C(t.summary,"模型没有返回分析摘要。"),nextAction:C(t.nextAction,"先补全职位详情，再重新分析。"),confidence:mt(t.confidence)}}function lt(e){const t=typeof e=="number"?e:Number(e);return Number.isFinite(t)?Math.max(0,Math.min(5,Math.round(t*10)/10)):0}function pt(e){return e==="apply"||e==="consider"||e==="skip"?e:"consider"}function ut(e){return e==="low"||e==="ok"||e==="good"||e==="unknown"?e:"unknown"}function dt(e){return e==="match"||e==="acceptable"||e==="mismatch"||e==="unknown"?e:"unknown"}function mt(e){return e==="low"||e==="medium"||e==="high"?e:"medium"}function C(e,t){return typeof e=="string"&&e.trim()?e.trim():t}function A(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function g(e){if(!Array.isArray(e))return[];const t=new Set;return e.map(n=>typeof n=="string"?n.trim():"").filter(n=>{if(!n)return!1;const r=n.toLowerCase();return t.has(r)?!1:(t.add(r),!0)})}function ee(e,t){return[...e.entries()].sort((n,r)=>r[1]-n[1]||n[0].localeCompare(r[0])).slice(0,8).map(([n,r])=>({skill:n,count:r,percentage:Math.round(r/t*1e3)/10}))}function te(e){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("AI JSON payload is not a valid profile object.");const t=e;return{name:A(t.name),profilePhotoDataUrl:A(t.profilePhotoDataUrl),age:A(t.age),phone:A(t.phone),email:A(t.email),currentCity:A(t.currentCity),targetRoles:g(t.targetRoles),targetCities:g(t.targetCities),remotePreference:ht(t.remotePreference),salaryExpectation:A(t.salaryExpectation),skills:g(t.skills),strengths:g(t.strengths),workExperiences:z(t.workExperiences,!0),projectExperiences:z(t.projectExperiences,!0),educationExperiences:z(t.educationExperiences,!1),avoidKeywords:g(t.avoidKeywords),resumeSummary:C(t.resumeSummary,"")}}function z(e,t){if(!Array.isArray(e))return[];const n=e.flatMap(r=>{if(typeof r=="string"&&r.trim())return[r.trim()];if(r&&typeof r=="object"&&!Array.isArray(r)&&typeof r.content=="string"){const i=r.content.trim();return i?[i]:[]}return[]});return!t||n.length===0?n:[n.join(`

`)]}function ht(e){return e==="remote"||e==="hybrid"||e==="onsite"||e==="any"?e:"any"}class ne extends Error{constructor(t,n){super(gt(t)),this.code=t,this.permanent=n,this.name="OfficialTrialClaimError"}code;permanent}function En(e=navigator,t=screen,n=Intl.DateTimeFormat().resolvedOptions().timeZone){const r=[t.width,t.height].map(i=>Math.max(0,Math.round(i))).sort((i,o)=>i-o);return{schemaVersion:1,platform:(e.userAgentData?.platform||e.platform||"unknown").slice(0,64),browserMajor:ft(e.userAgent),language:(e.language||"unknown").slice(0,32),timeZone:(n||"unknown").slice(0,64),screen:`${r[0]}x${r[1]}x${Math.max(0,Math.round(t.colorDepth))}`,hardwareConcurrency:F(e.hardwareConcurrency,1024),deviceMemory:F(e.deviceMemory,1024),maxTouchPoints:F(e.maxTouchPoints,100)}}async function kn(e,t,n){const r=await fetch(`${e.replace(/\/$/,"")}/job-assistant/trial`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({installId:t,device:n}),cache:"no-store"}),i=await r.json().catch(()=>({}));if(!r.ok){const o=i.error||`TRIAL_HTTP_${r.status}`;throw new ne(o,o==="TRIAL_DEVICE_LIMIT_REACHED")}if(!i.apiKey||!i.wallet?.accountId||!i.wallet.keyPrefix)throw new ne("INVALID_TRIAL_RESPONSE",!1);return i}function ft(e){return e.match(/(?:Edg|Chrome|CriOS)\/(\d+)/)?.[1]||"unknown"}function F(e,t){return typeof e=="number"&&Number.isFinite(e)?Math.min(t,Math.max(0,Math.round(e))):0}function gt(e){return e==="TRIAL_DEVICE_LIMIT_REACHED"?"这台设备已经领取过体验次数。":e==="TRIAL_IP_LIMIT_REACHED"?"当前网络的体验领取次数已达到上限。":e==="TRIAL_RATE_LIMITED"?"体验领取请求过于频繁，请稍后再试。":"暂时无法领取体验次数。"}const ge=[{id:"local-guojin-hongfeng",name:"弘丰 · 宽松一页",source:"cv-guojin-shanxi-hongfeng-2026-06-24.html",hasPhoto:!0,layout:"local-hongfeng",accent:"#D24726",contentGuide:Tt()},{id:"orbit-color-4",name:"Orbit 橙 · 紧凑双栏（内容多）",source:"xriley/Orbit-Theme orbit-4",hasPhoto:!0,layout:"orbit",accent:"#D24726",contentGuide:re("Orbit · 紧凑双栏")},{id:"orbit-color-6",name:"Orbit 青灰 · 紧凑双栏",source:"xriley/Orbit-Theme orbit-6",hasPhoto:!0,layout:"orbit",accent:"#4B6A78",contentGuide:re("Orbit 青灰 · 紧凑双栏")}],S=Object.fromEntries(ge.map(e=>[e.id,{id:e.id,name:e.name,locale:"zh-CN",hasPhoto:e.hasPhoto,thumbnailDataUrl:Ct(e),contentGuide:e.contentGuide,render:t=>Et(t,e)}]));function In(){return ge.map(e=>S[e.id])}function _(){return"local-guojin-hongfeng"}function Mn(e){return Object.prototype.hasOwnProperty.call(S,e)}function xt(e,t){return(S[e]??S[_()]).render(t)}function xe(e){return(S[e]??S[_()]).contentGuide}function bt(e){return xe(e).contentBudget}const U=794,yt=1123;function wt(e,t,n={}){const i=n.mode==="preview"?["html,body{margin:0;padding:0;background:#dfe3e8;}",`body{width:${U}px;min-height:${yt}px;}`,"@page{size:A4;margin:0;}",`.resume-print-page{margin:0;width:${U}px;box-shadow:none;}`].join(""):["body{margin:0;background:#f3f5f8;padding:24px;}","@page{size:A4;margin:0;}","@media print{body{background:#fff;padding:0;} .resume-print-page{box-shadow:none!important;margin:0!important;}}",`.resume-print-page{margin:0 auto;box-shadow:0 18px 48px rgba(30,41,59,.14);width:${U}px;}`].join("");return["<!DOCTYPE html>",'<html lang="zh-CN">',"<head>",'<meta charset="UTF-8">','<meta name="viewport" content="width=device-width, initial-scale=1.0">',`<title>${m(t)} - 简历</title>`,"<style>",Ot(),i,"</style>","</head>","<body>",`<div class="resume-print-page">${e}</div>`,"</body>","</html>"].join("")}function Et(e,t){return t.layout==="orbit"?kt(e,t):Mt(e,t)}function kt(e,t){const n=It(e);return`
    <div xmlns="http://www.w3.org/1999/xhtml" class="resume-template resume-template-orbit ${t.id}" style="${ke(t)}">
      <aside class="orbit-sidebar">
        <div class="orbit-profile">
          ${Ee(e,"orbit-photo")}
          <h1>${m(e.candidateName)}</h1>
          <p class="orbit-role">${m(e.title)}</p>
        </div>
        <div class="orbit-side-body">
          ${ye(e,"orbit-side")}
          ${n.sidebarSections.map(r=>St(r)).join("")}
        </div>
      </aside>
      <main class="orbit-main">
        ${n.mainSections.map(r=>At(r)).join("")}
      </main>
    </div>
  `}function It(e){const t=be(e,e.sections),n=t.filter(o=>o.kind==="tags"||/技能|关键词|能力标签|skill/i.test(o.title)),r=t.filter(o=>/教育|证书|作品|奖项|基本信息/i.test(o.title)),i=t.filter(o=>!n.includes(o)&&!r.includes(o));return{sidebarSections:[...r,...n],mainSections:i}}function Mt(e,t){const n=e.sections[0],r=n?e.sections.slice(1):e.sections;return`
    <div xmlns="http://www.w3.org/1999/xhtml" class="resume-template resume-template-local-hongfeng ${t.id}" style="${ke(t)}">
      <div class="local-page">
        <header class="local-header">
          <div class="local-header-main">
            <h1>${m(e.candidateName)}</h1>
            <p>${m(e.title)}</p>
            ${ye(e,"local")}
            <div class="local-gradient"></div>
          </div>
          ${Ee(e,"local-photo")}
        </header>
        ${n?`<section class="local-section">
                <h2>${m(n.title)}</h2>
                ${O(n,"local")}
              </section>`:""}
        ${be(e,r).map(i=>`<section class="local-section"><h2>${m(i.title)}</h2>${O(i,"local")}</section>`).join("")}
      </div>
    </div>
  `}function be(e,t){return e.educationExperiences.length===0||t.some(n=>/教育|证书|education/i.test(n.title))?t:[...t,{title:"教育背景",kind:"list",bullets:e.educationExperiences}]}function ye(e,t){return e.personalInfo.length===0?"":`
    <section class="${t}-basic-info">
      <h2>基本信息</h2>
      <ul>
        ${e.personalInfo.map(n=>`<li>${m(n)}</li>`).join("")}
      </ul>
    </section>
  `}function At(e){return`
    <section class="orbit-section">
      <h2><span></span>${m(e.title)}</h2>
      ${O(e,"orbit")}
    </section>
  `}function St(e){return`
    <section class="orbit-side-section">
      <h2>${m(e.title)}</h2>
      ${O(e,"orbit-side")}
    </section>
  `}function O(e,t){return e.kind==="paragraph"?`<p class="${t}-paragraph">${m(e.content??"")}</p>`:e.kind==="tags"?`<div class="${t}-tags">${(e.tags??[]).map(n=>`<span>${m(n)}</span>`).join("")}</div>`:e.kind==="experience"?_t(e.items??[],t):`<ul class="${t}-list">${(e.bullets??[]).map(n=>`<li>${m(n)}</li>`).join("")}</ul>`}function _t(e,t){return`
    <div class="${t}-experience">
      ${e.map(n=>`
            <article class="${t}-item">
              ${Pt(n,t)}
              ${n.text?`<p class="${t}-item-text">${m(n.text)}</p>`:""}
              ${n.bullets?.length?`<ul>${n.bullets.map(r=>`<li>${m(r)}</li>`).join("")}</ul>`:""}
              ${n.tags?.length?`<div class="${t}-tags">${n.tags.map(r=>`<span>${m(r)}</span>`).join("")}</div>`:""}
            </article>
          `).join("")}
    </div>
  `}function Pt(e,t){if(t==="orbit"){const n=we(e.subtitle),r=$t(e.subtitle);return`
      <div class="${t}-item-head">
        <div class="${t}-item-copy">
          ${e.title?`<h3>${m(e.title)}</h3>`:""}
          ${r?`<p class="${t}-item-meta">${m(r)}</p>`:""}
        </div>
        ${n?`<p class="${t}-item-time">${m(n)}</p>`:""}
      </div>
    `}return`
    <div class="${t}-item-head">
      ${e.title?`<h3>${m(e.title)}</h3>`:""}
      ${e.subtitle?`<p>${m(e.subtitle)}</p>`:""}
    </div>
  `}function we(e){return e?e.match(/((?:19|20)\d{2}(?:[./-]\d{1,2})?\s*(?:[~-]|至今|至今|—|–|到)\s*(?:(?:19|20)\d{2}(?:[./-]\d{1,2})?|至今)|(?:19|20)\d{2}(?:[./-]\d{1,2})?)/u)?.[0]?.trim()??"":""}function $t(e){if(!e)return"";const t=we(e);return t?e.replace(t,"").replace(/^[|/｜\-\s]+|[|/｜\-\s]+$/g,"").trim():e.trim()}function Ee(e,t){return e.candidatePhotoDataUrl?`<img class="${t}" src="${ie(e.candidatePhotoDataUrl)}" alt="${ie(e.candidateName)}" />`:`<div class="${t} photo-placeholder">${m(e.candidateName.slice(0,1)||"简")}</div>`}function ke(e){return`--accent:${e.accent};`}function Ct(e){const t=e.layout==="orbit",n=t?['<rect x="18" y="24" width="44" height="220" fill="rgba(255,255,255,.22)"/>','<circle cx="40" cy="54" r="14" fill="white" opacity=".82"/>','<rect x="28" y="80" width="24" height="4" rx="2" fill="white" opacity=".9"/>','<rect x="26" y="96" width="28" height="3" rx="1.5" fill="white" opacity=".66"/>','<rect x="26" y="108" width="24" height="3" rx="1.5" fill="white" opacity=".66"/>'].join(""):'<rect x="20" y="28" width="122" height="34" fill="white" opacity=".94"/><rect x="142" y="28" width="30" height="40" fill="white" opacity=".76"/>',r=t?78:24,i=t?82:116,o=t?94:144,c=Array.from({length:5},(p,l)=>{const a=92+l*32;return`<rect x="${r}" y="${a}" width="${i}" height="5" rx="2" fill="white" opacity=".82"/><rect x="${r}" y="${a+11}" width="${o}" height="4" rx="2" fill="white" opacity=".46"/>`}).join(""),s=`
    <svg xmlns="http://www.w3.org/2000/svg" width="192" height="272" viewBox="0 0 192 272">
      <rect width="192" height="272" fill="${e.accent}"/>
      <rect x="10" y="10" width="172" height="252" rx="4" fill="rgba(255,255,255,.18)"/>
      ${n}
      ${c}
      <text x="20" y="250" fill="white" font-size="13" font-family="Arial, sans-serif">${m(e.name)}</text>
    </svg>
  `;return`data:image/svg+xml;utf8,${encodeURIComponent(s)}`}function re(e){return{templateName:e,writingStyle:"紧凑双栏，适合内容偏多、需要压进一页的候选人：左侧头像/联系方式/教育/技能，右侧简介与经历项目。字号与间距偏紧，信息密度高。经历 subtitle 写时间。文风正式求职：先价值后细节，跨行业经历做职能转译包装。",contentBudget:{sectionsMax:5,sectionTitleMaxChars:14,paragraphMaxChars:170,listBulletsMax:4,experienceItemsMax:3,bulletsPerItemMax:4,bulletMaxChars:68,tagsMax:12,tagMaxChars:16},sectionPlan:[{title:"职业简介",kind:"paragraph",guidance:"130-170 字。写成投递主张：定位 + 转型/优势故事 + 2-3 个能力支柱 + 能交付什么。避免“具备…熟悉…”空话。"},{title:"核心经历",kind:"experience",guidance:"2-3 段，每段 3-4 条 bullet。标题面向目标岗；bullet=动作+场景+方法+结果。旧行业经历要转译成可迁移能力。"},{title:"项目成果",kind:"experience",guidance:"2-3 个项目。突出 0-1、上线/交付、用户/业务反馈、AI 能力落地；每项 2-3 条 bullet。"},{title:"技能栈",kind:"tags",guidance:"8-12 个精选词（会放在左侧栏），按目标岗相关性排序。"},{title:"教育证书",kind:"list",guidance:"只写用户明确提供的学校、专业、学历或证书（会放在左侧栏）。没有明确事实则省略。"}],exampleDraft:{title:"前端工程师",sections:[{title:"职业简介",kind:"paragraph",content:"具备中后台前端开发经验，熟悉 React、TypeScript 与复杂业务组件交付，能围绕目标岗位要求强化性能优化、协作沟通和工程化实践。"},{title:"核心经历",kind:"experience",items:[{title:"企业级前端开发经历",subtitle:"2021-2024",bullets:["负责业务模块开发与联调，沉淀可复用表单和权限组件","参与需求拆解、排期评估和跨端问题定位，保障版本按期交付"]}]},{title:"项目成果",kind:"experience",items:[{title:"候选人管理系统",bullets:["完成核心页面和状态管理设计，提升复杂列表与筛选场景的维护性","围绕性能瓶颈优化渲染和接口调用，改善用户操作体验"]}]},{title:"技能栈",kind:"tags",tags:["React","TypeScript","Vite","组件化","性能优化","复杂表单","权限系统","协作交付"]}]}}}function Tt(){return{templateName:"弘丰 · 宽松一页",writingStyle:"单栏一页：适合内容适中、经历不堆砌的候选人。字号清晰可读，章节间距适中，务必压在一页内，禁止为撑版面而拉大空白。顶部姓名+职位+证件照+联系方式，紫色强调线；正文中文模块。",contentBudget:{sectionsMax:6,sectionTitleMaxChars:14,paragraphMaxChars:160,listBulletsMax:4,experienceItemsMax:3,bulletsPerItemMax:3,bulletMaxChars:60,tagsMax:12,tagMaxChars:16},sectionPlan:[{title:"职业简介",kind:"paragraph",guidance:"120-160 字。投递主张：定位 + 优势故事 + 能力支柱 + 能交付什么。"},{title:"核心经历",kind:"experience",guidance:"2 段为主，每段 2-3 条 bullet。标题具体；bullet=动作+场景+结果。"},{title:"项目成果",kind:"experience",guidance:"2 个项目即可，每项 2-3 条 bullet，突出上线/交付/用户价值。"},{title:"技能栈",kind:"tags",guidance:"8-12 个精选词，偏目标岗能力与业务场景。"},{title:"教育背景",kind:"list",guidance:"只写明确学校、专业、学历、证书。"}],exampleDraft:{title:"AI 产品经理",sections:[{title:"职业简介",kind:"paragraph",content:"面向 AI 应用与业务提效场景，具备检测行业项目协调经验和 AI 工具产品化实践，能从业务痛点出发完成需求分析、方案设计、开发协同和上线验证。"},{title:"核心经历",kind:"experience",items:[{title:"第三方检测行业项目协调",subtitle:"2020-2024",bullets:["协调测试项目排期、客户沟通和交付跟进，保障项目按时推进","沉淀流程问题与客户需求，为产品化方案提供业务输入"]}]},{title:"项目成果",kind:"experience",items:[{title:"AI 与 macOS 工具项目",bullets:["完成需求分析、交互原型、功能验收和上线流程","集成大模型 API、RAG 与 Agent 能力，降低使用门槛"]}]},{title:"技能栈",kind:"tags",tags:["AI 应用","需求分析","业务流程","原型设计","项目推进","客户沟通"]}]}}}function Ot(){return`
    *{box-sizing:border-box;}
    .resume-template{width:794px;min-height:1123px;background:#fff;color:#333;font-family:Arial,"Microsoft YaHei","PingFang SC",sans-serif;font-size:13px;line-height:1.58;overflow:hidden;}
    .resume-template h1,.resume-template h2,.resume-template h3,.resume-template p,.resume-template ul{margin:0;}
    .resume-template ul{padding-left:18px;}
    .resume-template li{margin:3px 0;}
    .resume-template img{object-fit:cover;}
    .photo-placeholder{display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.2);font-weight:700;}

    /* —— Orbit 双栏：真 grid，侧栏满高着色，主栏自然流式 —— */
    .resume-template-orbit{
      display:grid;
      grid-template-columns:250px 544px;
      width:794px;
      min-height:1123px;
      background:#fff;
      align-items:stretch;
    }
    .orbit-sidebar{
      background:var(--accent);
      color:#fff;
      display:flex;
      flex-direction:column;
      min-height:1123px;
    }
    .orbit-profile{
      padding:28px 22px 22px;
      text-align:center;
      background:rgba(0,0,0,.16);
    }
    .orbit-photo{
      width:96px;
      height:96px;
      border-radius:50%;
      border:3px solid rgba(255,255,255,.42);
      display:block;
      margin:0 auto;
      background:rgba(255,255,255,.12);
    }
    .orbit-photo.photo-placeholder{font-size:28px;color:#fff;}
    .orbit-profile h1{
      margin-top:14px;
      font-size:28px;
      line-height:1.15;
      font-weight:800;
      color:#fff;
      letter-spacing:.02em;
    }
    .orbit-role{
      margin-top:8px;
      font-size:13px;
      line-height:1.35;
      color:rgba(255,255,255,.82);
      font-weight:500;
    }
    .orbit-side-body{padding:10px 0 36px;}
    .orbit-side-basic-info,
    .orbit-side-section{
      padding:18px 22px 6px;
    }
    .orbit-side-basic-info h2,
    .orbit-side-section h2{
      margin:0 0 10px;
      padding-bottom:7px;
      border-bottom:1px solid rgba(255,255,255,.28);
      font-size:13px;
      font-weight:700;
      letter-spacing:.06em;
      color:#fff;
    }
    .orbit-side-basic-info ul{
      list-style:none;
      padding:0;
      margin:0;
    }
    .orbit-side-basic-info li{
      margin:0 0 8px;
      font-size:12px;
      line-height:1.45;
      color:rgba(255,255,255,.94);
      word-break:break-all;
    }
    .orbit-side-basic-info li:last-child{margin-bottom:0;}
    .orbit-side-list{
      margin:0;
      padding-left:16px;
      list-style:disc;
    }
    .orbit-side-list li{
      margin:0 0 7px;
      font-size:12px;
      line-height:1.5;
      color:rgba(255,255,255,.94);
    }
    .orbit-side-paragraph{
      font-size:12px;
      line-height:1.55;
      color:rgba(255,255,255,.94);
      white-space:pre-wrap;
    }
    /* 技能进侧栏：竖向标签，把左侧撑起来 */
    .orbit-side-tags{
      display:flex;
      flex-wrap:wrap;
      gap:8px;
      padding-top:2px;
    }
    .orbit-side-tags span{
      display:inline-block;
      padding:4px 9px;
      border-radius:999px;
      border:1px solid rgba(255,255,255,.32);
      background:rgba(255,255,255,.12);
      color:#fff;
      font-size:11px;
      line-height:1.3;
      font-weight:500;
    }

    .orbit-main{
      background:#fff;
      padding:40px 36px 48px;
      min-height:1123px;
    }
    .orbit-section{margin:0 0 30px;}
    .orbit-section:last-child{margin-bottom:0;}
    .orbit-section h2{
      display:flex;
      align-items:center;
      gap:10px;
      margin:0 0 14px;
      padding-bottom:9px;
      border-bottom:1.5px solid color-mix(in srgb,var(--accent),#fff 72%);
      font-size:15px;
      font-weight:700;
      color:color-mix(in srgb,var(--accent),#000 12%);
      letter-spacing:.02em;
    }
    .orbit-section h2 span{
      display:inline-block;
      width:8px;
      height:8px;
      border-radius:50%;
      background:var(--accent);
      flex:0 0 8px;
    }
    .orbit-paragraph{
      font-size:12.5px;
      line-height:1.78;
      color:#3d4654;
      text-align:justify;
      white-space:pre-wrap;
    }
    .orbit-experience{display:flex;flex-direction:column;gap:18px;}
    .orbit-item{break-inside:avoid;}
    .orbit-item-head{
      display:flex;
      justify-content:space-between;
      align-items:flex-start;
      gap:12px;
      margin-bottom:7px;
    }
    .orbit-item-copy{flex:1;min-width:0;}
    .orbit-item-head h3{
      font-size:13.5px;
      font-weight:700;
      color:#1f2937;
      line-height:1.35;
    }
    .orbit-item-meta{
      margin-top:3px;
      font-size:11.5px;
      color:#6b7c93;
      line-height:1.35;
    }
    .orbit-item-time{
      flex:0 0 auto;
      font-size:11.5px;
      color:#6b7c93;
      white-space:nowrap;
      line-height:1.35;
      padding-top:2px;
    }
    .orbit-item-text,
    .orbit-item li{
      color:#3d4654;
      font-size:12.5px;
      line-height:1.72;
      white-space:pre-wrap;
    }
    .orbit-item ul{
      margin:6px 0 0;
      padding-left:18px;
    }
    .orbit-item li{margin:5px 0;}
    .orbit-tags{display:flex;flex-wrap:wrap;gap:7px;}
    .orbit-tags span{
      border:1px solid color-mix(in srgb,var(--accent),#fff 55%);
      border-radius:999px;
      padding:4px 10px;
      color:color-mix(in srgb,var(--accent),#000 22%);
      background:color-mix(in srgb,var(--accent),#fff 90%);
      font-size:11px;
      line-height:1.3;
      font-weight:500;
    }

    /* —— 弘丰 · 单栏一页：比旧版好读，但不把 A4 撑爆 —— */
    .resume-template-local-hongfeng{
      width:794px;
      min-height:1123px;
      max-height:1123px;
      background:#fff;
      color:#222;
      overflow:hidden;
    }
    .local-page{
      width:794px;
      min-height:1123px;
      max-height:1123px;
      padding:36px 42px 32px;
      background:#fff;
      box-sizing:border-box;
      overflow:hidden;
    }
    .local-header{
      display:flex;
      align-items:flex-start;
      justify-content:space-between;
      gap:22px;
      margin-bottom:20px;
    }
    .local-header-main{flex:1;min-width:0;padding-top:2px;}
    .local-header h1{
      font-size:30px;
      line-height:1.12;
      font-weight:800;
      color:#151515;
      margin:0 0 6px;
      letter-spacing:.02em;
    }
    .local-header-main > p{
      font-size:15px;
      line-height:1.3;
      color:#3a3a3a;
      margin:0 0 10px;
      font-weight:600;
    }
    .local-basic-info{margin:0 0 10px;}
    .local-basic-info h2{display:none;}
    .local-basic-info ul{
      display:flex;
      flex-wrap:wrap;
      gap:4px 14px;
      list-style:none;
      padding:0;
      margin:0;
    }
    .local-basic-info li{
      font-size:12px;
      color:#555;
      margin:0;
      line-height:1.4;
    }
    .local-gradient{
      height:5px;
      border-radius:999px;
      background:linear-gradient(90deg,#D24726 0 84%,#4472C4 84% 100%);
      margin-top:2px;
    }
    .local-photo{
      width:96px;
      height:118px;
      object-fit:cover;
      border:2px solid #fff;
      box-shadow:0 0 0 1px #d9d9d9;
      border-radius:2px;
      flex:0 0 auto;
      background:#FBE9E3;
    }
    .local-photo.photo-placeholder{
      font-size:28px;
      color:#D24726;
    }
    .local-section{
      margin:0 0 18px;
      break-inside:avoid;
    }
    .local-section:last-child{margin-bottom:0;}
    .local-section h2{
      font-size:15.5px;
      font-weight:800;
      color:#D24726;
      border-bottom:1px solid #EBCFC5;
      padding-bottom:6px;
      margin:0 0 10px;
      letter-spacing:.03em;
    }
    .local-paragraph{
      font-size:14.5px;
      line-height:1.72;
      color:#333;
      text-align:justify;
      white-space:pre-wrap;
    }
    .local-list{
      margin:0;
      padding-left:20px;
      list-style:disc;
    }
    .local-list li{
      font-size:14.5px;
      line-height:1.65;
      color:#333;
      margin:4px 0;
    }
    .local-experience{display:flex;flex-direction:column;gap:13px;}
    .local-item{break-inside:avoid;}
    .local-item-head{
      display:flex;
      justify-content:space-between;
      align-items:flex-start;
      gap:12px;
      margin-bottom:5px;
    }
    .local-item-head h3{
      font-size:14.5px;
      font-weight:700;
      color:#2F5597;
      line-height:1.35;
    }
    .local-item-head p{
      font-size:12.5px;
      color:#777;
      white-space:nowrap;
      line-height:1.35;
      padding-top:2px;
    }
    .local-item-text,
    .local-item li{
      font-size:14.5px;
      color:#333;
      line-height:1.68;
      white-space:pre-wrap;
    }
    .local-item ul{
      margin:3px 0 0;
      padding-left:20px;
    }
    .local-item li{margin:3px 0;}
    .local-tags{
      display:flex;
      flex-wrap:wrap;
      gap:8px;
    }
    .local-tags span{
      font-size:13px;
      line-height:1.3;
      font-weight:600;
      background:#FBE9E3;
      color:#A93B22;
      border-radius:5px;
      padding:6px 12px;
    }
    .local-item .local-tags{margin-top:6px;}
  `}function m(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function ie(e){return m(e).replace(/`/g,"&#96;")}const oe=me,d={summaryMaxChars:150,sectionsMax:6,sectionContentMaxChars:150,sectionBulletsMax:4,sectionItemsMax:3,sectionTagsMax:12,skillGroupsMax:3,skillsPerGroupMax:6,workExperienceMax:3,projectExperienceMax:3,bulletsPerExperienceMax:4,bulletMaxChars:70,educationMax:3,keywordsMax:12};function An(e,t,n){if(!n)return{buckets:[],strategies:[],customStrategies:[],batchJobCount:0};const r=e.map(a=>({job:a,analysis:t[a.id]})).filter(a=>!!a.analysis),i=new Map;for(const{job:a,analysis:u}of r){if(u.recommendation==="skip")continue;const b=se(u.roleType||a.title),f=ce(b),w=i.get(f)??{id:f,roleFamily:b,jobs:[],analyses:[],keywords:new Map};w.jobs.push(a),w.analyses.push(u);for(const M of Ht(a,u,n))w.keywords.set(M,(w.keywords.get(M)??0)+1);i.set(f,w)}const o=new Date().toISOString(),c=[...i.values()].map(a=>Vt(a,o)).sort((a,u)=>u.jobIds.length-a.jobIds.length||u.confidence-a.confidence),s=new Map(c.map(a=>[a.id,a])),p=r.map(({job:a,analysis:u})=>{const b=se(u.roleType||a.title),f=u.recommendation==="skip"?void 0:ce(b),w=f?s.get(f):void 0;return qt(a,u,n,w)}),l=p.filter(a=>a.strategy==="custom").sort((a,u)=>u.customPriority-a.customPriority);return{buckets:c,strategies:p,customStrategies:l,batchJobCount:p.filter(a=>a.strategy==="batch").length}}async function Sn(e,t,n,r,i={}){if(!D(r))throw new Error("AI provider is not configured.");const o=i.templateId??_(),c=xe(o),s=t.filter(f=>e.jobIds.includes(f.id)).slice(0,8),p={bucket:e,jobs:s,profile:n,template:{id:o,templateName:c.templateName,writingStyle:c.writingStyle,contentBudget:c.contentBudget,sectionPlan:c.sectionPlan,exampleDraft:c.exampleDraft}};let l;if(E(r))l=await q(r,"resume-generation",p,{timeoutMs:18e4,onWalletUpdate:i.onWalletUpdate});else{const f=He(p),w=`${r.baseUrl.replace(/\/$/,"")}/chat/completions`,M=await fetch(w,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${r.apiKey}`},body:JSON.stringify({model:r.model,temperature:f.temperature,...jt(r,f.thinkingBudget),response_format:{type:"json_object"},messages:[{role:"system",content:f.system},{role:"user",content:f.user}]})});if(!M.ok){const Se=await M.text();throw new Error(`AI provider request failed: ${M.status} ${Se}`)}const X=(await M.json()).choices?.[0]?.message?.content;if(!X)throw new Error("AI provider returned an empty resume draft.");l=W(X)}const a=Dt(l,e,c.contentBudget),u=new Date().toISOString(),b={id:`${n.id}:${e.id}:${oe}:${u}`,profileId:n.id,bucketId:e.id,generatedAt:u,provider:r.providerId,model:E(r)?"managed":r.model,promptVersion:`${oe}:${o}`,...a};return Nt(b,e.id),b}function jt(e,t){return e.providerId==="deepseek"||e.baseUrl.includes("api.deepseek.com")?{thinking:{type:"enabled"}}:e.providerId==="bailian"||e.baseUrl.includes("dashscope.aliyuncs.com")?{enable_thinking:!0,thinking_budget:t}:{}}function Rt(e,t){return!e||t&&e.bucketId!==t?!1:!!e.title.trim()&&Q(e.sections).some(Ie)}function Lt(e,t,n,r,i={}){const o=Bt(e,t,n,r,i);return xt(i.templateId??_(),o)}function _n(e,t,n,r,i={}){return wt(Lt(e,t,n,r,i),e.name,{mode:i.documentMode??"print"})}function Dt(e,t,n){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("AI JSON payload is not a valid resume draft object.");const r=e,i=I(r.keywords).slice(0,Math.min(d.keywordsMax,n.tagsMax)),o=Q(r.sections,n);return{title:y(r.title)??"",sections:o,summary:h(y(r.summary)??"",Math.min(d.summaryMaxChars,n.paragraphMaxChars)),skillGroups:Ut(r.skillGroups),workExperiences:ae(r.workExperiences),projectExperiences:ae(r.projectExperiences),educationExperiences:L(r.educationExperiences),targetJobs:[],keywords:i}}function Nt(e,t){if(!Rt(e,t))throw new Error("AI 简历草稿不完整：缺少可渲染的模板栏目内容。请补充个人画像后重新生成。")}function Q(e,t=Me()){return Array.isArray(e)?e.map(n=>{if(!n||typeof n!="object"||Array.isArray(n))return null;const r=n,i=y(r.title),o=zt(r.kind);if(!i||!o)return null;const c={title:h(i,Math.min(16,t.sectionTitleMaxChars)),kind:o};if(o==="paragraph"){const s=y(r.content??r.text??r.summary);if(!s)return null;c.content=h(s,Math.min(d.sectionContentMaxChars,t.paragraphMaxChars))}if(o==="list"){const s=I(r.bullets??r.items??r.points).slice(0,Math.min(d.sectionBulletsMax,t.listBulletsMax)).map(p=>h(p,Math.min(d.bulletMaxChars,t.bulletMaxChars)));if(s.length===0)return null;c.bullets=s}if(o==="tags"){const s=I(r.tags??r.items??r.keywords).slice(0,Math.min(d.sectionTagsMax,t.tagsMax)).map(p=>h(p,Math.min(24,t.tagMaxChars)));if(s.length===0)return null;c.tags=s}if(o==="experience"){const s=Ft(r.items??r.experiences??r.projects,t);if(s.length===0)return null;c.items=s}return c}).filter(n=>!!n).filter(Ie).slice(0,Math.min(d.sectionsMax,t.sectionsMax)):[]}function zt(e){return e==="paragraph"||e==="list"||e==="experience"||e==="tags"?e:null}function Ft(e,t=Me()){return Array.isArray(e)?e.map(n=>{if(!n||typeof n!="object"||Array.isArray(n))return null;const r=n,i=y(r.title??r.name??r.company??r.projectName),o=y(r.subtitle),c=y(r.text??r.content??r.summary),s=I(r.bullets??r.points).slice(0,Math.min(d.bulletsPerExperienceMax,t.bulletsPerItemMax)).map(l=>h(l,Math.min(d.bulletMaxChars,t.bulletMaxChars))),p=I(r.tags??r.keywords).slice(0,Math.min(8,t.tagsMax)).map(l=>h(l,Math.min(24,t.tagMaxChars)));return!i&&!c&&s.length===0&&p.length===0?null:{...i?{title:h(i,32)}:{},...o?{subtitle:h(o,36)}:{},...c?{text:h(c,Math.min(d.sectionContentMaxChars,t.paragraphMaxChars))}:{},...s.length?{bullets:s}:{},...p.length?{tags:p}:{}}}).filter(n=>!!n).slice(0,Math.min(d.sectionItemsMax,t.experienceItemsMax)):[]}function Ie(e){return e.kind==="paragraph"?!!e.content?.trim():e.kind==="list"?!!e.bullets?.length:e.kind==="tags"?!!e.tags?.length:!!e.items?.length}function Ut(e){return Array.isArray(e)?e.map(t=>{if(!t||typeof t!="object"||Array.isArray(t))return null;const n=t,r=I(n.items).slice(0,d.skillsPerGroupMax).map(o=>h(o,24));if(r.length===0)return null;const i=y(n.category);return i?{category:i,items:r}:null}).filter(t=>!!t).slice(0,d.skillGroupsMax):[]}function ae(e){return Array.isArray(e)?e.map(t=>{if(!t||typeof t!="object"||Array.isArray(t))return null;const n=t,r=y(n.title??n.name??n.company??n.projectName),i=I(n.bullets??n.bullet??n.points??n.items??n.content??n.description).slice(0,d.bulletsPerExperienceMax).map(s=>h(s,d.bulletMaxChars)),o=y(n.subtitle);if(!r||i.length===0)return null;const c={title:r,bullets:i};return o&&(c.subtitle=o),c}).filter(t=>!!t).slice(0,d.workExperienceMax):[]}function Bt(e,t,n,r,i={}){const o=i.templateId??_(),c=bt(o),s=i.preserveDraftContent===!0;return{candidateName:n.name||"候选人",candidatePhotoDataUrl:n.profilePhotoDataUrl,title:s?r?.title||"":Kt(r?.title||""),personalInfo:Jt(n),sections:r?Gt(r,c,s):[],summary:s?r?.summary||"":h(r?.summary||"",Math.min(d.summaryMaxChars,c.paragraphMaxChars)),skillGroups:r?.skillGroups.length?s?r.skillGroups.map(p=>({...p,items:[...p.items]})):r.skillGroups.slice(0,d.skillGroupsMax).map(p=>({category:p.category,items:p.items.slice(0,d.skillsPerGroupMax).map(l=>h(l,24))})):[],workExperiences:r?.workExperiences.length?s?R(r.workExperiences):j(r.workExperiences,d.workExperienceMax):[],projectExperiences:r?.projectExperiences.length?s?R(r.projectExperiences):j(r.projectExperiences,d.projectExperienceMax):[],educationExperiences:r?.educationExperiences.length?s?[...r.educationExperiences]:L(r.educationExperiences):s?[...n.educationExperiences]:L(n.educationExperiences),keywords:r?.keywords.length?s?[...r.keywords]:r.keywords.slice(0,Math.min(d.keywordsMax,c.tagsMax)):[]}}function Gt(e,t,n=!1){const r=n?rn(e.sections??[]):Q(e.sections,t);return r.length>0?r:vt(e,t,n)}function vt(e,t,n=!1){const r=[],i=n?e.summary||"":h(e.summary||"",Math.min(d.summaryMaxChars,t.paragraphMaxChars)),o=n?R(e.workExperiences):j(e.workExperiences,d.workExperienceMax),c=n?R(e.projectExperiences):j(e.projectExperiences,d.projectExperienceMax),s=(n?[...e.keywords,...e.skillGroups.flatMap(l=>l.items)]:[...e.keywords,...e.skillGroups.flatMap(l=>l.items)].slice(0,Math.min(d.sectionTagsMax,t.tagsMax))).map(l=>n?l:h(l,Math.min(24,t.tagMaxChars))),p=n?[...e.educationExperiences]:L(e.educationExperiences);return i&&r.push({title:"职业定位",kind:"paragraph",content:i}),o.length>0&&r.push({title:"核心经历",kind:"experience",items:o}),c.length>0&&r.push({title:"代表成果",kind:"experience",items:c}),s.length>0&&r.push({title:"能力标签",kind:"tags",tags:s}),p.length>0&&r.push({title:"教育 / 证书",kind:"list",bullets:p}),n?r:r.slice(0,Math.min(d.sectionsMax,t.sectionsMax))}function Jt(e){const t=e.currentCity||e.targetCities[0]||"";return[e.age?`年龄：${h(e.age,12)}`:"",e.phone?`电话：${h(e.phone,24)}`:"",e.email?`邮箱：${h(e.email,40)}`:"",t?`城市：${h(t,16)}`:""].filter(Boolean)}function Me(){return{sectionsMax:d.sectionsMax,sectionTitleMaxChars:16,paragraphMaxChars:d.sectionContentMaxChars,listBulletsMax:d.sectionBulletsMax,experienceItemsMax:d.sectionItemsMax,bulletsPerItemMax:d.bulletsPerExperienceMax,bulletMaxChars:d.bulletMaxChars,tagsMax:d.sectionTagsMax,tagMaxChars:24}}function Kt(e){return e.replace(/定制简历|简历|版/g,"").replace(/[·|｜].*$/g,"").trim()}function Vt(e,t){const n=[...e.keywords.entries()].sort((i,o)=>o[1]-i[1]||i[0].localeCompare(o[0])).slice(0,8).map(([i])=>i),r=Z(e.analyses.reduce((i,o)=>i+Ae(o.confidence),0)/Math.max(e.analyses.length,1));return{id:e.id,name:`${e.roleFamily}版`,functionArea:nn(e.roleFamily,n),roleFamily:e.roleFamily,specialization:n.slice(0,3).join(" / ")||void 0,jobIds:e.jobs.map(i=>i.id),sharedKeywords:n,resumeAngle:tn(e.roleFamily,n),evidenceSummary:`该桶包含 ${e.jobs.length} 条职位，主要围绕 ${n.slice(0,4).join("、")||e.roleFamily} 展开。`,confidence:r,createdAt:t,updatedAt:t}}function qt(e,t,n,r){const i=t.scoreOverall/5,o=Wt(t),c=Yt(t,r),s=Qt(t),p=Zt(e,t,n),l=Z(i*.35+o*.25+c*.25-s*.1-p*.05),a=r?Xt(e,t,r):0,u=t.recommendation==="skip"?"skip":l>=.75&&i>=.65&&s<.35?"custom":"batch";return{jobId:e.id,bucketId:r?.id,strategy:u,bucketConfidence:a,customPriority:l,customizationLift:c,customizationCost:p,riskPenalty:s,reason:en(u,e,t,r),suggestedResumeAngle:r?.resumeAngle??t.nextAction}}function se(e){return e.replace(/[（(].*?[)）]/g,"").replace(/高级|资深|初级|中级|实习|专家|主管|经理/g,"").replace(/\s+/g,"").trim()||"通用岗位"}function ce(e){return`bucket-${e.toLowerCase().replace(/[^a-z0-9\u4e00-\u9fa5]+/g,"-")}`}function Ht(e,t,n){return v([...e.skills,...t.matchedSkills,...t.strengths,...n.skills.filter(r=>e.description.includes(r)||e.skills.includes(r))]).slice(0,12)}function Wt(e){const t=e.recommendation==="apply"?.15:e.recommendation==="consider"?.05:0,n=e.salaryFit==="good"?.85:e.salaryFit==="ok"?.65:e.salaryFit==="low"?.3:.45,r=e.locationFit==="match"?.1:e.locationFit==="acceptable"?.05:0;return P(n+t+r)}function Yt(e,t){const n=e.softGaps.length>0||e.missingSkills.length>0,r=e.matchedSkills.length>0||e.strengths.length>0,i=t&&t.confidence<.72?.12:0;return P((n&&r?.72:.48)+i)}function Qt(e){const t=Math.min(.55,e.hardStops.length*.25),n=Math.min(.25,e.risks.length*.06),r=e.salaryFit==="low"?.16:0,i=e.locationFit==="mismatch"?.18:0;return P(t+n+r+i)}function Zt(e,t,n){const r=Math.min(.45,t.missingSkills.length*.06),i=e.detailCaptured?0:.15,o=n.resumeSummary.trim()?0:.2;return P(r+i+o)}function Xt(e,t,n){const r=n.sharedKeywords.filter(c=>`${e.title} ${e.description} ${e.skills.join(" ")} ${t.matchedSkills.join(" ")}`.toLowerCase().includes(c.toLowerCase())).length,i=n.sharedKeywords.length>0?r/n.sharedKeywords.length:.4,o=Ae(t.confidence);return Z(i*.55+o*.35+Math.min(n.jobIds.length,5)*.02)}function en(e,t,n,r){return e==="skip"?n.hardStops[0]||n.risks[0]||"该职位当前风险较高，暂不建议投入简历定制成本。":e==="custom"?`“${t.title}”匹配度较高，且可通过突出 ${n.matchedSkills.slice(0,3).join("、")||r?.roleFamily||"相关经历"} 提升命中率。`:`可使用“${r?.name??"通用"}”批量投递，核心卖点与该职位需求基本一致。`}function tn(e,t){const n=t.slice(0,4).join("、");return n?`主打 ${e} 能力，突出 ${n} 等关键词。`:`主打 ${e} 相关经验和稳定交付能力。`}function nn(e,t){const n=`${e} ${t.join(" ")}`.toLowerCase();return/react|前端|后端|java|python|开发|工程师|算法|数据/.test(n)?"技术研发":/运营|内容|增长|电商|社媒|市场/.test(n)?"市场/运营":/销售|商务|客户|bd/.test(n)?"销售/商务":/质量|制程|供应链|生产|采购|检验/.test(n)?"制造/供应链":"通用职能"}function v(e){const t=new Set;return e.map(n=>n.trim()).filter(n=>{if(!n)return!1;const r=n.toLowerCase();return t.has(r)?!1:(t.add(r),!0)})}function j(e,t){return e.slice(0,t).map(n=>({title:h(n.title,32),...n.subtitle?{subtitle:h(n.subtitle,36)}:{},bullets:n.bullets.slice(0,d.bulletsPerExperienceMax).map(r=>h(r,d.bulletMaxChars))}))}function R(e){return e.map(t=>({...t,bullets:[...t.bullets]}))}function rn(e){return e.map(t=>({...t,...t.items?{items:t.items.map(n=>({...n,...n.bullets?{bullets:[...n.bullets]}:{},...n.tags?{tags:[...n.tags]}:{}}))}:{},...t.bullets?{bullets:[...t.bullets]}:{},...t.tags?{tags:[...t.tags]}:{}}))}function h(e,t){const n=e.trim();return n.length<=t?n:`${n.slice(0,Math.max(0,t-1)).trim()}…`}function I(e){return typeof e=="string"?v(e.split(/\n|；|;|。/).map(t=>t.trim()).filter(Boolean)):Array.isArray(e)?v(e.map(t=>typeof t=="string"?t:"")):[]}function L(e){return I(e).filter(on).slice(0,d.educationMax).map(t=>h(t,48))}function on(e){const t=e.replace(/\s+/g,"").toLowerCase();return!t||/(相关专业|某某|待补充|未填写|不详|未知|暂无|n\/a|xx|xxx)/i.test(t)||/^(本科|硕士|博士|大专|专科|学历|学位|证书|相关证书)$/.test(t)?!1:/(大学|学院|学校|university|college|认证|证书|资格证|职称|cet-|雅思|托福|pmp|软考)/i.test(t)}function y(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function Ae(e){return e==="high"?.9:e==="low"?.45:.68}function P(e){return Math.max(0,Math.min(1,e))}function Z(e){return Math.round(P(e)*100)/100}export{ln as A,bn as B,xn as C,nt as D,yn as E,G as F,Sn as G,sn as M,cn as O,ze as P,yt as R,wn as a,dn as b,En as c,Ue as d,fn as e,de as f,J as g,D as h,An as i,_ as j,_n as k,In as l,Mn as m,U as n,N as o,hn as p,Ne as q,pn as r,mn as s,pe as t,un as u,kn as v,ne as w,gn as x,$e as y,ot as z};
