mirror of
https://github.com/setube/ogame-vue-ts.git
synced 2026-05-12 16:05:12 +08:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cfcde0b024 | ||
|
|
053bd24855 | ||
|
|
7d1f36046d | ||
|
|
22ae07de90 | ||
|
|
a76909a2c7 | ||
|
|
8144f305e2 | ||
|
|
04721e2450 | ||
|
|
85ab19fb4a | ||
|
|
03f76b6497 | ||
|
|
9a571da4b1 | ||
|
|
797cc815f6 | ||
|
|
30aceb2a76 | ||
|
|
4340450d78 | ||
|
|
2bac87cd39 | ||
|
|
1aac97dfee | ||
|
|
84b090d51d | ||
|
|
a592713623 | ||
|
|
ec6b9cee07 | ||
|
|
b6fcad0a65 | ||
|
|
5273520305 | ||
|
|
751cb1e341 | ||
|
|
add90c5603 | ||
|
|
3410eeda19 | ||
|
|
c690323803 | ||
|
|
59dd7bfd05 | ||
|
|
3fa716e515 | ||
|
|
9aa240e335 | ||
|
|
88fa8aa2ee | ||
|
|
2601f1b776 | ||
|
|
763dfdde04 |
45
.github/workflows/github-pages.yml
vendored
Normal file
45
.github/workflows/github-pages.yml
vendored
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
name: 构建 Github Pages
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main ] # 如果你的主分支叫 master,请改为 master
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pages: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
environment:
|
||||||
|
name: github-pages
|
||||||
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
|
steps:
|
||||||
|
- name: 检出代码
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: 安装 Nodejs
|
||||||
|
uses: actions/setup-node@v6
|
||||||
|
with:
|
||||||
|
node-version: 20 # 建议使用 LTS 版本
|
||||||
|
|
||||||
|
- name: 安装 pnpm 并构建前端
|
||||||
|
uses: pnpm/action-setup@v4
|
||||||
|
with:
|
||||||
|
run_install: true
|
||||||
|
|
||||||
|
- name: 构建前端项目
|
||||||
|
run: pnpm run build
|
||||||
|
|
||||||
|
# 关键步骤:告诉 GitHub Actions 跳过 Jekyll 检查
|
||||||
|
- name: 配置 Github Pages
|
||||||
|
uses: actions/configure-pages@v5
|
||||||
|
|
||||||
|
- name: 上传构建版
|
||||||
|
uses: actions/upload-pages-artifact@v4
|
||||||
|
with:
|
||||||
|
path: './docs'
|
||||||
|
|
||||||
|
- name: 部署到 GitHub Pages
|
||||||
|
uses: actions/deploy-pages@v4
|
||||||
1
.github/workflows/ogame-vue-ts.yml
vendored
1
.github/workflows/ogame-vue-ts.yml
vendored
@@ -57,3 +57,4 @@ jobs:
|
|||||||
${{ vars.DOCKERHUB_USERNAME != '' && format('docker.io/{0}/ogame-vue-ts:{1}', vars.DOCKERHUB_USERNAME, github.sha) || '' }}
|
${{ vars.DOCKERHUB_USERNAME != '' && format('docker.io/{0}/ogame-vue-ts:{1}', vars.DOCKERHUB_USERNAME, github.sha) || '' }}
|
||||||
cache-from: type=gha
|
cache-from: type=gha
|
||||||
cache-to: type=gha,mode=max
|
cache-to: type=gha,mode=max
|
||||||
|
outputs: type=image,name=target,annotation-index.org.opencontainers.image.description=OGame Vue
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -11,6 +11,8 @@ CLAUDE.md
|
|||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
dist-ssr
|
dist-ssr
|
||||||
|
dist-electron
|
||||||
|
docs
|
||||||
*.local
|
*.local
|
||||||
|
|
||||||
# Editor directories and files
|
# Editor directories and files
|
||||||
@@ -24,3 +26,5 @@ dist-ssr
|
|||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
|
/docs
|
||||||
|
/docs/assets
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
import { BrowserWindow, app } from "electron";
|
|
||||||
import path, { dirname } from "node:path";
|
|
||||||
import { fileURLToPath } from "node:url";
|
|
||||||
app.whenReady().then(() => {
|
|
||||||
let i = dirname(fileURLToPath(import.meta.url)), a = new BrowserWindow({
|
|
||||||
title: "OGame",
|
|
||||||
icon: path.join(i, "../public/favicon.ico"),
|
|
||||||
width: 1200,
|
|
||||||
height: 800
|
|
||||||
});
|
|
||||||
a.setMenu(null), process.env.VITE_DEV_SERVER_URL ? a.loadURL(process.env.VITE_DEV_SERVER_URL) : a.loadFile("docs/index.html");
|
|
||||||
});
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
ogame-vue-ts.wenzi.games
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,7 +0,0 @@
|
|||||||
import{$t as e,At as t,Ct as n,Dn as r,En as i,Gn as a,Gt as o,Jt as s,Ln as c,Ot as ee,Qt as l,Vt as te,Xn as u,Xt as d,Yn as ne,Yt as f,Zt as p,_ as m,b as h,en as g,g as re,gn as _,jt as ie,kt as ae,m as oe,mn as v,p as se,qn as y,tn as ce,v as le,y as b}from"./game-logic-Bi1l7y4K.js";import"./vendor-pinia-DqhKuBjp.js";import"./vendor-crypto-CQM8pryk.js";import"./game-i18n-Dr0JspcV.js";import"./vendor-others-DTUzJ7S-.js";import"./vendor-reka-ui-BEHIKScj.js";import"./vendor-utils-BlvnUqQX.js";import"./vendor-vueuse-CJcfYqoW.js";import{B as ue,M as x}from"./vendor-icons-z9V6Jdbh.js";import{t as S}from"./CardDescription-BSLS07AU.js";import{d as C,v as de}from"./game-config-CG6z6nnH.js";import{D as fe,H as pe,K as w,N as T,W as E,_ as D,a as O,b as me,c as he,f as k,h as ge,i as A,l as j,o as M,p as N,q as P,r as F,s as I,u as L,v as _e,y as ve}from"./index-BT5w6et-.js";import{t as ye}from"./useGameConfig-b98LOtBY.js";import{t as be}from"./CardUnlockOverlay-DYfgGY6J.js";var xe={key:0,class:`container mx-auto p-4 sm:p-6`},Se={class:`text-2xl sm:text-3xl font-bold mb-4 sm:mb-6`},Ce={class:`mb-4 sm:mb-6 p-3 sm:p-4 bg-muted/50 rounded-lg border`},we={class:`flex items-center justify-between`},Te={class:`text-sm sm:text-base font-medium flex items-center gap-2`},Ee={class:`text-sm sm:text-base font-bold`},De={class:`mt-2`},Oe={class:`w-full bg-background rounded-full h-2.5 sm:h-3 overflow-hidden`},ke={class:`grid grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4`},Ae={class:`mb-2`},je={class:`flex flex-col sm:flex-row sm:justify-between sm:items-start gap-2`},Me={class:`space-y-3`},R={class:`text-xs sm:text-sm space-y-1.5 sm:space-y-2`},Ne={class:`text-muted-foreground mb-1 sm:mb-2`},Pe={class:`space-y-1 sm:space-y-1.5`},Fe={class:`text-xs`},Ie={class:`text-xs sm:text-sm space-y-0.5 sm:space-y-1`},Le={class:`flex items-center gap-1.5 text-muted-foreground`},Re={class:`flex items-center gap-1.5 text-muted-foreground`},ze={key:1,class:`text-xs text-muted-foreground`},Be={class:`flex gap-2 flex-wrap`},Ve={key:0},z=ce({__name:`BuildingsView`,setup(ce){let z=P(),He=fe(),{t:B}=w(),{BUILDINGS:V,TECHNOLOGIES:Ue}=ye(),H=s(()=>z.currentPlanet),U=c(!1),W=c(``),G=c(``),K=c(!1),q=c(``),J=c(null),We=[{key:`metal`},{key:`crystal`},{key:`deuterium`},{key:`darkMatter`}],Ge=s(()=>H.value?Object.values(C).filter(e=>{let t=V.value[e];return H.value.isMoon?t.moonOnly===!0:t.moonOnly!==!0}):[]),Ke=e=>{if(!z.currentPlanet||!m(z.currentPlanet,e,z.player.technologies,z.player.officers).valid)return!1;let t=oe(z.currentPlanet,e,z.player.officers);return z.currentPlanet.buildQueue.push(t),!0},Y=e=>ie(e),qe=e=>{if(!Z(e)){W.value=B(`common.requirementsNotMet`),G.value=Ye(e),U.value=!0;return}Ke(e)||(W.value=B(`buildingsView.upgradeFailed`),G.value=B(`buildingsView.upgradeFailedMessage`),U.value=!0)},X=e=>H.value?.buildings[e]||0,Z=e=>{if(!H.value)return!1;let t=V.value[e],n=b(t,X(e)+1);return!n||Object.keys(n).length===0?!0:le(H.value,z.player.technologies,n)},Je=e=>{if(!H.value)return B(`buildingsView.upgrade`);let t=V.value[e],n=X(e);return t.maxLevel!==void 0&&n>=t.maxLevel?B(`buildingsView.maxLevelReached`):H.value.buildQueue.length>0||Z(e)?B(`buildingsView.upgrade`):B(`buildingsView.requirementsNotMet`)},Ye=e=>{let t=V.value[e],n=b(t,X(e)+1);if(!n||!H.value)return``;let r=[];for(let[e,t]of Object.entries(n))if(Object.values(C).includes(e)){let n=e,i=H.value.buildings[n]||0,a=V.value[n]?.name||n,o=i>=t?`✓`:`✗`;r.push(`${o} ${a}: Lv ${t} (${B(`common.current`)}: Lv ${i})`)}else if(Object.values(de).includes(e)){let n=e,i=z.player.technologies[n]||0,a=Ue.value[n]?.name||n,o=i>=t?`✓`:`✗`;r.push(`${o} ${a}: Lv ${t} (${B(`common.current`)}: Lv ${i})`)}return r.join(`
|
|
||||||
`)},Xe=e=>{if(!H.value)return!1;let t=V.value[e],r=X(e);if(t.maxLevel!==void 0&&r>=t.maxLevel)return!1;let i=n(z.player.officers,Date.now()),a=h(H.value,i.additionalBuildQueue);if(H.value.buildQueue.filter(e=>e.type===`building`||e.type===`demolish`).length>=a||!m(H.value,e,z.player.technologies,z.player.officers).valid)return!1;let o=Q(e,r+1);return H.value.resources.metal>=o.metal&&H.value.resources.crystal>=o.crystal&&H.value.resources.deuterium>=o.deuterium&&H.value.resources.darkMatter>=o.darkMatter},Q=(e,t)=>ee(e,t),Ze=(e,t)=>{if(!H.value)return 0;let r=n(z.player.officers,Date.now()),i=H.value.buildings[C.RoboticsFactory]||0,a=H.value.buildings[C.NaniteFactory]||0;return ae(e,t,r.buildingSpeedBonus,i,a)},Qe=e=>{if(!z.currentPlanet||!re(z.currentPlanet,e,z.player.officers).valid)return!1;let t=se(z.currentPlanet,e,z.player.officers);return z.currentPlanet.buildQueue.push(t),!0},$e=e=>{let t=V.value[e].name,n=$(e);q.value=`${B(`buildingsView.confirmDemolishMessage`)}: ${t}
|
|
||||||
|
|
||||||
${B(`buildingsView.demolishRefund`)}:
|
|
||||||
${B(`resources.metal`)}: ${k(n.metal)}
|
|
||||||
${B(`resources.crystal`)}: ${k(n.crystal)}
|
|
||||||
${B(`resources.deuterium`)}: ${k(n.deuterium)}${n.darkMatter>0?`\n${B(`resources.darkMatter`)}: ${k(n.darkMatter)}`:``}`,J.value=e,K.value=!0},et=()=>{J.value&&(Qe(J.value)||(W.value=B(`buildingsView.demolishFailed`),G.value=B(`buildingsView.demolishFailedMessage`),U.value=!0)),K.value=!1,J.value=null},tt=e=>{if(!H.value||X(e)<=0)return!1;let t=n(z.player.officers,Date.now()),r=h(H.value,t.additionalBuildQueue);return!(H.value.buildQueue.filter(e=>e.type===`building`||e.type===`demolish`).length>=r)},$=e=>t(e,X(e));return(t,n)=>H.value?(v(),l(`div`,xe,[f(`h1`,Se,u(a(B)(`buildingsView.title`)),1),f(`div`,Ce,[f(`div`,we,[f(`div`,Te,[g(a(x),{size:16}),e(` `+u(a(B)(`buildingsView.spaceUsage`))+`: `,1)]),f(`div`,Ee,[f(`span`,{class:y(Y(H.value)>H.value.maxSpace?`text-destructive`:`text-primary`)},u(a(k)(Y(H.value))),3),n[2]||=f(`span`,{class:`text-muted-foreground mx-1`},`/`,-1),f(`span`,null,u(a(k)(H.value.maxSpace)),1)])]),f(`div`,De,[f(`div`,Oe,[f(`div`,{class:y([`h-full transition-all duration-300`,Y(H.value)>H.value.maxSpace?`bg-destructive`:`bg-primary`]),style:ne({width:`${Math.min(Y(H.value)/H.value.maxSpace*100,100)}%`})},null,6)])])]),f(`div`,ke,[(v(!0),l(o,null,_(Ge.value,t=>(v(),d(a(me),{key:t,class:`relative`},{default:i(()=>[g(be,{requirements:a(V)[t].requirements,currentLevel:X(t)},null,8,[`requirements`,`currentLevel`]),g(a(_e),null,{default:i(()=>[f(`div`,Ae,[f(`div`,je,[g(a(D),{class:`text-sm sm:text-base lg:text-lg cursor-pointer hover:text-primary transition-colors underline decoration-dotted underline-offset-4 order-2 sm:order-1`,onClick:e=>a(He).openBuilding(t,X(t))},{default:i(()=>[e(u(a(V)[t].name),1)]),_:2},1032,[`onClick`]),g(a(pe),{variant:`secondary`,class:`text-xs whitespace-nowrap self-start order-1 sm:order-2`},{default:i(()=>[e(` Lv `+u(X(t)),1)]),_:2},1024)])]),g(a(S),{class:`text-xs sm:text-sm`},{default:i(()=>[e(u(a(V)[t].description),1)]),_:2},1024)]),_:2},1024),g(a(ve),null,{default:i(()=>[f(`div`,Me,[f(`div`,R,[f(`p`,Ne,u(a(B)(`buildingsView.upgradeCost`))+`:`,1),f(`div`,Pe,[(v(),l(o,null,_(We,e=>r(f(`div`,{key:e.key,class:`flex items-center gap-1.5 sm:gap-2`},[g(T,{type:e.key,size:`sm`},null,8,[`type`]),f(`span`,Fe,u(a(B)(`resources.${e.key}`))+`:`,1),f(`span`,{class:y([`font-medium text-xs sm:text-sm`,a(ge)(H.value.resources[e.key],Q(t,X(t)+1)[e.key])])},u(a(k)(Q(t,X(t)+1)[e.key])),3)]),[[te,e.key!==`darkMatter`||Q(t,X(t)+1).darkMatter>0]])),64))])]),f(`div`,Ie,[f(`div`,Le,[g(a(ue),{size:14,class:`flex-shrink-0`}),f(`span`,null,u(a(N)(Ze(t,X(t)+1))),1)]),f(`div`,Re,[g(a(x),{size:14,class:`flex-shrink-0`}),f(`span`,null,u(a(V)[t].spaceUsage),1)])]),g(a(E),{onClick:e=>qe(t),disabled:!Xe(t),class:`w-full`},{default:i(()=>[e(u(Je(t)),1)]),_:2},1032,[`onClick`,`disabled`]),X(t)>0?(v(),d(a(E),{key:0,onClick:e=>$e(t),disabled:!tt(t),variant:`destructive`,class:`w-full`},{default:i(()=>[e(u(a(B)(`buildingsView.demolish`)),1)]),_:1},8,[`onClick`,`disabled`])):p(``,!0),X(t)>0?(v(),l(`div`,ze,[f(`p`,null,u(a(B)(`buildingsView.demolishRefund`))+`:`,1),f(`div`,Be,[f(`span`,null,u(a(k)($(t).metal))+` `+u(a(B)(`resources.metal`)),1),f(`span`,null,u(a(k)($(t).crystal))+` `+u(a(B)(`resources.crystal`)),1),f(`span`,null,u(a(k)($(t).deuterium))+` `+u(a(B)(`resources.deuterium`)),1),$(t).darkMatter>0?(v(),l(`span`,Ve,u(a(k)($(t).darkMatter))+` `+u(a(B)(`resources.darkMatter`)),1)):p(``,!0)])])):p(``,!0)])]),_:2},1024)]),_:2},1024))),128))]),g(a(L),{open:U.value,"onUpdate:open":n[0]||=e=>U.value=e},{default:i(()=>[g(a(I),null,{default:i(()=>[g(a(A),null,{default:i(()=>[g(a(F),null,{default:i(()=>[e(u(W.value),1)]),_:1}),g(a(M),{class:`whitespace-pre-line`},{default:i(()=>[e(u(G.value),1)]),_:1})]),_:1}),g(a(O),null,{default:i(()=>[g(a(j),null,{default:i(()=>[e(u(a(B)(`common.confirm`)),1)]),_:1})]),_:1})]),_:1})]),_:1},8,[`open`]),g(a(L),{open:K.value,"onUpdate:open":n[1]||=e=>K.value=e},{default:i(()=>[g(a(I),null,{default:i(()=>[g(a(A),null,{default:i(()=>[g(a(F),null,{default:i(()=>[e(u(a(B)(`buildingsView.confirmDemolish`)),1)]),_:1}),g(a(M),{class:`whitespace-pre-line`},{default:i(()=>[e(u(q.value),1)]),_:1})]),_:1}),g(a(O),null,{default:i(()=>[g(a(he),null,{default:i(()=>[e(u(a(B)(`common.cancel`)),1)]),_:1}),g(a(j),{onClick:et},{default:i(()=>[e(u(a(B)(`common.confirm`)),1)]),_:1})]),_:1})]),_:1})]),_:1},8,[`open`])])):p(``,!0)}});export{z as default};
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
import{Gn as e,Qt as t,_n as n,mn as r,qn as i,tn as a}from"./game-logic-Bi1l7y4K.js";import{G as o}from"./index-BT5w6et-.js";var s=a({__name:`CardDescription`,props:{class:{}},setup(a){let s=a;return(a,c)=>(r(),t(`p`,{"data-slot":`card-description`,class:i(e(o)(`text-muted-foreground text-sm`,s.class))},[n(a.$slots,`default`)],2))}});export{s as t};
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
import{$t as e,En as t,Gn as n,Jt as r,Ln as i,Qt as a,Xn as o,Yt as s,Zt as c,en as l,mn as u,tn as d,v as f}from"./game-logic-Bi1l7y4K.js";import{D as p}from"./vendor-icons-z9V6Jdbh.js";import{d as m,v as h}from"./game-config-CG6z6nnH.js";import{K as g,W as _,a as v,i as y,l as b,o as x,q as S,r as C,s as w,u as T}from"./index-BT5w6et-.js";import{t as E}from"./useGameConfig-b98LOtBY.js";var D={key:0,class:`absolute inset-0 z-10 bg-background/70 backdrop-blur-[2px] rounded-lg flex items-center justify-center`},O={class:`text-center p-4 space-y-2`},k={class:`flex justify-center`},A={class:`rounded-full bg-muted p-2`},j={class:`text-xs font-medium text-muted-foreground`},M=d({__name:`CardUnlockOverlay`,props:{requirements:{},currentLevel:{}},setup(d){let M=d,N=S(),{t:P}=g(),{BUILDINGS:F,TECHNOLOGIES:I}=E(),L=i(!1),R=i(``),z=i(``),B=r(()=>M.currentLevel!==void 0&&M.currentLevel>0||!M.requirements||!N.currentPlanet?!0:f(N.currentPlanet,N.player.technologies,M.requirements)),V=()=>{if(!M.requirements||!N.currentPlanet)return``;let e=[];for(let[t,n]of Object.entries(M.requirements))if(Object.values(m).includes(t)){let r=t,i=N.currentPlanet.buildings[r]||0,a=F.value[r]?.name||r,o=i>=n?`✓`:`✗`;e.push(`${o} ${a}: Lv ${n} (${P(`common.current`)}: Lv ${i})`)}else if(Object.values(h).includes(t)){let r=t,i=N.player.technologies[r]||0,a=I.value[r]?.name||r,o=i>=n?`✓`:`✗`;e.push(`${o} ${a}: Lv ${n} (${P(`common.current`)}: Lv ${i})`)}return e.join(`
|
|
||||||
`)},H=()=>{R.value=P(`common.requirementsNotMet`),z.value=V(),L.value=!0};return(r,i)=>B.value?c(``,!0):(u(),a(`div`,D,[s(`div`,O,[s(`div`,k,[s(`div`,A,[l(n(p),{size:20,class:`text-muted-foreground`})])]),s(`p`,j,o(n(P)(`common.locked`)),1),l(n(_),{variant:`outline`,size:`sm`,onClick:H,class:`text-xs`},{default:t(()=>[e(o(n(P)(`common.viewRequirements`)),1)]),_:1})]),l(n(T),{open:L.value,"onUpdate:open":i[0]||=e=>L.value=e},{default:t(()=>[l(n(w),null,{default:t(()=>[l(n(y),null,{default:t(()=>[l(n(C),null,{default:t(()=>[e(o(R.value),1)]),_:1}),l(n(x),{class:`whitespace-pre-line`},{default:t(()=>[e(o(z.value),1)]),_:1})]),_:1}),l(n(v),null,{default:t(()=>[l(n(b),null,{default:t(()=>[e(o(n(P)(`common.confirm`)),1)]),_:1})]),_:1})]),_:1})]),_:1},8,[`open`])]))}});export{M as t};
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,2 +0,0 @@
|
|||||||
import{$t as e,Dn as t,En as n,Gn as r,Gt as i,It as a,Jt as o,Ln as s,Qt as c,S as l,Vt as ee,Xn as u,Xt as te,Yt as d,Zt as ne,d as re,en as f,gn as p,mn as m,qn as ie,tn as ae,u as oe,v as h,y as g}from"./game-logic-Bi1l7y4K.js";import"./vendor-pinia-DqhKuBjp.js";import"./vendor-vue-router-1sDnnIWZ.js";import"./vendor-crypto-CQM8pryk.js";import"./game-i18n-Dr0JspcV.js";import"./vendor-others-DTUzJ7S-.js";import"./vendor-reka-ui-BEHIKScj.js";import"./vendor-utils-BlvnUqQX.js";import"./vendor-vueuse-CJcfYqoW.js";import"./vendor-icons-z9V6Jdbh.js";import{t as se}from"./CardDescription-BSLS07AU.js";import{d as _,v}from"./game-config-CG6z6nnH.js";import{D as ce,H as le,K as ue,N as de,W as y,_ as b,a as x,b as S,f as C,h as w,i as T,l as E,o as D,q as O,r as k,s as A,u as j,v as M,y as N}from"./index-BT5w6et-.js";import{t as P}from"./useGameConfig-b98LOtBY.js";import{t as F}from"./CardUnlockOverlay-DYfgGY6J.js";import{t as I}from"./UnlockRequirement-CoWPiUl8.js";var L={key:0,class:`container mx-auto p-4 sm:p-6`},R={class:`text-2xl sm:text-3xl font-bold mb-4 sm:mb-6`},fe={class:`grid grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4`},z={class:`mb-2`},B={class:`flex flex-col sm:flex-row sm:justify-between sm:items-start gap-2`},V={class:`space-y-2.5 sm:space-y-3`},pe={class:`text-xs sm:text-sm space-y-1.5 sm:space-y-2`},me={class:`text-muted-foreground mb-1 sm:mb-2`},he={class:`space-y-1 sm:space-y-1.5`},ge={class:`text-xs`},H=ae({__name:`ResearchView`,setup(ae){let H=O(),_e=ce(),{t:U}=ue(),{TECHNOLOGIES:W,BUILDINGS:ve}=P(),G=o(()=>H.currentPlanet),K=o(()=>H.player),q=s(!1),J=s(``),Y=s(``),ye=[{key:`metal`},{key:`crystal`},{key:`deuterium`},{key:`darkMatter`}],X=e=>{if(!H.currentPlanet||!re(H.currentPlanet,e,H.player.technologies,H.player.researchQueue).valid)return!1;let t=H.player.technologies[e]||0,{queueItem:n}=oe(H.currentPlanet,e,t,H.player.officers,H.player.technologies);return H.player.researchQueue.push(n),!0},Z=e=>{if(!G.value)return!1;let t=W.value[e],n=g(t,Q(e)+1);return!n||Object.keys(n).length===0?!0:h(G.value,H.player.technologies,n)},be=e=>{if(!G.value)return U(`researchView.research`);let t=W.value[e],n=Q(e);if(t.maxLevel!==void 0&&n>=t.maxLevel)return U(`researchView.maxLevelReached`);let r=l(H.player.technologies);return K.value.researchQueue.length>=r||Z(e)?U(`researchView.research`):U(`buildingsView.requirementsNotMet`)},xe=e=>{let t=W.value[e],n=g(t,Q(e)+1);if(!n||!G.value)return``;let r=[];for(let[e,t]of Object.entries(n))if(Object.values(_).includes(e)){let n=e,i=G.value.buildings[n]||0,a=ve.value[n]?.name||n,o=i>=t?`✓`:`✗`;r.push(`${o} ${a}: Lv ${t} (${U(`common.current`)}: Lv ${i})`)}else if(Object.values(v).includes(e)){let n=e,i=H.player.technologies[n]||0,a=W.value[n]?.name||n,o=i>=t?`✓`:`✗`;r.push(`${o} ${a}: Lv ${t} (${U(`common.current`)}: Lv ${i})`)}return r.join(`
|
|
||||||
`)},Se=e=>{if(!Z(e)){J.value=U(`common.requirementsNotMet`),Y.value=xe(e),q.value=!0;return}X(e)||(J.value=U(`researchView.researchFailed`),Y.value=U(`researchView.researchFailedMessage`),q.value=!0)},Q=e=>K.value.technologies[e]||0,Ce=e=>{if(!G.value)return!1;let t=W.value[e],n=Q(e);if(t.maxLevel!==void 0&&n>=t.maxLevel)return!1;let r=l(H.player.technologies);if(K.value.researchQueue.length>=r)return!1;let i=$(e,n+1);return h(G.value,H.player.technologies,t.requirements)&&G.value.resources.metal>=i.metal&&G.value.resources.crystal>=i.crystal&&G.value.resources.deuterium>=i.deuterium&&G.value.resources.darkMatter>=i.darkMatter},$=(e,t)=>a(e,t);return(a,o)=>G.value?(m(),c(`div`,L,[f(I,{"required-building":r(_).ResearchLab,"required-level":1},null,8,[`required-building`]),d(`h1`,R,u(r(U)(`researchView.title`)),1),d(`div`,fe,[(m(!0),c(i,null,p(Object.values(r(v)),a=>(m(),te(r(S),{key:a,class:`relative`},{default:n(()=>[f(F,{requirements:r(W)[a].requirements,currentLevel:Q(a)},null,8,[`requirements`,`currentLevel`]),f(r(M),null,{default:n(()=>[d(`div`,z,[d(`div`,B,[f(r(b),{class:`text-sm sm:text-base lg:text-lg cursor-pointer hover:text-primary transition-colors underline decoration-dotted underline-offset-4 order-2 sm:order-1`,onClick:e=>r(_e).openTechnology(a,Q(a))},{default:n(()=>[e(u(r(W)[a].name),1)]),_:2},1032,[`onClick`]),f(r(le),{variant:`secondary`,class:`text-xs whitespace-nowrap self-start order-1 sm:order-2`},{default:n(()=>[e(` Lv `+u(Q(a)),1)]),_:2},1024)])]),f(r(se),{class:`text-xs sm:text-sm`},{default:n(()=>[e(u(r(W)[a].description),1)]),_:2},1024)]),_:2},1024),f(r(N),null,{default:n(()=>[d(`div`,V,[d(`div`,pe,[d(`p`,me,u(r(U)(`researchView.researchCost`))+`:`,1),d(`div`,he,[(m(),c(i,null,p(ye,e=>t(d(`div`,{key:e.key,class:`flex items-center gap-1.5 sm:gap-2`},[f(de,{type:e.key,size:`sm`},null,8,[`type`]),d(`span`,ge,u(r(U)(`resources.${e.key}`))+`:`,1),d(`span`,{class:ie([`font-medium text-xs sm:text-sm`,r(w)(G.value.resources[e.key],$(a,Q(a)+1)[e.key])])},u(r(C)($(a,Q(a)+1)[e.key])),3)]),[[ee,e.key!==`darkMatter`||$(a,Q(a)+1).darkMatter>0]])),64))])]),f(r(y),{onClick:e=>Se(a),disabled:!Ce(a),class:`w-full`},{default:n(()=>[e(u(be(a)),1)]),_:2},1032,[`onClick`,`disabled`])])]),_:2},1024)]),_:2},1024))),128))]),f(r(j),{open:q.value,"onUpdate:open":o[0]||=e=>q.value=e},{default:n(()=>[f(r(A),null,{default:n(()=>[f(r(T),null,{default:n(()=>[f(r(k),null,{default:n(()=>[e(u(J.value),1)]),_:1}),f(r(D),{class:`whitespace-pre-line`},{default:n(()=>[e(u(Y.value),1)]),_:1})]),_:1}),f(r(x),null,{default:n(()=>[f(r(E),null,{default:n(()=>[e(u(r(U)(`common.confirm`)),1)]),_:1})]),_:1})]),_:1})]),_:1},8,[`open`])])):ne(``,!0)}});export{H as default};
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
|||||||
import{En as e,Gn as t,Jn as n,Xt as r,_n as i,ln as a,mn as o,rn as s,tn as c}from"./game-logic-Bi1l7y4K.js";import{c as l}from"./vendor-others-DTUzJ7S-.js";import{$ as u,c as d,et as f,l as p,s as m,u as h}from"./vendor-reka-ui-BEHIKScj.js";import{G as g}from"./index-BT5w6et-.js";var _=c({__name:`Tabs`,props:{defaultValue:{},orientation:{},dir:{},activationMode:{},modelValue:{},unmountOnHide:{type:Boolean},asChild:{type:Boolean},as:{},class:{}},emits:[`update:modelValue`],setup(c,{emit:d}){let f=c,p=d,m=u(l(f,`class`),p);return(c,l)=>(o(),r(t(h),a({"data-slot":`tabs`},t(m),{class:t(g)(`flex flex-col gap-2`,f.class)}),{default:e(e=>[i(c.$slots,`default`,n(s(e)))]),_:3},16,[`class`]))}}),v=c({__name:`TabsContent`,props:{value:{},forceMount:{type:Boolean},asChild:{type:Boolean},as:{},class:{}},setup(n){let s=n,c=l(s,`class`);return(n,l)=>(o(),r(t(p),a({"data-slot":`tabs-content`,class:t(g)(`flex-1 outline-none`,s.class)},t(c)),{default:e(()=>[i(n.$slots,`default`)]),_:3},16,[`class`]))}}),y=c({__name:`TabsList`,props:{loop:{type:Boolean},asChild:{type:Boolean},as:{},class:{},tabCount:{}},setup(n){let s=n,c=l(s,`class`,`tabCount`);return(l,u)=>(o(),r(t(d),a({"data-slot":`tabs-list`},t(c),{class:t(g)(`bg-muted text-muted-foreground inline-flex w-fit items-center justify-center rounded-lg p-[3px]`,n.tabCount&&n.tabCount>3?n.tabCount>6?`h-[85px] sm:h-9`:`h-[65px] sm:h-9`:`h-9`,s.class)}),{default:e(()=>[i(l.$slots,`default`)]),_:3},16,[`class`]))}}),b=c({__name:`TabsTrigger`,props:{value:{},disabled:{type:Boolean},asChild:{type:Boolean},as:{},class:{}},setup(n){let s=n,c=f(l(s,`class`));return(n,l)=>(o(),r(t(m),a({"data-slot":`tabs-trigger`,class:t(g)(`inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-all`,`text-muted-foreground hover:text-foreground`,`data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-md data-[state=active]:border-border`,`dark:data-[state=active]:bg-background dark:data-[state=active]:text-foreground dark:data-[state=active]:border-border dark:data-[state=active]:shadow-lg`,`focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring focus-visible:ring-[3px] focus-visible:outline-1`,`disabled:pointer-events-none disabled:opacity-50`,`[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,s.class)},t(c)),{default:e(()=>[i(n.$slots,`default`)]),_:3},16,[`class`]))}});export{_ as i,y as n,v as r,b as t};
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
import{En as e,Gn as t,Jn as n,Xt as r,_n as i,mn as a,rn as o,tn as s}from"./game-logic-Bi1l7y4K.js";import{a as c}from"./vendor-reka-ui-BEHIKScj.js";var l=s({__name:`TooltipProvider`,props:{delayDuration:{default:0},skipDelayDuration:{},disableHoverableContent:{type:Boolean},disableClosingTrigger:{type:Boolean},disabled:{type:Boolean},ignoreNonKeyboardFocus:{type:Boolean}},setup(s){let l=s;return(s,u)=>(a(),r(t(c),n(o(l)),{default:e(()=>[i(s.$slots,`default`)]),_:3},16))}});export{l as t};
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
import{$t as e,En as t,Gn as n,Jt as r,Qt as i,Xn as a,Yt as o,Zt as s,en as c,mn as l,tn as u}from"./game-logic-Bi1l7y4K.js";import{o as d}from"./vendor-vue-router-1sDnnIWZ.js";import{D as f,J as p}from"./vendor-icons-z9V6Jdbh.js";import{t as m}from"./CardDescription-BSLS07AU.js";import{H as h,K as g,W as _,_ as v,b as y,q as b,v as x,y as S}from"./index-BT5w6et-.js";import{t as C}from"./useGameConfig-b98LOtBY.js";var w={key:0,class:`fixed inset-0 z-50 bg-background/80 backdrop-blur-sm flex items-center justify-center p-4`},T={class:`flex justify-center mb-4`},E={class:`rounded-full bg-muted p-4`},D={class:`p-4 bg-muted rounded-lg space-y-2`},O={class:`text-sm font-medium text-center`},k={class:`flex items-center justify-center gap-2`},A={class:`text-base sm:text-lg font-bold`},j={key:0,class:`text-xs text-center text-muted-foreground`},M={class:`flex gap-2`},N=u({__name:`UnlockRequirement`,props:{requiredBuilding:{},requiredLevel:{}},setup(u){let N=u,P=d(),F=b(),{t:I}=g(),{BUILDINGS:L}=C(),R=r(()=>L.value[N.requiredBuilding]?.name||N.requiredBuilding),z=r(()=>F.currentPlanet&&F.currentPlanet.buildings[N.requiredBuilding]||0),B=r(()=>z.value>=N.requiredLevel),V=()=>{P.push(`/buildings`)};return(r,d)=>B.value?s(``,!0):(l(),i(`div`,w,[c(n(y),{class:`max-w-md w-full`},{default:t(()=>[c(n(x),{class:`text-center`},{default:t(()=>[o(`div`,T,[o(`div`,E,[c(n(f),{size:48,class:`text-muted-foreground`})])]),c(n(v),{class:`text-xl sm:text-2xl`},{default:t(()=>[e(a(n(I)(`common.featureLocked`)),1)]),_:1}),c(n(m),{class:`text-sm sm:text-base`},{default:t(()=>[e(a(n(I)(`common.unlockRequired`)),1)]),_:1})]),_:1}),c(n(S),{class:`space-y-4`},{default:t(()=>[o(`div`,D,[o(`p`,O,a(n(I)(`common.requiredBuilding`))+`:`,1),o(`div`,k,[o(`span`,A,a(R.value),1),c(n(h),{variant:`default`},{default:t(()=>[e(`Lv `+a(u.requiredLevel),1)]),_:1})]),z.value===void 0?s(``,!0):(l(),i(`p`,j,a(n(I)(`common.currentLevel`))+`: Lv `+a(z.value),1))]),o(`div`,M,[c(n(_),{onClick:V,class:`flex-1`},{default:t(()=>[c(n(p),{size:16,class:`mr-2`}),e(` `+a(n(I)(`common.goToBuildings`)),1)]),_:1})])]),_:1})]),_:1})]))}});export{N as t};
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 12 KiB |
@@ -1 +0,0 @@
|
|||||||
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),s=e=>{let n={};for(var r in e)t(n,r,{get:e[r],enumerable:!0});return n},c=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},l=(n,r,a)=>(a=n==null?{}:e(i(n)),c(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n)),u=(e=>typeof require<`u`?require:typeof Proxy<`u`?new Proxy(e,{get:(e,t)=>(typeof require<`u`?require:e)[t]}):e)(function(e){if(typeof require<`u`)return require.apply(this,arguments);throw Error('Calling `require` for "'+e+"\" in an environment that doesn't expose the `require` function.")});export{l as i,s as n,u as r,o as t};
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
import{Jt as e}from"./game-logic-Bi1l7y4K.js";import{_ as t,d as n,f as r,h as i,l as a,n as o,r as s,s as c,u as l,v as u}from"./game-config-CG6z6nnH.js";import{K as d}from"./index-BT5w6et-.js";const f=()=>{let{t:f}=d(),p={[n.MetalMine]:`metalMine`,[n.CrystalMine]:`crystalMine`,[n.DeuteriumSynthesizer]:`deuteriumSynthesizer`,[n.SolarPlant]:`solarPlant`,[n.FusionReactor]:`fusionReactor`,[n.RoboticsFactory]:`roboticsFactory`,[n.NaniteFactory]:`naniteFactory`,[n.Shipyard]:`shipyard`,[n.ResearchLab]:`researchLab`,[n.MetalStorage]:`metalStorage`,[n.CrystalStorage]:`crystalStorage`,[n.DeuteriumTank]:`deuteriumTank`,[n.DarkMatterCollector]:`darkMatterCollector`,[n.DarkMatterTank]:`darkMatterTank`,[n.MissileSilo]:`missileSilo`,[n.Terraformer]:`terraformer`,[n.LunarBase]:`lunarBase`,[n.SensorPhalanx]:`sensorPhalanx`,[n.JumpGate]:`jumpGate`,[n.PlanetDestroyerFactory]:`planetDestroyerFactory`},m={[t.LightFighter]:`lightFighter`,[t.HeavyFighter]:`heavyFighter`,[t.Cruiser]:`cruiser`,[t.Battleship]:`battleship`,[t.Battlecruiser]:`battlecruiser`,[t.Bomber]:`bomber`,[t.Destroyer]:`destroyer`,[t.SmallCargo]:`smallCargo`,[t.LargeCargo]:`largeCargo`,[t.ColonyShip]:`colonyShip`,[t.Recycler]:`recycler`,[t.EspionageProbe]:`espionageProbe`,[t.SolarSatellite]:`solarSatellite`,[t.DarkMatterHarvester]:`darkMatterHarvester`,[t.Deathstar]:`deathstar`},h={[r.RocketLauncher]:`rocketLauncher`,[r.LightLaser]:`lightLaser`,[r.HeavyLaser]:`heavyLaser`,[r.GaussCannon]:`gaussCannon`,[r.IonCannon]:`ionCannon`,[r.PlasmaTurret]:`plasmaTurret`,[r.SmallShieldDome]:`smallShieldDome`,[r.LargeShieldDome]:`largeShieldDome`,[r.AntiBallisticMissile]:`antiBallisticMissile`,[r.InterplanetaryMissile]:`interplanetaryMissile`,[r.PlanetaryShield]:`planetaryShield`},g={[u.EnergyTechnology]:`energyTechnology`,[u.LaserTechnology]:`laserTechnology`,[u.IonTechnology]:`ionTechnology`,[u.HyperspaceTechnology]:`hyperspaceTechnology`,[u.PlasmaTechnology]:`plasmaTechnology`,[u.ComputerTechnology]:`computerTechnology`,[u.EspionageTechnology]:`espionageTechnology`,[u.WeaponsTechnology]:`weaponsTechnology`,[u.ShieldingTechnology]:`shieldingTechnology`,[u.ArmourTechnology]:`armourTechnology`,[u.Astrophysics]:`astrophysics`,[u.GravitonTechnology]:`gravitonTechnology`,[u.CombustionDrive]:`combustionDrive`,[u.ImpulseDrive]:`impulseDrive`,[u.HyperspaceDrive]:`hyperspaceDrive`,[u.DarkMatterTechnology]:`darkMatterTechnology`,[u.TerraformingTechnology]:`terraformingTechnology`,[u.PlanetDestructionTech]:`planetDestructionTech`},_={[i.Commander]:`commander`,[i.Admiral]:`admiral`,[i.Engineer]:`engineer`,[i.Geologist]:`geologist`,[i.Technocrat]:`technocrat`,[i.DarkMatterSpecialist]:`darkMatterSpecialist`};return{BUILDINGS:e(()=>{let e={};for(let[t,n]of Object.entries(o)){let r=t,i=p[r];e[r]={...n,name:f(`buildings.${i}`),description:f(`buildingDescriptions.${i}`)}}return e}),SHIPS:e(()=>{let e={};for(let[t,n]of Object.entries(a)){let r=t,i=m[r];e[r]={...n,name:f(`ships.${i}`),description:f(`shipDescriptions.${i}`)}}return e}),DEFENSES:e(()=>{let e={};for(let[t,n]of Object.entries(s)){let r=t,i=h[r];e[r]={...n,name:f(`defenses.${i}`),description:f(`defenseDescriptions.${i}`)}}return e}),TECHNOLOGIES:e(()=>{let e={};for(let[t,n]of Object.entries(l)){let r=t,i=g[r];e[r]={...n,name:f(`technologies.${i}`),description:f(`technologyDescriptions.${i}`)}}return e}),OFFICERS:e(()=>{let e={};for(let[t,n]of Object.entries(c)){let r=t,i=_[r];e[r]={...n,name:f(`officers.${i}`),description:f(`officerDescriptions.${i}`)}}return e})}};export{f as t};
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
|||||||
import{Bn as e,Cn as t,Gn as n,Jt as r,Ln as i,Wn as a,an as o,fn as s,nn as c,un as l,wn as u}from"./game-logic-Bi1l7y4K.js";import{a as d,i as f,l as p,o as m,r as h,s as g,u as _}from"./vendor-others-DTUzJ7S-.js";var v=f?window:void 0,y=f?window.document:void 0;f&&window.navigator,f&&window.location;function b(e){let t=a(e);return t?.$el??t}function x(...e){let t=(e,t,n,r)=>(e.addEventListener(t,n,r),()=>e.removeEventListener(t,n,r)),i=r(()=>{let t=p(a(e[0])).filter(e=>e!=null);return t.every(e=>typeof e!=`string`)?t:void 0});return _(()=>[i.value?.map(e=>b(e))??[v].filter(e=>e!=null),p(a(i.value?e[1]:e[0])),p(n(i.value?e[2]:e[1])),a(i.value?e[3]:e[2])],([e,n,r,i],a,o)=>{if(!e?.length||!n?.length||!r?.length)return;let s=m(i)?{...i}:i,c=e.flatMap(e=>n.flatMap(n=>r.map(r=>t(e,n,r,s))));o(()=>{c.forEach(e=>e())})},{flush:`post`})}function S(){let t=e(!1),n=c();return n&&s(()=>{t.value=!0},n),t}function C(e){let t=S();return r(()=>(t.value,!!e()))}var w=Symbol(`vueuse-ssr-width`);function T(){let e=o()?h(w,null):null;return typeof e==`number`?e:void 0}function E(t,n={}){let{window:i=v,ssrWidth:o=T()}=n,s=C(()=>i&&`matchMedia`in i&&typeof i.matchMedia==`function`),c=e(typeof o==`number`),l=e(),d=e(!1);return u(()=>{if(c.value){c.value=!s.value,d.value=a(t).split(`,`).some(e=>{let t=e.includes(`not all`),n=e.match(/\(\s*min-width:\s*(-?\d+(?:\.\d*)?[a-z]+\s*)\)/),r=e.match(/\(\s*max-width:\s*(-?\d+(?:\.\d*)?[a-z]+\s*)\)/),i=!!(n||r);return n&&i&&(i=o>=g(n[1])),r&&i&&(i=o<=g(r[1])),t?!i:i});return}s.value&&(l.value=i.matchMedia(a(t)),d.value=l.value.matches)}),x(l,`change`,e=>{d.value=e.matches},{passive:!0}),r(()=>d.value)}function D(e){return JSON.parse(JSON.stringify(e))}function O(e,n,a,o={}){var s,u;let{clone:f=!1,passive:p=!1,eventName:m,deep:h=!1,defaultValue:g,shouldEmit:_}=o,v=c(),y=a||v?.emit||(v==null||(s=v.$emit)==null?void 0:s.bind(v))||(v==null||(u=v.proxy)==null||(u=u.$emit)==null?void 0:u.bind(v?.proxy)),b=m;n||=`modelValue`,b||=`update:${n.toString()}`;let x=e=>f?typeof f==`function`?f(e):D(e):e,S=()=>d(e[n])?x(e[n]):g,C=e=>{_?_(e)&&y(b,e):y(b,e)};if(p){let r=i(S()),a=!1;return t(()=>e[n],e=>{a||(a=!0,r.value=x(e),l(()=>a=!1))}),t(r,t=>{!a&&(t!==e[n]||h)&&C(t)},{deep:h}),r}else return r({get(){return S()},set(e){C(e)}})}export{O as i,x as n,E as r,y as t};
|
|
||||||
BIN
docs/favicon.ico
BIN
docs/favicon.ico
Binary file not shown.
|
Before Width: | Height: | Size: 227 KiB |
@@ -1,34 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-cmn-Hans">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover" />
|
|
||||||
<link rel="icon" type="image/svg+xml" href="./logo.svg" />
|
|
||||||
<title>OGame-Vue-Ts</title>
|
|
||||||
<script type="module" crossorigin src="./assets/index-BT5w6et-.js"></script>
|
|
||||||
<link rel="modulepreload" crossorigin href="./assets/game-config-CG6z6nnH.js">
|
|
||||||
<link rel="modulepreload" crossorigin href="./assets/rolldown-runtime-CIDIeb-o.js">
|
|
||||||
<link rel="modulepreload" crossorigin href="./assets/game-logic-Bi1l7y4K.js">
|
|
||||||
<link rel="modulepreload" crossorigin href="./assets/vendor-others-DTUzJ7S-.js">
|
|
||||||
<link rel="modulepreload" crossorigin href="./assets/vendor-reka-ui-BEHIKScj.js">
|
|
||||||
<link rel="modulepreload" crossorigin href="./assets/vendor-vueuse-CJcfYqoW.js">
|
|
||||||
<link rel="modulepreload" crossorigin href="./assets/vendor-crypto-CQM8pryk.js">
|
|
||||||
<link rel="modulepreload" crossorigin href="./assets/vendor-utils-BlvnUqQX.js">
|
|
||||||
<link rel="modulepreload" crossorigin href="./assets/vendor-icons-z9V6Jdbh.js">
|
|
||||||
<link rel="modulepreload" crossorigin href="./assets/vendor-pinia-DqhKuBjp.js">
|
|
||||||
<link rel="modulepreload" crossorigin href="./assets/vendor-vue-router-1sDnnIWZ.js">
|
|
||||||
<link rel="modulepreload" crossorigin href="./assets/game-i18n-Dr0JspcV.js">
|
|
||||||
<link rel="stylesheet" crossorigin href="./assets/vendor-others-BMPyaZWq.css">
|
|
||||||
<link rel="stylesheet" crossorigin href="./assets/index-D0T1QtIu.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="app"></div>
|
|
||||||
|
|
||||||
<!-- 统计勿删 -->
|
|
||||||
<script charset="UTF-8" id="LA_COLLECT" src="https://sdk.51.la/js-sdk-pro.min.js"></script>
|
|
||||||
<script>LA.init({ id: "L298GYqn6JhAO0VU", ck: "L298GYqn6JhAO0VU", autoTrack: true, hashMode: true })</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 12 KiB |
@@ -8,8 +8,8 @@
|
|||||||
"email": "1962257451@qq.com"
|
"email": "1962257451@qq.com"
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.2.0",
|
"version": "1.3.0",
|
||||||
"buildDate": "2025/12/15 08:22:52",
|
"buildDate": "2025/12/17 21:05:49",
|
||||||
"main": "dist-electron/main.js",
|
"main": "dist-electron/main.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"finalhandler": "^2.1.1",
|
"finalhandler": "^2.1.1",
|
||||||
"lucide-vue-next": "^0.556.0",
|
"lucide-vue-next": "^0.556.0",
|
||||||
|
"marked": "^17.0.1",
|
||||||
"pinia": "^3.0.4",
|
"pinia": "^3.0.4",
|
||||||
"pinia-plugin-persistedstate": "^4.7.1",
|
"pinia-plugin-persistedstate": "^4.7.1",
|
||||||
"reka-ui": "^2.6.1",
|
"reka-ui": "^2.6.1",
|
||||||
@@ -54,6 +55,7 @@
|
|||||||
"vite": "npm:rolldown-vite@7.2.5",
|
"vite": "npm:rolldown-vite@7.2.5",
|
||||||
"vite-plugin-electron": "^0.29.0",
|
"vite-plugin-electron": "^0.29.0",
|
||||||
"vite-plugin-electron-renderer": "^0.14.6",
|
"vite-plugin-electron-renderer": "^0.14.6",
|
||||||
|
"vite-plugin-pwa": "^1.2.0",
|
||||||
"vue-tsc": "^3.1.4"
|
"vue-tsc": "^3.1.4"
|
||||||
},
|
},
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
|
|||||||
2886
pnpm-lock.yaml
generated
2886
pnpm-lock.yaml
generated
@@ -38,6 +38,9 @@ importers:
|
|||||||
lucide-vue-next:
|
lucide-vue-next:
|
||||||
specifier: ^0.556.0
|
specifier: ^0.556.0
|
||||||
version: 0.556.0(vue@3.5.25(typescript@5.9.3))
|
version: 0.556.0(vue@3.5.25(typescript@5.9.3))
|
||||||
|
marked:
|
||||||
|
specifier: ^17.0.1
|
||||||
|
version: 17.0.1
|
||||||
pinia:
|
pinia:
|
||||||
specifier: ^3.0.4
|
specifier: ^3.0.4
|
||||||
version: 3.0.4(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3))
|
version: 3.0.4(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3))
|
||||||
@@ -108,6 +111,9 @@ importers:
|
|||||||
vite-plugin-electron-renderer:
|
vite-plugin-electron-renderer:
|
||||||
specifier: ^0.14.6
|
specifier: ^0.14.6
|
||||||
version: 0.14.6
|
version: 0.14.6
|
||||||
|
vite-plugin-pwa:
|
||||||
|
specifier: ^1.2.0
|
||||||
|
version: 1.2.0(@vite-pwa/assets-generator@1.0.2)(rolldown-vite@7.2.5(@types/node@24.10.2)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.44.1))(workbox-build@7.4.0)(workbox-window@7.4.0)
|
||||||
vue-tsc:
|
vue-tsc:
|
||||||
specifier: ^3.1.4
|
specifier: ^3.1.4
|
||||||
version: 3.1.8(typescript@5.9.3)
|
version: 3.1.8(typescript@5.9.3)
|
||||||
@@ -117,6 +123,12 @@ packages:
|
|||||||
7zip-bin@5.2.0:
|
7zip-bin@5.2.0:
|
||||||
resolution: {integrity: sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==}
|
resolution: {integrity: sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==}
|
||||||
|
|
||||||
|
'@apideck/better-ajv-errors@0.3.6':
|
||||||
|
resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
peerDependencies:
|
||||||
|
ajv: '>=8'
|
||||||
|
|
||||||
'@babel/code-frame@7.27.1':
|
'@babel/code-frame@7.27.1':
|
||||||
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
|
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
@@ -133,14 +145,39 @@ packages:
|
|||||||
resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==}
|
resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
|
'@babel/helper-annotate-as-pure@7.27.3':
|
||||||
|
resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
'@babel/helper-compilation-targets@7.27.2':
|
'@babel/helper-compilation-targets@7.27.2':
|
||||||
resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==}
|
resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
|
'@babel/helper-create-class-features-plugin@7.28.5':
|
||||||
|
resolution: {integrity: sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0
|
||||||
|
|
||||||
|
'@babel/helper-create-regexp-features-plugin@7.28.5':
|
||||||
|
resolution: {integrity: sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0
|
||||||
|
|
||||||
|
'@babel/helper-define-polyfill-provider@0.6.5':
|
||||||
|
resolution: {integrity: sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
|
||||||
|
|
||||||
'@babel/helper-globals@7.28.0':
|
'@babel/helper-globals@7.28.0':
|
||||||
resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==}
|
resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
|
'@babel/helper-member-expression-to-functions@7.28.5':
|
||||||
|
resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
'@babel/helper-module-imports@7.27.1':
|
'@babel/helper-module-imports@7.27.1':
|
||||||
resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==}
|
resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
@@ -151,10 +188,30 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@babel/core': ^7.0.0
|
'@babel/core': ^7.0.0
|
||||||
|
|
||||||
|
'@babel/helper-optimise-call-expression@7.27.1':
|
||||||
|
resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
'@babel/helper-plugin-utils@7.27.1':
|
'@babel/helper-plugin-utils@7.27.1':
|
||||||
resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==}
|
resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
|
'@babel/helper-remap-async-to-generator@7.27.1':
|
||||||
|
resolution: {integrity: sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0
|
||||||
|
|
||||||
|
'@babel/helper-replace-supers@7.27.1':
|
||||||
|
resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0
|
||||||
|
|
||||||
|
'@babel/helper-skip-transparent-expression-wrappers@7.27.1':
|
||||||
|
resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
'@babel/helper-string-parser@7.27.1':
|
'@babel/helper-string-parser@7.27.1':
|
||||||
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
|
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
@@ -167,6 +224,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==}
|
resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
|
'@babel/helper-wrap-function@7.28.3':
|
||||||
|
resolution: {integrity: sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
'@babel/helpers@7.28.4':
|
'@babel/helpers@7.28.4':
|
||||||
resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==}
|
resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
@@ -176,12 +237,381 @@ packages:
|
|||||||
engines: {node: '>=6.0.0'}
|
engines: {node: '>=6.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
'@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5':
|
||||||
|
resolution: {integrity: sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0
|
||||||
|
|
||||||
|
'@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1':
|
||||||
|
resolution: {integrity: sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0
|
||||||
|
|
||||||
|
'@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1':
|
||||||
|
resolution: {integrity: sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0
|
||||||
|
|
||||||
|
'@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1':
|
||||||
|
resolution: {integrity: sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.13.0
|
||||||
|
|
||||||
|
'@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3':
|
||||||
|
resolution: {integrity: sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0
|
||||||
|
|
||||||
|
'@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2':
|
||||||
|
resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-syntax-import-assertions@7.27.1':
|
||||||
|
resolution: {integrity: sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-syntax-import-attributes@7.27.1':
|
||||||
|
resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-syntax-unicode-sets-regex@7.18.6':
|
||||||
|
resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0
|
||||||
|
|
||||||
'@babel/plugin-transform-arrow-functions@7.27.1':
|
'@babel/plugin-transform-arrow-functions@7.27.1':
|
||||||
resolution: {integrity: sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==}
|
resolution: {integrity: sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-async-generator-functions@7.28.0':
|
||||||
|
resolution: {integrity: sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-async-to-generator@7.27.1':
|
||||||
|
resolution: {integrity: sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-block-scoped-functions@7.27.1':
|
||||||
|
resolution: {integrity: sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-block-scoping@7.28.5':
|
||||||
|
resolution: {integrity: sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-class-properties@7.27.1':
|
||||||
|
resolution: {integrity: sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-class-static-block@7.28.3':
|
||||||
|
resolution: {integrity: sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.12.0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-classes@7.28.4':
|
||||||
|
resolution: {integrity: sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-computed-properties@7.27.1':
|
||||||
|
resolution: {integrity: sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-destructuring@7.28.5':
|
||||||
|
resolution: {integrity: sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-dotall-regex@7.27.1':
|
||||||
|
resolution: {integrity: sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-duplicate-keys@7.27.1':
|
||||||
|
resolution: {integrity: sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1':
|
||||||
|
resolution: {integrity: sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-dynamic-import@7.27.1':
|
||||||
|
resolution: {integrity: sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-explicit-resource-management@7.28.0':
|
||||||
|
resolution: {integrity: sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-exponentiation-operator@7.28.5':
|
||||||
|
resolution: {integrity: sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-export-namespace-from@7.27.1':
|
||||||
|
resolution: {integrity: sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-for-of@7.27.1':
|
||||||
|
resolution: {integrity: sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-function-name@7.27.1':
|
||||||
|
resolution: {integrity: sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-json-strings@7.27.1':
|
||||||
|
resolution: {integrity: sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-literals@7.27.1':
|
||||||
|
resolution: {integrity: sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-logical-assignment-operators@7.28.5':
|
||||||
|
resolution: {integrity: sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-member-expression-literals@7.27.1':
|
||||||
|
resolution: {integrity: sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-modules-amd@7.27.1':
|
||||||
|
resolution: {integrity: sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-modules-commonjs@7.27.1':
|
||||||
|
resolution: {integrity: sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-modules-systemjs@7.28.5':
|
||||||
|
resolution: {integrity: sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-modules-umd@7.27.1':
|
||||||
|
resolution: {integrity: sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-named-capturing-groups-regex@7.27.1':
|
||||||
|
resolution: {integrity: sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-new-target@7.27.1':
|
||||||
|
resolution: {integrity: sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-nullish-coalescing-operator@7.27.1':
|
||||||
|
resolution: {integrity: sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-numeric-separator@7.27.1':
|
||||||
|
resolution: {integrity: sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-object-rest-spread@7.28.4':
|
||||||
|
resolution: {integrity: sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-object-super@7.27.1':
|
||||||
|
resolution: {integrity: sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-optional-catch-binding@7.27.1':
|
||||||
|
resolution: {integrity: sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-optional-chaining@7.28.5':
|
||||||
|
resolution: {integrity: sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-parameters@7.27.7':
|
||||||
|
resolution: {integrity: sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-private-methods@7.27.1':
|
||||||
|
resolution: {integrity: sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-private-property-in-object@7.27.1':
|
||||||
|
resolution: {integrity: sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-property-literals@7.27.1':
|
||||||
|
resolution: {integrity: sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-regenerator@7.28.4':
|
||||||
|
resolution: {integrity: sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-regexp-modifiers@7.27.1':
|
||||||
|
resolution: {integrity: sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-reserved-words@7.27.1':
|
||||||
|
resolution: {integrity: sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-shorthand-properties@7.27.1':
|
||||||
|
resolution: {integrity: sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-spread@7.27.1':
|
||||||
|
resolution: {integrity: sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-sticky-regex@7.27.1':
|
||||||
|
resolution: {integrity: sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-template-literals@7.27.1':
|
||||||
|
resolution: {integrity: sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-typeof-symbol@7.27.1':
|
||||||
|
resolution: {integrity: sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-unicode-escapes@7.27.1':
|
||||||
|
resolution: {integrity: sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-unicode-property-regex@7.27.1':
|
||||||
|
resolution: {integrity: sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-unicode-regex@7.27.1':
|
||||||
|
resolution: {integrity: sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/plugin-transform-unicode-sets-regex@7.27.1':
|
||||||
|
resolution: {integrity: sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0
|
||||||
|
|
||||||
|
'@babel/preset-env@7.28.5':
|
||||||
|
resolution: {integrity: sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/preset-modules@0.1.6-no-external-plugins':
|
||||||
|
resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0
|
||||||
|
|
||||||
|
'@babel/runtime@7.28.4':
|
||||||
|
resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
'@babel/template@7.27.2':
|
'@babel/template@7.27.2':
|
||||||
resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==}
|
resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
@@ -194,6 +624,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==}
|
resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
|
'@canvas/image-data@1.1.0':
|
||||||
|
resolution: {integrity: sha512-QdObRRjRbcXGmM1tmJ+MrHcaz1MftF2+W7YI+MsphnsCrmtyfS0d5qJbk0MeSbUeyM/jCb0hmnkXPsy026L7dA==}
|
||||||
|
|
||||||
'@develar/schema-utils@2.6.5':
|
'@develar/schema-utils@2.6.5':
|
||||||
resolution: {integrity: sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==}
|
resolution: {integrity: sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==}
|
||||||
engines: {node: '>= 8.9.0'}
|
engines: {node: '>= 8.9.0'}
|
||||||
@@ -425,6 +858,123 @@ packages:
|
|||||||
'@gar/promisify@1.1.3':
|
'@gar/promisify@1.1.3':
|
||||||
resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==}
|
resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==}
|
||||||
|
|
||||||
|
'@img/sharp-darwin-arm64@0.33.5':
|
||||||
|
resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==}
|
||||||
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@img/sharp-darwin-x64@0.33.5':
|
||||||
|
resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==}
|
||||||
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@img/sharp-libvips-darwin-arm64@1.0.4':
|
||||||
|
resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@img/sharp-libvips-darwin-x64@1.0.4':
|
||||||
|
resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-arm64@1.0.4':
|
||||||
|
resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-arm@1.0.5':
|
||||||
|
resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==}
|
||||||
|
cpu: [arm]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-s390x@1.0.4':
|
||||||
|
resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==}
|
||||||
|
cpu: [s390x]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-x64@1.0.4':
|
||||||
|
resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linuxmusl-arm64@1.0.4':
|
||||||
|
resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linuxmusl-x64@1.0.4':
|
||||||
|
resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
|
'@img/sharp-linux-arm64@0.33.5':
|
||||||
|
resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==}
|
||||||
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-linux-arm@0.33.5':
|
||||||
|
resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==}
|
||||||
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
|
cpu: [arm]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-linux-s390x@0.33.5':
|
||||||
|
resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==}
|
||||||
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
|
cpu: [s390x]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-linux-x64@0.33.5':
|
||||||
|
resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==}
|
||||||
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-linuxmusl-arm64@0.33.5':
|
||||||
|
resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==}
|
||||||
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
|
'@img/sharp-linuxmusl-x64@0.33.5':
|
||||||
|
resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==}
|
||||||
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
|
'@img/sharp-wasm32@0.33.5':
|
||||||
|
resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==}
|
||||||
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
|
cpu: [wasm32]
|
||||||
|
|
||||||
|
'@img/sharp-win32-ia32@0.33.5':
|
||||||
|
resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==}
|
||||||
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
|
cpu: [ia32]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
'@img/sharp-win32-x64@0.33.5':
|
||||||
|
resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==}
|
||||||
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
'@internationalized/date@3.10.0':
|
'@internationalized/date@3.10.0':
|
||||||
resolution: {integrity: sha512-oxDR/NTEJ1k+UFVQElaNIk65E/Z83HK1z1WI3lQyhTtnNg4R5oVXaPzK3jcpKG8UHKDVuDQHzn+wsxSz8RP3aw==}
|
resolution: {integrity: sha512-oxDR/NTEJ1k+UFVQElaNIk65E/Z83HK1z1WI3lQyhTtnNg4R5oVXaPzK3jcpKG8UHKDVuDQHzn+wsxSz8RP3aw==}
|
||||||
|
|
||||||
@@ -493,6 +1043,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
|
|
||||||
|
'@quansync/fs@1.0.0':
|
||||||
|
resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==}
|
||||||
|
|
||||||
'@rolldown/binding-android-arm64@1.0.0-beta.50':
|
'@rolldown/binding-android-arm64@1.0.0-beta.50':
|
||||||
resolution: {integrity: sha512-XlEkrOIHLyGT3avOgzfTFSjG+f+dZMw+/qd+Y3HLN86wlndrB/gSimrJCk4gOhr1XtRtEKfszpadI3Md4Z4/Ag==}
|
resolution: {integrity: sha512-XlEkrOIHLyGT3avOgzfTFSjG+f+dZMw+/qd+Y3HLN86wlndrB/gSimrJCk4gOhr1XtRtEKfszpadI3Md4Z4/Ag==}
|
||||||
engines: {node: ^20.19.0 || >=22.12.0}
|
engines: {node: ^20.19.0 || >=22.12.0}
|
||||||
@@ -583,10 +1136,62 @@ packages:
|
|||||||
'@rolldown/pluginutils@1.0.0-beta.50':
|
'@rolldown/pluginutils@1.0.0-beta.50':
|
||||||
resolution: {integrity: sha512-5e76wQiQVeL1ICOZVUg4LSOVYg9jyhGCin+icYozhsUzM+fHE7kddi1bdiE0jwVqTfkjba3jUFbEkoC9WkdvyA==}
|
resolution: {integrity: sha512-5e76wQiQVeL1ICOZVUg4LSOVYg9jyhGCin+icYozhsUzM+fHE7kddi1bdiE0jwVqTfkjba3jUFbEkoC9WkdvyA==}
|
||||||
|
|
||||||
|
'@rollup/plugin-babel@5.3.1':
|
||||||
|
resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==}
|
||||||
|
engines: {node: '>= 10.0.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0
|
||||||
|
'@types/babel__core': ^7.1.9
|
||||||
|
rollup: ^1.20.0||^2.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/babel__core':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@rollup/plugin-node-resolve@15.3.1':
|
||||||
|
resolution: {integrity: sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==}
|
||||||
|
engines: {node: '>=14.0.0'}
|
||||||
|
peerDependencies:
|
||||||
|
rollup: ^2.78.0||^3.0.0||^4.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
rollup:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@rollup/plugin-replace@2.4.2':
|
||||||
|
resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==}
|
||||||
|
peerDependencies:
|
||||||
|
rollup: ^1.20.0 || ^2.0.0
|
||||||
|
|
||||||
|
'@rollup/plugin-terser@0.4.4':
|
||||||
|
resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==}
|
||||||
|
engines: {node: '>=14.0.0'}
|
||||||
|
peerDependencies:
|
||||||
|
rollup: ^2.0.0||^3.0.0||^4.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
rollup:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@rollup/pluginutils@3.1.0':
|
||||||
|
resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==}
|
||||||
|
engines: {node: '>= 8.0.0'}
|
||||||
|
peerDependencies:
|
||||||
|
rollup: ^1.20.0||^2.0.0
|
||||||
|
|
||||||
|
'@rollup/pluginutils@5.3.0':
|
||||||
|
resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==}
|
||||||
|
engines: {node: '>=14.0.0'}
|
||||||
|
peerDependencies:
|
||||||
|
rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
rollup:
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@sindresorhus/is@4.6.0':
|
'@sindresorhus/is@4.6.0':
|
||||||
resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==}
|
resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
'@surma/rollup-plugin-off-main-thread@2.2.3':
|
||||||
|
resolution: {integrity: sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==}
|
||||||
|
|
||||||
'@swc/helpers@0.5.17':
|
'@swc/helpers@0.5.17':
|
||||||
resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==}
|
resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==}
|
||||||
|
|
||||||
@@ -722,6 +1327,12 @@ packages:
|
|||||||
'@types/debug@4.1.12':
|
'@types/debug@4.1.12':
|
||||||
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
|
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
|
||||||
|
|
||||||
|
'@types/estree@0.0.39':
|
||||||
|
resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==}
|
||||||
|
|
||||||
|
'@types/estree@1.0.8':
|
||||||
|
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
|
||||||
|
|
||||||
'@types/file-saver@2.0.7':
|
'@types/file-saver@2.0.7':
|
||||||
resolution: {integrity: sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==}
|
resolution: {integrity: sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==}
|
||||||
|
|
||||||
@@ -746,9 +1357,15 @@ packages:
|
|||||||
'@types/plist@3.0.5':
|
'@types/plist@3.0.5':
|
||||||
resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==}
|
resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==}
|
||||||
|
|
||||||
|
'@types/resolve@1.20.2':
|
||||||
|
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
|
||||||
|
|
||||||
'@types/responselike@1.0.3':
|
'@types/responselike@1.0.3':
|
||||||
resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==}
|
resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==}
|
||||||
|
|
||||||
|
'@types/trusted-types@2.0.7':
|
||||||
|
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
|
||||||
|
|
||||||
'@types/verror@1.10.11':
|
'@types/verror@1.10.11':
|
||||||
resolution: {integrity: sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==}
|
resolution: {integrity: sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==}
|
||||||
|
|
||||||
@@ -758,6 +1375,11 @@ packages:
|
|||||||
'@types/yauzl@2.10.3':
|
'@types/yauzl@2.10.3':
|
||||||
resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
|
resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
|
||||||
|
|
||||||
|
'@vite-pwa/assets-generator@1.0.2':
|
||||||
|
resolution: {integrity: sha512-MCbrb508JZHqe7bUibmZj/lyojdhLRnfkmyXnkrCM2zVrjTgL89U8UEfInpKTvPeTnxsw2hmyZxnhsdNR6yhwg==}
|
||||||
|
engines: {node: '>=16.14.0'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
'@vitejs/plugin-vue@6.0.2':
|
'@vitejs/plugin-vue@6.0.2':
|
||||||
resolution: {integrity: sha512-iHmwV3QcVGGvSC1BG5bZ4z6iwa1SOpAPWmnjOErd4Ske+lZua5K9TtAVdx0gMBClJ28DViCbSmZitjWZsWO3LA==}
|
resolution: {integrity: sha512-iHmwV3QcVGGvSC1BG5bZ4z6iwa1SOpAPWmnjOErd4Ske+lZua5K9TtAVdx0gMBClJ28DViCbSmZitjWZsWO3LA==}
|
||||||
engines: {node: ^20.19.0 || >=22.12.0}
|
engines: {node: ^20.19.0 || >=22.12.0}
|
||||||
@@ -892,6 +1514,9 @@ packages:
|
|||||||
ajv@6.12.6:
|
ajv@6.12.6:
|
||||||
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
|
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
|
||||||
|
|
||||||
|
ajv@8.17.1:
|
||||||
|
resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==}
|
||||||
|
|
||||||
alien-signals@3.1.1:
|
alien-signals@3.1.1:
|
||||||
resolution: {integrity: sha512-ogkIWbVrLwKtHY6oOAXaYkAxP+cTH7V5FZ5+Tm4NZFd8VDZ6uNMDrfzqctTZ42eTMCSR3ne3otpcxmqSnFfPYA==}
|
resolution: {integrity: sha512-ogkIWbVrLwKtHY6oOAXaYkAxP+cTH7V5FZ5+Tm4NZFd8VDZ6uNMDrfzqctTZ42eTMCSR3ne3otpcxmqSnFfPYA==}
|
||||||
|
|
||||||
@@ -928,6 +1553,14 @@ packages:
|
|||||||
resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==}
|
resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
array-buffer-byte-length@1.0.2:
|
||||||
|
resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
arraybuffer.prototype.slice@1.0.4:
|
||||||
|
resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
assert-plus@1.0.0:
|
assert-plus@1.0.0:
|
||||||
resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==}
|
resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==}
|
||||||
engines: {node: '>=0.8'}
|
engines: {node: '>=0.8'}
|
||||||
@@ -940,6 +1573,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==}
|
resolution: {integrity: sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==}
|
||||||
engines: {node: '>=0.12.0'}
|
engines: {node: '>=0.12.0'}
|
||||||
|
|
||||||
|
async-function@1.0.0:
|
||||||
|
resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
async@3.2.6:
|
async@3.2.6:
|
||||||
resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==}
|
resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==}
|
||||||
|
|
||||||
@@ -950,6 +1587,25 @@ packages:
|
|||||||
resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
|
resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
|
||||||
engines: {node: '>= 4.0.0'}
|
engines: {node: '>= 4.0.0'}
|
||||||
|
|
||||||
|
available-typed-arrays@1.0.7:
|
||||||
|
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
babel-plugin-polyfill-corejs2@0.4.14:
|
||||||
|
resolution: {integrity: sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
|
||||||
|
|
||||||
|
babel-plugin-polyfill-corejs3@0.13.0:
|
||||||
|
resolution: {integrity: sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
|
||||||
|
|
||||||
|
babel-plugin-polyfill-regenerator@0.6.5:
|
||||||
|
resolution: {integrity: sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
|
||||||
|
|
||||||
balanced-match@1.0.2:
|
balanced-match@1.0.2:
|
||||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||||
|
|
||||||
@@ -1017,6 +1673,14 @@ packages:
|
|||||||
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
|
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
call-bind@1.0.8:
|
||||||
|
resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
call-bound@1.0.4:
|
||||||
|
resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
caniuse-lite@1.0.30001760:
|
caniuse-lite@1.0.30001760:
|
||||||
resolution: {integrity: sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==}
|
resolution: {integrity: sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==}
|
||||||
|
|
||||||
@@ -1076,6 +1740,16 @@ packages:
|
|||||||
color-name@1.1.4:
|
color-name@1.1.4:
|
||||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||||
|
|
||||||
|
color-string@1.9.1:
|
||||||
|
resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
|
||||||
|
|
||||||
|
color@4.2.3:
|
||||||
|
resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
|
||||||
|
engines: {node: '>=12.5.0'}
|
||||||
|
|
||||||
|
colorette@2.0.20:
|
||||||
|
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
|
||||||
|
|
||||||
combined-stream@1.0.8:
|
combined-stream@1.0.8:
|
||||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
@@ -1091,6 +1765,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==}
|
resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==}
|
||||||
engines: {node: ^12.20.0 || >=14}
|
engines: {node: ^12.20.0 || >=14}
|
||||||
|
|
||||||
|
common-tags@1.8.2:
|
||||||
|
resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==}
|
||||||
|
engines: {node: '>=4.0.0'}
|
||||||
|
|
||||||
compare-version@0.1.2:
|
compare-version@0.1.2:
|
||||||
resolution: {integrity: sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==}
|
resolution: {integrity: sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -1101,6 +1779,10 @@ packages:
|
|||||||
config-file-ts@0.2.8-rc1:
|
config-file-ts@0.2.8-rc1:
|
||||||
resolution: {integrity: sha512-GtNECbVI82bT4RiDIzBSVuTKoSHufnU7Ce7/42bkWZJZFLjmDF2WBpVsvRkhKCfKBnTBb3qZrBwPpFBU/Myvhg==}
|
resolution: {integrity: sha512-GtNECbVI82bT4RiDIzBSVuTKoSHufnU7Ce7/42bkWZJZFLjmDF2WBpVsvRkhKCfKBnTBb3qZrBwPpFBU/Myvhg==}
|
||||||
|
|
||||||
|
consola@3.4.2:
|
||||||
|
resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
|
||||||
|
engines: {node: ^14.18.0 || >=16.10.0}
|
||||||
|
|
||||||
convert-source-map@2.0.0:
|
convert-source-map@2.0.0:
|
||||||
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
|
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
|
||||||
|
|
||||||
@@ -1108,6 +1790,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==}
|
resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
core-js-compat@3.47.0:
|
||||||
|
resolution: {integrity: sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==}
|
||||||
|
|
||||||
core-util-is@1.0.2:
|
core-util-is@1.0.2:
|
||||||
resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==}
|
resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==}
|
||||||
|
|
||||||
@@ -1129,9 +1814,25 @@ packages:
|
|||||||
crypto-js@4.2.0:
|
crypto-js@4.2.0:
|
||||||
resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==}
|
resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==}
|
||||||
|
|
||||||
|
crypto-random-string@2.0.0:
|
||||||
|
resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
csstype@3.2.3:
|
csstype@3.2.3:
|
||||||
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
|
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
|
||||||
|
|
||||||
|
data-view-buffer@1.0.2:
|
||||||
|
resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
data-view-byte-length@1.0.2:
|
||||||
|
resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
data-view-byte-offset@1.0.1:
|
||||||
|
resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
debug@4.4.3:
|
debug@4.4.3:
|
||||||
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
|
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
|
||||||
engines: {node: '>=6.0'}
|
engines: {node: '>=6.0'}
|
||||||
@@ -1141,10 +1842,22 @@ packages:
|
|||||||
supports-color:
|
supports-color:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
decode-bmp@0.2.1:
|
||||||
|
resolution: {integrity: sha512-NiOaGe+GN0KJqi2STf24hfMkFitDUaIoUU3eKvP/wAbLe8o6FuW5n/x7MHPR0HKvBokp6MQY/j7w8lewEeVCIA==}
|
||||||
|
engines: {node: '>=8.6.0'}
|
||||||
|
|
||||||
|
decode-ico@0.4.1:
|
||||||
|
resolution: {integrity: sha512-69NZfbKIzux1vBOd31al3XnMnH+2mqDhEgLdpygErm4d60N+UwA5Sq5WFjmEDQzumgB9fElojGwWG0vybVfFmA==}
|
||||||
|
engines: {node: '>=8.6'}
|
||||||
|
|
||||||
decompress-response@6.0.0:
|
decompress-response@6.0.0:
|
||||||
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
|
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
deepmerge@4.3.1:
|
||||||
|
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
defaults@1.0.4:
|
defaults@1.0.4:
|
||||||
resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==}
|
resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==}
|
||||||
|
|
||||||
@@ -1278,6 +1991,10 @@ packages:
|
|||||||
err-code@2.0.3:
|
err-code@2.0.3:
|
||||||
resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==}
|
resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==}
|
||||||
|
|
||||||
|
es-abstract@1.24.1:
|
||||||
|
resolution: {integrity: sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
es-define-property@1.0.1:
|
es-define-property@1.0.1:
|
||||||
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
|
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -1294,6 +2011,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
|
resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
es-to-primitive@1.3.0:
|
||||||
|
resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
es6-error@4.1.1:
|
es6-error@4.1.1:
|
||||||
resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==}
|
resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==}
|
||||||
|
|
||||||
@@ -1313,9 +2034,16 @@ packages:
|
|||||||
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
|
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
estree-walker@1.0.1:
|
||||||
|
resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==}
|
||||||
|
|
||||||
estree-walker@2.0.2:
|
estree-walker@2.0.2:
|
||||||
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
|
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
|
||||||
|
|
||||||
|
esutils@2.0.3:
|
||||||
|
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
etag@1.8.1:
|
etag@1.8.1:
|
||||||
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
|
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
@@ -1338,6 +2066,9 @@ packages:
|
|||||||
fast-json-stable-stringify@2.1.0:
|
fast-json-stable-stringify@2.1.0:
|
||||||
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
|
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
|
||||||
|
|
||||||
|
fast-uri@3.1.0:
|
||||||
|
resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==}
|
||||||
|
|
||||||
fd-slicer@1.1.0:
|
fd-slicer@1.1.0:
|
||||||
resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==}
|
resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==}
|
||||||
|
|
||||||
@@ -1360,6 +2091,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==}
|
resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==}
|
||||||
engines: {node: '>= 18.0.0'}
|
engines: {node: '>= 18.0.0'}
|
||||||
|
|
||||||
|
for-each@0.3.5:
|
||||||
|
resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
foreground-child@3.3.1:
|
foreground-child@3.3.1:
|
||||||
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
|
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
@@ -1407,6 +2142,17 @@ packages:
|
|||||||
function-bind@1.1.2:
|
function-bind@1.1.2:
|
||||||
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
|
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
|
||||||
|
|
||||||
|
function.prototype.name@1.1.8:
|
||||||
|
resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
functions-have-names@1.2.3:
|
||||||
|
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
|
||||||
|
|
||||||
|
generator-function@2.0.1:
|
||||||
|
resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
gensync@1.0.0-beta.2:
|
gensync@1.0.0-beta.2:
|
||||||
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
|
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
@@ -1419,6 +2165,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
|
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
get-own-enumerable-property-symbols@3.0.2:
|
||||||
|
resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==}
|
||||||
|
|
||||||
get-proto@1.0.1:
|
get-proto@1.0.1:
|
||||||
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
|
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -1427,10 +2176,19 @@ packages:
|
|||||||
resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
|
resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
get-symbol-description@1.1.0:
|
||||||
|
resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
glob@10.5.0:
|
glob@10.5.0:
|
||||||
resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==}
|
resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
glob@11.1.0:
|
||||||
|
resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==}
|
||||||
|
engines: {node: 20 || >=22}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
glob@7.2.3:
|
glob@7.2.3:
|
||||||
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
|
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
|
||||||
deprecated: Glob versions prior to v9 are no longer supported
|
deprecated: Glob versions prior to v9 are no longer supported
|
||||||
@@ -1459,6 +2217,10 @@ packages:
|
|||||||
graceful-fs@4.2.11:
|
graceful-fs@4.2.11:
|
||||||
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
||||||
|
|
||||||
|
has-bigints@1.1.0:
|
||||||
|
resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
has-flag@4.0.0:
|
has-flag@4.0.0:
|
||||||
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -1466,6 +2228,10 @@ packages:
|
|||||||
has-property-descriptors@1.0.2:
|
has-property-descriptors@1.0.2:
|
||||||
resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
|
resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
|
||||||
|
|
||||||
|
has-proto@1.2.0:
|
||||||
|
resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
has-symbols@1.1.0:
|
has-symbols@1.1.0:
|
||||||
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
|
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -1515,6 +2281,9 @@ packages:
|
|||||||
humanize-ms@1.2.1:
|
humanize-ms@1.2.1:
|
||||||
resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==}
|
resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==}
|
||||||
|
|
||||||
|
ico-endec@0.1.6:
|
||||||
|
resolution: {integrity: sha512-ZdLU38ZoED3g1j3iEyzcQj+wAkY2xfWNkymszfJPoxucIUhK7NayQ+/C4Kv0nDFMIsbtbEHldv3V8PU494/ueQ==}
|
||||||
|
|
||||||
iconv-corefoundation@1.1.7:
|
iconv-corefoundation@1.1.7:
|
||||||
resolution: {integrity: sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==}
|
resolution: {integrity: sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==}
|
||||||
engines: {node: ^8.11.2 || >=10}
|
engines: {node: ^8.11.2 || >=10}
|
||||||
@@ -1524,6 +2293,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
|
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
idb@7.1.1:
|
||||||
|
resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==}
|
||||||
|
|
||||||
ieee754@1.2.1:
|
ieee754@1.2.1:
|
||||||
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
|
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
|
||||||
|
|
||||||
@@ -1545,18 +2317,65 @@ packages:
|
|||||||
inherits@2.0.4:
|
inherits@2.0.4:
|
||||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||||
|
|
||||||
|
internal-slot@1.1.0:
|
||||||
|
resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
ip-address@10.1.0:
|
ip-address@10.1.0:
|
||||||
resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==}
|
resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==}
|
||||||
engines: {node: '>= 12'}
|
engines: {node: '>= 12'}
|
||||||
|
|
||||||
|
is-array-buffer@3.0.5:
|
||||||
|
resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
is-arrayish@0.3.4:
|
||||||
|
resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==}
|
||||||
|
|
||||||
|
is-async-function@2.1.1:
|
||||||
|
resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
is-bigint@1.1.0:
|
||||||
|
resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
is-boolean-object@1.2.2:
|
||||||
|
resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
is-callable@1.2.7:
|
||||||
|
resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
is-ci@3.0.1:
|
is-ci@3.0.1:
|
||||||
resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==}
|
resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
is-core-module@2.16.1:
|
||||||
|
resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
is-data-view@1.0.2:
|
||||||
|
resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
is-date-object@1.1.0:
|
||||||
|
resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
is-finalizationregistry@1.1.1:
|
||||||
|
resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
is-fullwidth-code-point@3.0.0:
|
is-fullwidth-code-point@3.0.0:
|
||||||
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
|
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
is-generator-function@1.1.2:
|
||||||
|
resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
is-interactive@1.0.0:
|
is-interactive@1.0.0:
|
||||||
resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==}
|
resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -1564,14 +2383,80 @@ packages:
|
|||||||
is-lambda@1.0.1:
|
is-lambda@1.0.1:
|
||||||
resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==}
|
resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==}
|
||||||
|
|
||||||
|
is-map@2.0.3:
|
||||||
|
resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
is-module@1.0.0:
|
||||||
|
resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==}
|
||||||
|
|
||||||
|
is-negative-zero@2.0.3:
|
||||||
|
resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
is-number-object@1.1.1:
|
||||||
|
resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
is-obj@1.0.1:
|
||||||
|
resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
is-regex@1.2.1:
|
||||||
|
resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
is-regexp@1.0.0:
|
||||||
|
resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
is-set@2.0.3:
|
||||||
|
resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
is-shared-array-buffer@1.0.4:
|
||||||
|
resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
is-stream@2.0.1:
|
||||||
|
resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
is-string@1.1.1:
|
||||||
|
resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
is-symbol@1.1.1:
|
||||||
|
resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
is-typed-array@1.1.15:
|
||||||
|
resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
is-unicode-supported@0.1.0:
|
is-unicode-supported@0.1.0:
|
||||||
resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==}
|
resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
is-weakmap@2.0.2:
|
||||||
|
resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
is-weakref@1.1.1:
|
||||||
|
resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
is-weakset@2.0.4:
|
||||||
|
resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
is-what@5.5.0:
|
is-what@5.5.0:
|
||||||
resolution: {integrity: sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==}
|
resolution: {integrity: sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
isarray@2.0.5:
|
||||||
|
resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
|
||||||
|
|
||||||
isbinaryfile@4.0.10:
|
isbinaryfile@4.0.10:
|
||||||
resolution: {integrity: sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==}
|
resolution: {integrity: sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==}
|
||||||
engines: {node: '>= 8.0.0'}
|
engines: {node: '>= 8.0.0'}
|
||||||
@@ -1586,6 +2471,10 @@ packages:
|
|||||||
jackspeak@3.4.3:
|
jackspeak@3.4.3:
|
||||||
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
|
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
|
||||||
|
|
||||||
|
jackspeak@4.1.1:
|
||||||
|
resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==}
|
||||||
|
engines: {node: 20 || >=22}
|
||||||
|
|
||||||
jake@10.9.4:
|
jake@10.9.4:
|
||||||
resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==}
|
resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -1613,6 +2502,12 @@ packages:
|
|||||||
json-schema-traverse@0.4.1:
|
json-schema-traverse@0.4.1:
|
||||||
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
|
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
|
||||||
|
|
||||||
|
json-schema-traverse@1.0.0:
|
||||||
|
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
|
||||||
|
|
||||||
|
json-schema@0.4.0:
|
||||||
|
resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==}
|
||||||
|
|
||||||
json-stringify-safe@5.0.1:
|
json-stringify-safe@5.0.1:
|
||||||
resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==}
|
resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==}
|
||||||
|
|
||||||
@@ -1627,12 +2522,20 @@ packages:
|
|||||||
jsonfile@6.2.0:
|
jsonfile@6.2.0:
|
||||||
resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==}
|
resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==}
|
||||||
|
|
||||||
|
jsonpointer@5.0.1:
|
||||||
|
resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
keyv@4.5.4:
|
keyv@4.5.4:
|
||||||
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
|
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
|
||||||
|
|
||||||
lazy-val@1.0.5:
|
lazy-val@1.0.5:
|
||||||
resolution: {integrity: sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==}
|
resolution: {integrity: sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==}
|
||||||
|
|
||||||
|
leven@3.1.0:
|
||||||
|
resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
lightningcss-android-arm64@1.30.2:
|
lightningcss-android-arm64@1.30.2:
|
||||||
resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==}
|
resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==}
|
||||||
engines: {node: '>= 12.0.0'}
|
engines: {node: '>= 12.0.0'}
|
||||||
@@ -1707,6 +2610,12 @@ packages:
|
|||||||
resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==}
|
resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==}
|
||||||
engines: {node: '>= 12.0.0'}
|
engines: {node: '>= 12.0.0'}
|
||||||
|
|
||||||
|
lodash.debounce@4.0.8:
|
||||||
|
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
|
||||||
|
|
||||||
|
lodash.sortby@4.7.0:
|
||||||
|
resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==}
|
||||||
|
|
||||||
lodash@4.17.21:
|
lodash@4.17.21:
|
||||||
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
|
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
|
||||||
|
|
||||||
@@ -1721,6 +2630,10 @@ packages:
|
|||||||
lru-cache@10.4.3:
|
lru-cache@10.4.3:
|
||||||
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
|
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
|
||||||
|
|
||||||
|
lru-cache@11.2.4:
|
||||||
|
resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==}
|
||||||
|
engines: {node: 20 || >=22}
|
||||||
|
|
||||||
lru-cache@5.1.1:
|
lru-cache@5.1.1:
|
||||||
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
|
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
|
||||||
|
|
||||||
@@ -1737,6 +2650,9 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
vue: '>=3.0.1'
|
vue: '>=3.0.1'
|
||||||
|
|
||||||
|
magic-string@0.25.9:
|
||||||
|
resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
|
||||||
|
|
||||||
magic-string@0.30.21:
|
magic-string@0.30.21:
|
||||||
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
||||||
|
|
||||||
@@ -1744,6 +2660,11 @@ packages:
|
|||||||
resolution: {integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==}
|
resolution: {integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==}
|
||||||
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
||||||
|
|
||||||
|
marked@17.0.1:
|
||||||
|
resolution: {integrity: sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg==}
|
||||||
|
engines: {node: '>= 20'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
matcher@3.0.0:
|
matcher@3.0.0:
|
||||||
resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==}
|
resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -1888,10 +2809,18 @@ packages:
|
|||||||
resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==}
|
resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
object-inspect@1.13.4:
|
||||||
|
resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
object-keys@1.1.1:
|
object-keys@1.1.1:
|
||||||
resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
|
resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
object.assign@4.1.7:
|
||||||
|
resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
ohash@2.0.11:
|
ohash@2.0.11:
|
||||||
resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==}
|
resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==}
|
||||||
|
|
||||||
@@ -1910,6 +2839,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==}
|
resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
own-keys@1.0.1:
|
||||||
|
resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
p-cancelable@2.1.1:
|
p-cancelable@2.1.1:
|
||||||
resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==}
|
resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -1940,10 +2873,17 @@ packages:
|
|||||||
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
|
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
path-parse@1.0.7:
|
||||||
|
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
|
||||||
|
|
||||||
path-scurry@1.11.1:
|
path-scurry@1.11.1:
|
||||||
resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
|
resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
|
||||||
engines: {node: '>=16 || 14 >=14.18'}
|
engines: {node: '>=16 || 14 >=14.18'}
|
||||||
|
|
||||||
|
path-scurry@2.0.1:
|
||||||
|
resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==}
|
||||||
|
engines: {node: 20 || >=22}
|
||||||
|
|
||||||
pe-library@0.4.1:
|
pe-library@0.4.1:
|
||||||
resolution: {integrity: sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==}
|
resolution: {integrity: sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==}
|
||||||
engines: {node: '>=12', npm: '>=6'}
|
engines: {node: '>=12', npm: '>=6'}
|
||||||
@@ -1957,6 +2897,10 @@ packages:
|
|||||||
picocolors@1.1.1:
|
picocolors@1.1.1:
|
||||||
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
||||||
|
|
||||||
|
picomatch@2.3.1:
|
||||||
|
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
|
||||||
|
engines: {node: '>=8.6'}
|
||||||
|
|
||||||
picomatch@4.0.3:
|
picomatch@4.0.3:
|
||||||
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
|
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@@ -1988,6 +2932,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==}
|
resolution: {integrity: sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==}
|
||||||
engines: {node: '>=10.4.0'}
|
engines: {node: '>=10.4.0'}
|
||||||
|
|
||||||
|
possible-typed-array-names@1.1.0:
|
||||||
|
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
postcss@8.5.6:
|
postcss@8.5.6:
|
||||||
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
|
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
|
||||||
engines: {node: ^10 || ^12 || >=14}
|
engines: {node: ^10 || ^12 || >=14}
|
||||||
@@ -1997,6 +2945,14 @@ packages:
|
|||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
pretty-bytes@5.6.0:
|
||||||
|
resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
|
pretty-bytes@6.1.1:
|
||||||
|
resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==}
|
||||||
|
engines: {node: ^14.13.1 || >=16.0.0}
|
||||||
|
|
||||||
proc-log@2.0.1:
|
proc-log@2.0.1:
|
||||||
resolution: {integrity: sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==}
|
resolution: {integrity: sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==}
|
||||||
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
||||||
@@ -2024,10 +2980,16 @@ packages:
|
|||||||
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
|
quansync@1.0.0:
|
||||||
|
resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==}
|
||||||
|
|
||||||
quick-lru@5.1.1:
|
quick-lru@5.1.1:
|
||||||
resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
|
resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
randombytes@2.1.0:
|
||||||
|
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
|
||||||
|
|
||||||
range-parser@1.2.1:
|
range-parser@1.2.1:
|
||||||
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
|
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
@@ -2040,6 +3002,32 @@ packages:
|
|||||||
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
|
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
|
|
||||||
|
reflect.getprototypeof@1.0.10:
|
||||||
|
resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
regenerate-unicode-properties@10.2.2:
|
||||||
|
resolution: {integrity: sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
|
regenerate@1.4.2:
|
||||||
|
resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==}
|
||||||
|
|
||||||
|
regexp.prototype.flags@1.5.4:
|
||||||
|
resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
regexpu-core@6.4.0:
|
||||||
|
resolution: {integrity: sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
|
regjsgen@0.8.0:
|
||||||
|
resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==}
|
||||||
|
|
||||||
|
regjsparser@0.13.0:
|
||||||
|
resolution: {integrity: sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
reka-ui@2.6.1:
|
reka-ui@2.6.1:
|
||||||
resolution: {integrity: sha512-XK7cJDQoNuGXfCNzBBo/81Yg/OgjPwvbabnlzXG2VsdSgNsT6iIkuPBPr+C0Shs+3bb0x0lbPvgQAhMSCKm5Ww==}
|
resolution: {integrity: sha512-XK7cJDQoNuGXfCNzBBo/81Yg/OgjPwvbabnlzXG2VsdSgNsT6iIkuPBPr+C0Shs+3bb0x0lbPvgQAhMSCKm5Ww==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -2049,6 +3037,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
require-from-string@2.0.2:
|
||||||
|
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
resedit@1.7.2:
|
resedit@1.7.2:
|
||||||
resolution: {integrity: sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==}
|
resolution: {integrity: sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==}
|
||||||
engines: {node: '>=12', npm: '>=6'}
|
engines: {node: '>=12', npm: '>=6'}
|
||||||
@@ -2056,6 +3048,11 @@ packages:
|
|||||||
resolve-alpn@1.2.1:
|
resolve-alpn@1.2.1:
|
||||||
resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==}
|
resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==}
|
||||||
|
|
||||||
|
resolve@1.22.11:
|
||||||
|
resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
responselike@2.0.1:
|
responselike@2.0.1:
|
||||||
resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==}
|
resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==}
|
||||||
|
|
||||||
@@ -2129,9 +3126,26 @@ packages:
|
|||||||
engines: {node: ^20.19.0 || >=22.12.0}
|
engines: {node: ^20.19.0 || >=22.12.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
rollup@2.79.2:
|
||||||
|
resolution: {integrity: sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==}
|
||||||
|
engines: {node: '>=10.0.0'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
|
safe-array-concat@1.1.3:
|
||||||
|
resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==}
|
||||||
|
engines: {node: '>=0.4'}
|
||||||
|
|
||||||
safe-buffer@5.2.1:
|
safe-buffer@5.2.1:
|
||||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||||
|
|
||||||
|
safe-push-apply@1.0.0:
|
||||||
|
resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
safe-regex-test@1.1.0:
|
||||||
|
resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
safer-buffer@2.1.2:
|
safer-buffer@2.1.2:
|
||||||
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
|
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
|
||||||
|
|
||||||
@@ -2165,13 +3179,35 @@ packages:
|
|||||||
resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==}
|
resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
serialize-javascript@6.0.2:
|
||||||
|
resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==}
|
||||||
|
|
||||||
serve-static@2.2.0:
|
serve-static@2.2.0:
|
||||||
resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==}
|
resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==}
|
||||||
engines: {node: '>= 18'}
|
engines: {node: '>= 18'}
|
||||||
|
|
||||||
|
set-function-length@1.2.2:
|
||||||
|
resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
set-function-name@2.0.2:
|
||||||
|
resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
set-proto@1.0.0:
|
||||||
|
resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
setprototypeof@1.2.0:
|
setprototypeof@1.2.0:
|
||||||
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
|
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
|
||||||
|
|
||||||
|
sharp-ico@0.1.5:
|
||||||
|
resolution: {integrity: sha512-a3jODQl82NPp1d5OYb0wY+oFaPk7AvyxipIowCHk7pBsZCWgbe0yAkU2OOXdoH0ENyANhyOQbs9xkAiRHcF02Q==}
|
||||||
|
|
||||||
|
sharp@0.33.5:
|
||||||
|
resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==}
|
||||||
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
|
|
||||||
shebang-command@2.0.0:
|
shebang-command@2.0.0:
|
||||||
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -2180,6 +3216,22 @@ packages:
|
|||||||
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
|
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
side-channel-list@1.0.0:
|
||||||
|
resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
side-channel-map@1.0.1:
|
||||||
|
resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
side-channel-weakmap@1.0.2:
|
||||||
|
resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
side-channel@1.1.0:
|
||||||
|
resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
signal-exit@3.0.7:
|
signal-exit@3.0.7:
|
||||||
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
|
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
|
||||||
|
|
||||||
@@ -2187,6 +3239,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
|
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
|
|
||||||
|
simple-swizzle@0.2.4:
|
||||||
|
resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==}
|
||||||
|
|
||||||
simple-update-notifier@2.0.0:
|
simple-update-notifier@2.0.0:
|
||||||
resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==}
|
resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -2199,6 +3254,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
|
resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
|
||||||
engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
|
engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
|
||||||
|
|
||||||
|
smob@1.5.0:
|
||||||
|
resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==}
|
||||||
|
|
||||||
socks-proxy-agent@7.0.0:
|
socks-proxy-agent@7.0.0:
|
||||||
resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==}
|
resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
@@ -2218,6 +3276,15 @@ packages:
|
|||||||
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
|
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
source-map@0.8.0-beta.0:
|
||||||
|
resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==}
|
||||||
|
engines: {node: '>= 8'}
|
||||||
|
deprecated: The work that was done in this beta branch won't be included in future versions
|
||||||
|
|
||||||
|
sourcemap-codec@1.4.8:
|
||||||
|
resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
|
||||||
|
deprecated: Please use @jridgewell/sourcemap-codec instead
|
||||||
|
|
||||||
speakingurl@14.0.1:
|
speakingurl@14.0.1:
|
||||||
resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==}
|
resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -2237,6 +3304,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
|
resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
|
|
||||||
|
stop-iteration-iterator@1.1.0:
|
||||||
|
resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
string-width@4.2.3:
|
string-width@4.2.3:
|
||||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -2245,9 +3316,29 @@ packages:
|
|||||||
resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
|
resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
string.prototype.matchall@4.0.12:
|
||||||
|
resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
string.prototype.trim@1.2.10:
|
||||||
|
resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
string.prototype.trimend@1.0.9:
|
||||||
|
resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
string.prototype.trimstart@1.0.8:
|
||||||
|
resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
string_decoder@1.3.0:
|
string_decoder@1.3.0:
|
||||||
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
|
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
|
||||||
|
|
||||||
|
stringify-object@3.3.0:
|
||||||
|
resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
strip-ansi@6.0.1:
|
strip-ansi@6.0.1:
|
||||||
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -2256,6 +3347,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==}
|
resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
strip-comments@2.0.1:
|
||||||
|
resolution: {integrity: sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
sumchecker@3.0.1:
|
sumchecker@3.0.1:
|
||||||
resolution: {integrity: sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==}
|
resolution: {integrity: sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==}
|
||||||
engines: {node: '>= 8.0'}
|
engines: {node: '>= 8.0'}
|
||||||
@@ -2268,6 +3363,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
supports-preserve-symlinks-flag@1.0.0:
|
||||||
|
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
tailwind-merge@3.4.0:
|
tailwind-merge@3.4.0:
|
||||||
resolution: {integrity: sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==}
|
resolution: {integrity: sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==}
|
||||||
|
|
||||||
@@ -2282,6 +3381,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==}
|
resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
temp-dir@2.0.0:
|
||||||
|
resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
temp-file@3.4.0:
|
temp-file@3.4.0:
|
||||||
resolution: {integrity: sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==}
|
resolution: {integrity: sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==}
|
||||||
|
|
||||||
@@ -2289,6 +3392,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==}
|
resolution: {integrity: sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==}
|
||||||
engines: {node: '>=6.0.0'}
|
engines: {node: '>=6.0.0'}
|
||||||
|
|
||||||
|
tempy@0.6.0:
|
||||||
|
resolution: {integrity: sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
terser@5.44.1:
|
terser@5.44.1:
|
||||||
resolution: {integrity: sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==}
|
resolution: {integrity: sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -2308,10 +3415,16 @@ packages:
|
|||||||
resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==}
|
resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==}
|
||||||
engines: {node: '>=14.14'}
|
engines: {node: '>=14.14'}
|
||||||
|
|
||||||
|
to-data-view@1.1.0:
|
||||||
|
resolution: {integrity: sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==}
|
||||||
|
|
||||||
toidentifier@1.0.1:
|
toidentifier@1.0.1:
|
||||||
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
|
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
|
||||||
engines: {node: '>=0.6'}
|
engines: {node: '>=0.6'}
|
||||||
|
|
||||||
|
tr46@1.0.1:
|
||||||
|
resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==}
|
||||||
|
|
||||||
truncate-utf8-bytes@1.0.2:
|
truncate-utf8-bytes@1.0.2:
|
||||||
resolution: {integrity: sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==}
|
resolution: {integrity: sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==}
|
||||||
|
|
||||||
@@ -2325,17 +3438,63 @@ packages:
|
|||||||
resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==}
|
resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
type-fest@0.16.0:
|
||||||
|
resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
typed-array-buffer@1.0.3:
|
||||||
|
resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
typed-array-byte-length@1.0.3:
|
||||||
|
resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
typed-array-byte-offset@1.0.4:
|
||||||
|
resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
typed-array-length@1.0.7:
|
||||||
|
resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
typescript@5.9.3:
|
typescript@5.9.3:
|
||||||
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
|
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
|
||||||
engines: {node: '>=14.17'}
|
engines: {node: '>=14.17'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
unbox-primitive@1.1.0:
|
||||||
|
resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
unconfig-core@7.4.2:
|
||||||
|
resolution: {integrity: sha512-VgPCvLWugINbXvMQDf8Jh0mlbvNjNC6eSUziHsBCMpxR05OPrNrvDnyatdMjRgcHaaNsCqz+wjNXxNw1kRLHUg==}
|
||||||
|
|
||||||
|
unconfig@7.4.2:
|
||||||
|
resolution: {integrity: sha512-nrMlWRQ1xdTjSnSUqvYqJzbTBFugoqHobQj58B2bc8qxHKBBHMNNsWQFP3Cd3/JZK907voM2geYPWqD4VK3MPQ==}
|
||||||
|
|
||||||
undici-types@6.21.0:
|
undici-types@6.21.0:
|
||||||
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
|
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
|
||||||
|
|
||||||
undici-types@7.16.0:
|
undici-types@7.16.0:
|
||||||
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
|
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
|
||||||
|
|
||||||
|
unicode-canonical-property-names-ecmascript@2.0.1:
|
||||||
|
resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
|
unicode-match-property-ecmascript@2.0.0:
|
||||||
|
resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
|
unicode-match-property-value-ecmascript@2.2.1:
|
||||||
|
resolution: {integrity: sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
|
unicode-property-aliases-ecmascript@2.2.0:
|
||||||
|
resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
unique-filename@2.0.1:
|
unique-filename@2.0.1:
|
||||||
resolution: {integrity: sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==}
|
resolution: {integrity: sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==}
|
||||||
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
||||||
@@ -2344,6 +3503,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==}
|
resolution: {integrity: sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==}
|
||||||
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
||||||
|
|
||||||
|
unique-string@2.0.0:
|
||||||
|
resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
universalify@0.1.2:
|
universalify@0.1.2:
|
||||||
resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
|
resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
|
||||||
engines: {node: '>= 4.0.0'}
|
engines: {node: '>= 4.0.0'}
|
||||||
@@ -2352,6 +3515,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
|
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
|
||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
|
|
||||||
|
upath@1.2.0:
|
||||||
|
resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
update-browserslist-db@1.2.2:
|
update-browserslist-db@1.2.2:
|
||||||
resolution: {integrity: sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==}
|
resolution: {integrity: sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@@ -2382,6 +3549,18 @@ packages:
|
|||||||
vite-plugin-electron-renderer:
|
vite-plugin-electron-renderer:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
vite-plugin-pwa@1.2.0:
|
||||||
|
resolution: {integrity: sha512-a2xld+SJshT9Lgcv8Ji4+srFJL4k/1bVbd1x06JIkvecpQkwkvCncD1+gSzcdm3s+owWLpMJerG3aN5jupJEVw==}
|
||||||
|
engines: {node: '>=16.0.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@vite-pwa/assets-generator': ^1.0.0
|
||||||
|
vite: ^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
|
||||||
|
workbox-build: ^7.4.0
|
||||||
|
workbox-window: ^7.4.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@vite-pwa/assets-generator':
|
||||||
|
optional: true
|
||||||
|
|
||||||
vscode-uri@3.1.0:
|
vscode-uri@3.1.0:
|
||||||
resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==}
|
resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==}
|
||||||
|
|
||||||
@@ -2432,11 +3611,82 @@ packages:
|
|||||||
wcwidth@1.0.1:
|
wcwidth@1.0.1:
|
||||||
resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
|
resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
|
||||||
|
|
||||||
|
webidl-conversions@4.0.2:
|
||||||
|
resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
|
||||||
|
|
||||||
|
whatwg-url@7.1.0:
|
||||||
|
resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==}
|
||||||
|
|
||||||
|
which-boxed-primitive@1.1.1:
|
||||||
|
resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
which-builtin-type@1.2.1:
|
||||||
|
resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
which-collection@1.0.2:
|
||||||
|
resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
which-typed-array@1.1.19:
|
||||||
|
resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
which@2.0.2:
|
which@2.0.2:
|
||||||
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
workbox-background-sync@7.4.0:
|
||||||
|
resolution: {integrity: sha512-8CB9OxKAgKZKyNMwfGZ1XESx89GryWTfI+V5yEj8sHjFH8MFelUwYXEyldEK6M6oKMmn807GoJFUEA1sC4XS9w==}
|
||||||
|
|
||||||
|
workbox-broadcast-update@7.4.0:
|
||||||
|
resolution: {integrity: sha512-+eZQwoktlvo62cI0b+QBr40v5XjighxPq3Fzo9AWMiAosmpG5gxRHgTbGGhaJv/q/MFVxwFNGh/UwHZ/8K88lA==}
|
||||||
|
|
||||||
|
workbox-build@7.4.0:
|
||||||
|
resolution: {integrity: sha512-Ntk1pWb0caOFIvwz/hfgrov/OJ45wPEhI5PbTywQcYjyZiVhT3UrwwUPl6TRYbTm4moaFYithYnl1lvZ8UjxcA==}
|
||||||
|
engines: {node: '>=20.0.0'}
|
||||||
|
|
||||||
|
workbox-cacheable-response@7.4.0:
|
||||||
|
resolution: {integrity: sha512-0Fb8795zg/x23ISFkAc7lbWes6vbw34DGFIMw31cwuHPgDEC/5EYm6m/ZkylLX0EnEbbOyOCLjKgFS/Z5g0HeQ==}
|
||||||
|
|
||||||
|
workbox-core@7.4.0:
|
||||||
|
resolution: {integrity: sha512-6BMfd8tYEnN4baG4emG9U0hdXM4gGuDU3ectXuVHnj71vwxTFI7WOpQJC4siTOlVtGqCUtj0ZQNsrvi6kZZTAQ==}
|
||||||
|
|
||||||
|
workbox-expiration@7.4.0:
|
||||||
|
resolution: {integrity: sha512-V50p4BxYhtA80eOvulu8xVfPBgZbkxJ1Jr8UUn0rvqjGhLDqKNtfrDfjJKnLz2U8fO2xGQJTx/SKXNTzHOjnHw==}
|
||||||
|
|
||||||
|
workbox-google-analytics@7.4.0:
|
||||||
|
resolution: {integrity: sha512-MVPXQslRF6YHkzGoFw1A4GIB8GrKym/A5+jYDUSL+AeJw4ytQGrozYdiZqUW1TPQHW8isBCBtyFJergUXyNoWQ==}
|
||||||
|
|
||||||
|
workbox-navigation-preload@7.4.0:
|
||||||
|
resolution: {integrity: sha512-etzftSgdQfjMcfPgbfaZCfM2QuR1P+4o8uCA2s4rf3chtKTq/Om7g/qvEOcZkG6v7JZOSOxVYQiOu6PbAZgU6w==}
|
||||||
|
|
||||||
|
workbox-precaching@7.4.0:
|
||||||
|
resolution: {integrity: sha512-VQs37T6jDqf1rTxUJZXRl3yjZMf5JX/vDPhmx2CPgDDKXATzEoqyRqhYnRoxl6Kr0rqaQlp32i9rtG5zTzIlNg==}
|
||||||
|
|
||||||
|
workbox-range-requests@7.4.0:
|
||||||
|
resolution: {integrity: sha512-3Vq854ZNuP6Y0KZOQWLaLC9FfM7ZaE+iuQl4VhADXybwzr4z/sMmnLgTeUZLq5PaDlcJBxYXQ3U91V7dwAIfvw==}
|
||||||
|
|
||||||
|
workbox-recipes@7.4.0:
|
||||||
|
resolution: {integrity: sha512-kOkWvsAn4H8GvAkwfJTbwINdv4voFoiE9hbezgB1sb/0NLyTG4rE7l6LvS8lLk5QIRIto+DjXLuAuG3Vmt3cxQ==}
|
||||||
|
|
||||||
|
workbox-routing@7.4.0:
|
||||||
|
resolution: {integrity: sha512-C/ooj5uBWYAhAqwmU8HYQJdOjjDKBp9MzTQ+otpMmd+q0eF59K+NuXUek34wbL0RFrIXe/KKT+tUWcZcBqxbHQ==}
|
||||||
|
|
||||||
|
workbox-strategies@7.4.0:
|
||||||
|
resolution: {integrity: sha512-T4hVqIi5A4mHi92+5EppMX3cLaVywDp8nsyUgJhOZxcfSV/eQofcOA6/EMo5rnTNmNTpw0rUgjAI6LaVullPpg==}
|
||||||
|
|
||||||
|
workbox-streams@7.4.0:
|
||||||
|
resolution: {integrity: sha512-QHPBQrey7hQbnTs5GrEVoWz7RhHJXnPT+12qqWM378orDMo5VMJLCkCM1cnCk+8Eq92lccx/VgRZ7WAzZWbSLg==}
|
||||||
|
|
||||||
|
workbox-sw@7.4.0:
|
||||||
|
resolution: {integrity: sha512-ltU+Kr3qWR6BtbdlMnCjobZKzeV1hN+S6UvDywBrwM19TTyqA03X66dzw1tEIdJvQ4lYKkBFox6IAEhoSEZ8Xw==}
|
||||||
|
|
||||||
|
workbox-window@7.4.0:
|
||||||
|
resolution: {integrity: sha512-/bIYdBLAVsNR3v7gYGaV4pQW3M3kEPx5E8vDxGvxo6khTrGtSSCS7QiFKv9ogzBgZiy0OXLP9zO28U/1nF1mfw==}
|
||||||
|
|
||||||
wrap-ansi@7.0.0:
|
wrap-ansi@7.0.0:
|
||||||
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -2481,6 +3731,13 @@ snapshots:
|
|||||||
|
|
||||||
7zip-bin@5.2.0: {}
|
7zip-bin@5.2.0: {}
|
||||||
|
|
||||||
|
'@apideck/better-ajv-errors@0.3.6(ajv@8.17.1)':
|
||||||
|
dependencies:
|
||||||
|
ajv: 8.17.1
|
||||||
|
json-schema: 0.4.0
|
||||||
|
jsonpointer: 5.0.1
|
||||||
|
leven: 3.1.0
|
||||||
|
|
||||||
'@babel/code-frame@7.27.1':
|
'@babel/code-frame@7.27.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/helper-validator-identifier': 7.28.5
|
'@babel/helper-validator-identifier': 7.28.5
|
||||||
@@ -2517,6 +3774,10 @@ snapshots:
|
|||||||
'@jridgewell/trace-mapping': 0.3.31
|
'@jridgewell/trace-mapping': 0.3.31
|
||||||
jsesc: 3.1.0
|
jsesc: 3.1.0
|
||||||
|
|
||||||
|
'@babel/helper-annotate-as-pure@7.27.3':
|
||||||
|
dependencies:
|
||||||
|
'@babel/types': 7.28.5
|
||||||
|
|
||||||
'@babel/helper-compilation-targets@7.27.2':
|
'@babel/helper-compilation-targets@7.27.2':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/compat-data': 7.28.5
|
'@babel/compat-data': 7.28.5
|
||||||
@@ -2525,8 +3786,46 @@ snapshots:
|
|||||||
lru-cache: 5.1.1
|
lru-cache: 5.1.1
|
||||||
semver: 6.3.1
|
semver: 6.3.1
|
||||||
|
|
||||||
|
'@babel/helper-create-class-features-plugin@7.28.5(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-annotate-as-pure': 7.27.3
|
||||||
|
'@babel/helper-member-expression-to-functions': 7.28.5
|
||||||
|
'@babel/helper-optimise-call-expression': 7.27.1
|
||||||
|
'@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/helper-skip-transparent-expression-wrappers': 7.27.1
|
||||||
|
'@babel/traverse': 7.28.5
|
||||||
|
semver: 6.3.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-annotate-as-pure': 7.27.3
|
||||||
|
regexpu-core: 6.4.0
|
||||||
|
semver: 6.3.1
|
||||||
|
|
||||||
|
'@babel/helper-define-polyfill-provider@0.6.5(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-compilation-targets': 7.27.2
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
debug: 4.4.3
|
||||||
|
lodash.debounce: 4.0.8
|
||||||
|
resolve: 1.22.11
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
'@babel/helper-globals@7.28.0': {}
|
'@babel/helper-globals@7.28.0': {}
|
||||||
|
|
||||||
|
'@babel/helper-member-expression-to-functions@7.28.5':
|
||||||
|
dependencies:
|
||||||
|
'@babel/traverse': 7.28.5
|
||||||
|
'@babel/types': 7.28.5
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
'@babel/helper-module-imports@7.27.1':
|
'@babel/helper-module-imports@7.27.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/traverse': 7.28.5
|
'@babel/traverse': 7.28.5
|
||||||
@@ -2543,14 +3842,51 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/helper-optimise-call-expression@7.27.1':
|
||||||
|
dependencies:
|
||||||
|
'@babel/types': 7.28.5
|
||||||
|
|
||||||
'@babel/helper-plugin-utils@7.27.1': {}
|
'@babel/helper-plugin-utils@7.27.1': {}
|
||||||
|
|
||||||
|
'@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-annotate-as-pure': 7.27.3
|
||||||
|
'@babel/helper-wrap-function': 7.28.3
|
||||||
|
'@babel/traverse': 7.28.5
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/helper-replace-supers@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-member-expression-to-functions': 7.28.5
|
||||||
|
'@babel/helper-optimise-call-expression': 7.27.1
|
||||||
|
'@babel/traverse': 7.28.5
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/helper-skip-transparent-expression-wrappers@7.27.1':
|
||||||
|
dependencies:
|
||||||
|
'@babel/traverse': 7.28.5
|
||||||
|
'@babel/types': 7.28.5
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
'@babel/helper-string-parser@7.27.1': {}
|
'@babel/helper-string-parser@7.27.1': {}
|
||||||
|
|
||||||
'@babel/helper-validator-identifier@7.28.5': {}
|
'@babel/helper-validator-identifier@7.28.5': {}
|
||||||
|
|
||||||
'@babel/helper-validator-option@7.27.1': {}
|
'@babel/helper-validator-option@7.27.1': {}
|
||||||
|
|
||||||
|
'@babel/helper-wrap-function@7.28.3':
|
||||||
|
dependencies:
|
||||||
|
'@babel/template': 7.27.2
|
||||||
|
'@babel/traverse': 7.28.5
|
||||||
|
'@babel/types': 7.28.5
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
'@babel/helpers@7.28.4':
|
'@babel/helpers@7.28.4':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/template': 7.27.2
|
'@babel/template': 7.27.2
|
||||||
@@ -2560,11 +3896,479 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@babel/types': 7.28.5
|
'@babel/types': 7.28.5
|
||||||
|
|
||||||
|
'@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
'@babel/traverse': 7.28.5
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
'@babel/helper-skip-transparent-expression-wrappers': 7.27.1
|
||||||
|
'@babel/plugin-transform-optional-chaining': 7.28.5(@babel/core@7.28.5)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
'@babel/traverse': 7.28.5
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
|
||||||
|
'@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
'@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.5)':
|
'@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.5)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.28.5
|
'@babel/core': 7.28.5
|
||||||
'@babel/helper-plugin-utils': 7.27.1
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-async-generator-functions@7.28.0(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
'@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/traverse': 7.28.5
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-module-imports': 7.27.1
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
'@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.5)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-block-scoping@7.28.5(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-transform-class-static-block@7.28.3(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-transform-classes@7.28.4(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-annotate-as-pure': 7.27.3
|
||||||
|
'@babel/helper-compilation-targets': 7.27.2
|
||||||
|
'@babel/helper-globals': 7.28.0
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
'@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/traverse': 7.28.5
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
'@babel/template': 7.27.2
|
||||||
|
|
||||||
|
'@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
'@babel/traverse': 7.28.5
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-explicit-resource-management@7.28.0(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
'@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-transform-exponentiation-operator@7.28.5(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
'@babel/helper-skip-transparent-expression-wrappers': 7.27.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-transform-function-name@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-compilation-targets': 7.27.2
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
'@babel/traverse': 7.28.5
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-logical-assignment-operators@7.28.5(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5)
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5)
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-transform-modules-systemjs@7.28.5(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5)
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
'@babel/helper-validator-identifier': 7.28.5
|
||||||
|
'@babel/traverse': 7.28.5
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5)
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-new-target@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-object-rest-spread@7.28.4(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-compilation-targets': 7.27.2
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
'@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.5)
|
||||||
|
'@babel/traverse': 7.28.5
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-transform-object-super@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
'@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-transform-optional-catch-binding@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-optional-chaining@7.28.5(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
'@babel/helper-skip-transparent-expression-wrappers': 7.27.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-annotate-as-pure': 7.27.3
|
||||||
|
'@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-regenerator@7.28.4(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-spread@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
'@babel/helper-skip-transparent-expression-wrappers': 7.27.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-unicode-property-regex@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/plugin-transform-unicode-sets-regex@7.27.1(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
|
||||||
|
'@babel/preset-env@7.28.5(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/compat-data': 7.28.5
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-compilation-targets': 7.27.2
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
'@babel/helper-validator-option': 7.27.1
|
||||||
|
'@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.3(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-async-generator-functions': 7.28.0(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-block-scoping': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-class-static-block': 7.28.3(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-classes': 7.28.4(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-dotall-regex': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-explicit-resource-management': 7.28.0(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-exponentiation-operator': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-json-strings': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-literals': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-logical-assignment-operators': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-modules-systemjs': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-object-rest-spread': 7.28.4(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-optional-chaining': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-regenerator': 7.28.4(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-spread': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-unicode-property-regex': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/plugin-transform-unicode-sets-regex': 7.27.1(@babel/core@7.28.5)
|
||||||
|
'@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.28.5)
|
||||||
|
babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.5)
|
||||||
|
babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.5)
|
||||||
|
babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.5)
|
||||||
|
core-js-compat: 3.47.0
|
||||||
|
semver: 6.3.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.28.5)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-plugin-utils': 7.27.1
|
||||||
|
'@babel/types': 7.28.5
|
||||||
|
esutils: 2.0.3
|
||||||
|
|
||||||
|
'@babel/runtime@7.28.4': {}
|
||||||
|
|
||||||
'@babel/template@7.27.2':
|
'@babel/template@7.27.2':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/code-frame': 7.27.1
|
'@babel/code-frame': 7.27.1
|
||||||
@@ -2588,6 +4392,9 @@ snapshots:
|
|||||||
'@babel/helper-string-parser': 7.27.1
|
'@babel/helper-string-parser': 7.27.1
|
||||||
'@babel/helper-validator-identifier': 7.28.5
|
'@babel/helper-validator-identifier': 7.28.5
|
||||||
|
|
||||||
|
'@canvas/image-data@1.1.0':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@develar/schema-utils@2.6.5':
|
'@develar/schema-utils@2.6.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
ajv: 6.12.6
|
ajv: 6.12.6
|
||||||
@@ -2819,6 +4626,81 @@ snapshots:
|
|||||||
|
|
||||||
'@gar/promisify@1.1.3': {}
|
'@gar/promisify@1.1.3': {}
|
||||||
|
|
||||||
|
'@img/sharp-darwin-arm64@0.33.5':
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-libvips-darwin-arm64': 1.0.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-darwin-x64@0.33.5':
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-libvips-darwin-x64': 1.0.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-libvips-darwin-arm64@1.0.4':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-libvips-darwin-x64@1.0.4':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-arm64@1.0.4':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-arm@1.0.5':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-s390x@1.0.4':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-x64@1.0.4':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linuxmusl-arm64@1.0.4':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linuxmusl-x64@1.0.4':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-linux-arm64@0.33.5':
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-libvips-linux-arm64': 1.0.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-linux-arm@0.33.5':
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-libvips-linux-arm': 1.0.5
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-linux-s390x@0.33.5':
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-libvips-linux-s390x': 1.0.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-linux-x64@0.33.5':
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-libvips-linux-x64': 1.0.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-linuxmusl-arm64@0.33.5':
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-libvips-linuxmusl-arm64': 1.0.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-linuxmusl-x64@0.33.5':
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-libvips-linuxmusl-x64': 1.0.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-wasm32@0.33.5':
|
||||||
|
dependencies:
|
||||||
|
'@emnapi/runtime': 1.7.1
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-win32-ia32@0.33.5':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-win32-x64@0.33.5':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@internationalized/date@3.10.0':
|
'@internationalized/date@3.10.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@swc/helpers': 0.5.17
|
'@swc/helpers': 0.5.17
|
||||||
@@ -2858,7 +4740,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/gen-mapping': 0.3.13
|
'@jridgewell/gen-mapping': 0.3.13
|
||||||
'@jridgewell/trace-mapping': 0.3.31
|
'@jridgewell/trace-mapping': 0.3.31
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@jridgewell/sourcemap-codec@1.5.5': {}
|
'@jridgewell/sourcemap-codec@1.5.5': {}
|
||||||
|
|
||||||
@@ -2904,6 +4785,11 @@ snapshots:
|
|||||||
'@pkgjs/parseargs@0.11.0':
|
'@pkgjs/parseargs@0.11.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@quansync/fs@1.0.0':
|
||||||
|
dependencies:
|
||||||
|
quansync: 1.0.0
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@rolldown/binding-android-arm64@1.0.0-beta.50':
|
'@rolldown/binding-android-arm64@1.0.0-beta.50':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -2950,8 +4836,63 @@ snapshots:
|
|||||||
|
|
||||||
'@rolldown/pluginutils@1.0.0-beta.50': {}
|
'@rolldown/pluginutils@1.0.0-beta.50': {}
|
||||||
|
|
||||||
|
'@rollup/plugin-babel@5.3.1(@babel/core@7.28.5)(rollup@2.79.2)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-module-imports': 7.27.1
|
||||||
|
'@rollup/pluginutils': 3.1.0(rollup@2.79.2)
|
||||||
|
rollup: 2.79.2
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@rollup/plugin-node-resolve@15.3.1(rollup@2.79.2)':
|
||||||
|
dependencies:
|
||||||
|
'@rollup/pluginutils': 5.3.0(rollup@2.79.2)
|
||||||
|
'@types/resolve': 1.20.2
|
||||||
|
deepmerge: 4.3.1
|
||||||
|
is-module: 1.0.0
|
||||||
|
resolve: 1.22.11
|
||||||
|
optionalDependencies:
|
||||||
|
rollup: 2.79.2
|
||||||
|
|
||||||
|
'@rollup/plugin-replace@2.4.2(rollup@2.79.2)':
|
||||||
|
dependencies:
|
||||||
|
'@rollup/pluginutils': 3.1.0(rollup@2.79.2)
|
||||||
|
magic-string: 0.25.9
|
||||||
|
rollup: 2.79.2
|
||||||
|
|
||||||
|
'@rollup/plugin-terser@0.4.4(rollup@2.79.2)':
|
||||||
|
dependencies:
|
||||||
|
serialize-javascript: 6.0.2
|
||||||
|
smob: 1.5.0
|
||||||
|
terser: 5.44.1
|
||||||
|
optionalDependencies:
|
||||||
|
rollup: 2.79.2
|
||||||
|
|
||||||
|
'@rollup/pluginutils@3.1.0(rollup@2.79.2)':
|
||||||
|
dependencies:
|
||||||
|
'@types/estree': 0.0.39
|
||||||
|
estree-walker: 1.0.1
|
||||||
|
picomatch: 2.3.1
|
||||||
|
rollup: 2.79.2
|
||||||
|
|
||||||
|
'@rollup/pluginutils@5.3.0(rollup@2.79.2)':
|
||||||
|
dependencies:
|
||||||
|
'@types/estree': 1.0.8
|
||||||
|
estree-walker: 2.0.2
|
||||||
|
picomatch: 4.0.3
|
||||||
|
optionalDependencies:
|
||||||
|
rollup: 2.79.2
|
||||||
|
|
||||||
'@sindresorhus/is@4.6.0': {}
|
'@sindresorhus/is@4.6.0': {}
|
||||||
|
|
||||||
|
'@surma/rollup-plugin-off-main-thread@2.2.3':
|
||||||
|
dependencies:
|
||||||
|
ejs: 3.1.10
|
||||||
|
json5: 2.2.3
|
||||||
|
magic-string: 0.25.9
|
||||||
|
string.prototype.matchall: 4.0.12
|
||||||
|
|
||||||
'@swc/helpers@0.5.17':
|
'@swc/helpers@0.5.17':
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
@@ -3062,6 +5003,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@types/ms': 2.1.0
|
'@types/ms': 2.1.0
|
||||||
|
|
||||||
|
'@types/estree@0.0.39': {}
|
||||||
|
|
||||||
|
'@types/estree@1.0.8': {}
|
||||||
|
|
||||||
'@types/file-saver@2.0.7': {}
|
'@types/file-saver@2.0.7': {}
|
||||||
|
|
||||||
'@types/fs-extra@9.0.13':
|
'@types/fs-extra@9.0.13':
|
||||||
@@ -3090,10 +5035,14 @@ snapshots:
|
|||||||
xmlbuilder: 15.1.1
|
xmlbuilder: 15.1.1
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@types/resolve@1.20.2': {}
|
||||||
|
|
||||||
'@types/responselike@1.0.3':
|
'@types/responselike@1.0.3':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 24.10.2
|
'@types/node': 24.10.2
|
||||||
|
|
||||||
|
'@types/trusted-types@2.0.7': {}
|
||||||
|
|
||||||
'@types/verror@1.10.11':
|
'@types/verror@1.10.11':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -3104,6 +5053,16 @@ snapshots:
|
|||||||
'@types/node': 24.10.2
|
'@types/node': 24.10.2
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@vite-pwa/assets-generator@1.0.2':
|
||||||
|
dependencies:
|
||||||
|
cac: 6.7.14
|
||||||
|
colorette: 2.0.20
|
||||||
|
consola: 3.4.2
|
||||||
|
sharp: 0.33.5
|
||||||
|
sharp-ico: 0.1.5
|
||||||
|
unconfig: 7.4.2
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@vitejs/plugin-vue@6.0.2(rolldown-vite@7.2.5(@types/node@24.10.2)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.44.1))(vue@3.5.25(typescript@5.9.3))':
|
'@vitejs/plugin-vue@6.0.2(rolldown-vite@7.2.5(@types/node@24.10.2)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.44.1))(vue@3.5.25(typescript@5.9.3))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@rolldown/pluginutils': 1.0.0-beta.50
|
'@rolldown/pluginutils': 1.0.0-beta.50
|
||||||
@@ -3247,8 +5206,7 @@ snapshots:
|
|||||||
|
|
||||||
abbrev@1.1.1: {}
|
abbrev@1.1.1: {}
|
||||||
|
|
||||||
acorn@8.15.0:
|
acorn@8.15.0: {}
|
||||||
optional: true
|
|
||||||
|
|
||||||
agent-base@6.0.2:
|
agent-base@6.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3278,6 +5236,13 @@ snapshots:
|
|||||||
json-schema-traverse: 0.4.1
|
json-schema-traverse: 0.4.1
|
||||||
uri-js: 4.4.1
|
uri-js: 4.4.1
|
||||||
|
|
||||||
|
ajv@8.17.1:
|
||||||
|
dependencies:
|
||||||
|
fast-deep-equal: 3.1.3
|
||||||
|
fast-uri: 3.1.0
|
||||||
|
json-schema-traverse: 1.0.0
|
||||||
|
require-from-string: 2.0.2
|
||||||
|
|
||||||
alien-signals@3.1.1: {}
|
alien-signals@3.1.1: {}
|
||||||
|
|
||||||
ansi-regex@5.0.1: {}
|
ansi-regex@5.0.1: {}
|
||||||
@@ -3339,6 +5304,21 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
array-buffer-byte-length@1.0.2:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
is-array-buffer: 3.0.5
|
||||||
|
|
||||||
|
arraybuffer.prototype.slice@1.0.4:
|
||||||
|
dependencies:
|
||||||
|
array-buffer-byte-length: 1.0.2
|
||||||
|
call-bind: 1.0.8
|
||||||
|
define-properties: 1.2.1
|
||||||
|
es-abstract: 1.24.1
|
||||||
|
es-errors: 1.3.0
|
||||||
|
get-intrinsic: 1.3.0
|
||||||
|
is-array-buffer: 3.0.5
|
||||||
|
|
||||||
assert-plus@1.0.0:
|
assert-plus@1.0.0:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -3347,12 +5327,42 @@ snapshots:
|
|||||||
|
|
||||||
async-exit-hook@2.0.1: {}
|
async-exit-hook@2.0.1: {}
|
||||||
|
|
||||||
|
async-function@1.0.0: {}
|
||||||
|
|
||||||
async@3.2.6: {}
|
async@3.2.6: {}
|
||||||
|
|
||||||
asynckit@0.4.0: {}
|
asynckit@0.4.0: {}
|
||||||
|
|
||||||
at-least-node@1.0.0: {}
|
at-least-node@1.0.0: {}
|
||||||
|
|
||||||
|
available-typed-arrays@1.0.7:
|
||||||
|
dependencies:
|
||||||
|
possible-typed-array-names: 1.1.0
|
||||||
|
|
||||||
|
babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.5):
|
||||||
|
dependencies:
|
||||||
|
'@babel/compat-data': 7.28.5
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5)
|
||||||
|
semver: 6.3.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.28.5):
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5)
|
||||||
|
core-js-compat: 3.47.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.5):
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
balanced-match@1.0.2: {}
|
balanced-match@1.0.2: {}
|
||||||
|
|
||||||
base64-js@1.5.1: {}
|
base64-js@1.5.1: {}
|
||||||
@@ -3467,6 +5477,18 @@ snapshots:
|
|||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
function-bind: 1.1.2
|
function-bind: 1.1.2
|
||||||
|
|
||||||
|
call-bind@1.0.8:
|
||||||
|
dependencies:
|
||||||
|
call-bind-apply-helpers: 1.0.2
|
||||||
|
es-define-property: 1.0.1
|
||||||
|
get-intrinsic: 1.3.0
|
||||||
|
set-function-length: 1.2.2
|
||||||
|
|
||||||
|
call-bound@1.0.4:
|
||||||
|
dependencies:
|
||||||
|
call-bind-apply-helpers: 1.0.2
|
||||||
|
get-intrinsic: 1.3.0
|
||||||
|
|
||||||
caniuse-lite@1.0.30001760: {}
|
caniuse-lite@1.0.30001760: {}
|
||||||
|
|
||||||
chalk@4.1.2:
|
chalk@4.1.2:
|
||||||
@@ -3518,18 +5540,34 @@ snapshots:
|
|||||||
|
|
||||||
color-name@1.1.4: {}
|
color-name@1.1.4: {}
|
||||||
|
|
||||||
|
color-string@1.9.1:
|
||||||
|
dependencies:
|
||||||
|
color-name: 1.1.4
|
||||||
|
simple-swizzle: 0.2.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
color@4.2.3:
|
||||||
|
dependencies:
|
||||||
|
color-convert: 2.0.1
|
||||||
|
color-string: 1.9.1
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
colorette@2.0.20:
|
||||||
|
optional: true
|
||||||
|
|
||||||
combined-stream@1.0.8:
|
combined-stream@1.0.8:
|
||||||
dependencies:
|
dependencies:
|
||||||
delayed-stream: 1.0.0
|
delayed-stream: 1.0.0
|
||||||
|
|
||||||
commander@2.20.3:
|
commander@2.20.3: {}
|
||||||
optional: true
|
|
||||||
|
|
||||||
commander@5.1.0: {}
|
commander@5.1.0: {}
|
||||||
|
|
||||||
commander@9.5.0:
|
commander@9.5.0:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
common-tags@1.8.2: {}
|
||||||
|
|
||||||
compare-version@0.1.2: {}
|
compare-version@0.1.2: {}
|
||||||
|
|
||||||
concat-map@0.0.1: {}
|
concat-map@0.0.1: {}
|
||||||
@@ -3539,12 +5577,19 @@ snapshots:
|
|||||||
glob: 10.5.0
|
glob: 10.5.0
|
||||||
typescript: 5.9.3
|
typescript: 5.9.3
|
||||||
|
|
||||||
|
consola@3.4.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
convert-source-map@2.0.0: {}
|
convert-source-map@2.0.0: {}
|
||||||
|
|
||||||
copy-anything@4.0.5:
|
copy-anything@4.0.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-what: 5.5.0
|
is-what: 5.5.0
|
||||||
|
|
||||||
|
core-js-compat@3.47.0:
|
||||||
|
dependencies:
|
||||||
|
browserslist: 4.28.1
|
||||||
|
|
||||||
core-util-is@1.0.2:
|
core-util-is@1.0.2:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -3568,16 +5613,51 @@ snapshots:
|
|||||||
|
|
||||||
crypto-js@4.2.0: {}
|
crypto-js@4.2.0: {}
|
||||||
|
|
||||||
|
crypto-random-string@2.0.0: {}
|
||||||
|
|
||||||
csstype@3.2.3: {}
|
csstype@3.2.3: {}
|
||||||
|
|
||||||
|
data-view-buffer@1.0.2:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
es-errors: 1.3.0
|
||||||
|
is-data-view: 1.0.2
|
||||||
|
|
||||||
|
data-view-byte-length@1.0.2:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
es-errors: 1.3.0
|
||||||
|
is-data-view: 1.0.2
|
||||||
|
|
||||||
|
data-view-byte-offset@1.0.1:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
es-errors: 1.3.0
|
||||||
|
is-data-view: 1.0.2
|
||||||
|
|
||||||
debug@4.4.3:
|
debug@4.4.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
ms: 2.1.3
|
ms: 2.1.3
|
||||||
|
|
||||||
|
decode-bmp@0.2.1:
|
||||||
|
dependencies:
|
||||||
|
'@canvas/image-data': 1.1.0
|
||||||
|
to-data-view: 1.1.0
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
decode-ico@0.4.1:
|
||||||
|
dependencies:
|
||||||
|
'@canvas/image-data': 1.1.0
|
||||||
|
decode-bmp: 0.2.1
|
||||||
|
to-data-view: 1.1.0
|
||||||
|
optional: true
|
||||||
|
|
||||||
decompress-response@6.0.0:
|
decompress-response@6.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
mimic-response: 3.1.0
|
mimic-response: 3.1.0
|
||||||
|
|
||||||
|
deepmerge@4.3.1: {}
|
||||||
|
|
||||||
defaults@1.0.4:
|
defaults@1.0.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
clone: 1.0.4
|
clone: 1.0.4
|
||||||
@@ -3589,14 +5669,12 @@ snapshots:
|
|||||||
es-define-property: 1.0.1
|
es-define-property: 1.0.1
|
||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
gopd: 1.2.0
|
gopd: 1.2.0
|
||||||
optional: true
|
|
||||||
|
|
||||||
define-properties@1.2.1:
|
define-properties@1.2.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
define-data-property: 1.1.4
|
define-data-property: 1.1.4
|
||||||
has-property-descriptors: 1.0.2
|
has-property-descriptors: 1.0.2
|
||||||
object-keys: 1.1.1
|
object-keys: 1.1.1
|
||||||
optional: true
|
|
||||||
|
|
||||||
defu@6.1.4: {}
|
defu@6.1.4: {}
|
||||||
|
|
||||||
@@ -3761,6 +5839,63 @@ snapshots:
|
|||||||
|
|
||||||
err-code@2.0.3: {}
|
err-code@2.0.3: {}
|
||||||
|
|
||||||
|
es-abstract@1.24.1:
|
||||||
|
dependencies:
|
||||||
|
array-buffer-byte-length: 1.0.2
|
||||||
|
arraybuffer.prototype.slice: 1.0.4
|
||||||
|
available-typed-arrays: 1.0.7
|
||||||
|
call-bind: 1.0.8
|
||||||
|
call-bound: 1.0.4
|
||||||
|
data-view-buffer: 1.0.2
|
||||||
|
data-view-byte-length: 1.0.2
|
||||||
|
data-view-byte-offset: 1.0.1
|
||||||
|
es-define-property: 1.0.1
|
||||||
|
es-errors: 1.3.0
|
||||||
|
es-object-atoms: 1.1.1
|
||||||
|
es-set-tostringtag: 2.1.0
|
||||||
|
es-to-primitive: 1.3.0
|
||||||
|
function.prototype.name: 1.1.8
|
||||||
|
get-intrinsic: 1.3.0
|
||||||
|
get-proto: 1.0.1
|
||||||
|
get-symbol-description: 1.1.0
|
||||||
|
globalthis: 1.0.4
|
||||||
|
gopd: 1.2.0
|
||||||
|
has-property-descriptors: 1.0.2
|
||||||
|
has-proto: 1.2.0
|
||||||
|
has-symbols: 1.1.0
|
||||||
|
hasown: 2.0.2
|
||||||
|
internal-slot: 1.1.0
|
||||||
|
is-array-buffer: 3.0.5
|
||||||
|
is-callable: 1.2.7
|
||||||
|
is-data-view: 1.0.2
|
||||||
|
is-negative-zero: 2.0.3
|
||||||
|
is-regex: 1.2.1
|
||||||
|
is-set: 2.0.3
|
||||||
|
is-shared-array-buffer: 1.0.4
|
||||||
|
is-string: 1.1.1
|
||||||
|
is-typed-array: 1.1.15
|
||||||
|
is-weakref: 1.1.1
|
||||||
|
math-intrinsics: 1.1.0
|
||||||
|
object-inspect: 1.13.4
|
||||||
|
object-keys: 1.1.1
|
||||||
|
object.assign: 4.1.7
|
||||||
|
own-keys: 1.0.1
|
||||||
|
regexp.prototype.flags: 1.5.4
|
||||||
|
safe-array-concat: 1.1.3
|
||||||
|
safe-push-apply: 1.0.0
|
||||||
|
safe-regex-test: 1.1.0
|
||||||
|
set-proto: 1.0.0
|
||||||
|
stop-iteration-iterator: 1.1.0
|
||||||
|
string.prototype.trim: 1.2.10
|
||||||
|
string.prototype.trimend: 1.0.9
|
||||||
|
string.prototype.trimstart: 1.0.8
|
||||||
|
typed-array-buffer: 1.0.3
|
||||||
|
typed-array-byte-length: 1.0.3
|
||||||
|
typed-array-byte-offset: 1.0.4
|
||||||
|
typed-array-length: 1.0.7
|
||||||
|
unbox-primitive: 1.1.0
|
||||||
|
which-typed-array: 1.1.19
|
||||||
|
|
||||||
es-define-property@1.0.1: {}
|
es-define-property@1.0.1: {}
|
||||||
|
|
||||||
es-errors@1.3.0: {}
|
es-errors@1.3.0: {}
|
||||||
@@ -3776,6 +5911,12 @@ snapshots:
|
|||||||
has-tostringtag: 1.0.2
|
has-tostringtag: 1.0.2
|
||||||
hasown: 2.0.2
|
hasown: 2.0.2
|
||||||
|
|
||||||
|
es-to-primitive@1.3.0:
|
||||||
|
dependencies:
|
||||||
|
is-callable: 1.2.7
|
||||||
|
is-date-object: 1.1.0
|
||||||
|
is-symbol: 1.1.1
|
||||||
|
|
||||||
es6-error@4.1.1:
|
es6-error@4.1.1:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -3815,8 +5956,12 @@ snapshots:
|
|||||||
escape-string-regexp@4.0.0:
|
escape-string-regexp@4.0.0:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
estree-walker@1.0.1: {}
|
||||||
|
|
||||||
estree-walker@2.0.2: {}
|
estree-walker@2.0.2: {}
|
||||||
|
|
||||||
|
esutils@2.0.3: {}
|
||||||
|
|
||||||
etag@1.8.1: {}
|
etag@1.8.1: {}
|
||||||
|
|
||||||
exponential-backoff@3.1.3: {}
|
exponential-backoff@3.1.3: {}
|
||||||
@@ -3838,6 +5983,8 @@ snapshots:
|
|||||||
|
|
||||||
fast-json-stable-stringify@2.1.0: {}
|
fast-json-stable-stringify@2.1.0: {}
|
||||||
|
|
||||||
|
fast-uri@3.1.0: {}
|
||||||
|
|
||||||
fd-slicer@1.1.0:
|
fd-slicer@1.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
pend: 1.2.0
|
pend: 1.2.0
|
||||||
@@ -3863,6 +6010,10 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
for-each@0.3.5:
|
||||||
|
dependencies:
|
||||||
|
is-callable: 1.2.7
|
||||||
|
|
||||||
foreground-child@3.3.1:
|
foreground-child@3.3.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
cross-spawn: 7.0.6
|
cross-spawn: 7.0.6
|
||||||
@@ -3920,6 +6071,19 @@ snapshots:
|
|||||||
|
|
||||||
function-bind@1.1.2: {}
|
function-bind@1.1.2: {}
|
||||||
|
|
||||||
|
function.prototype.name@1.1.8:
|
||||||
|
dependencies:
|
||||||
|
call-bind: 1.0.8
|
||||||
|
call-bound: 1.0.4
|
||||||
|
define-properties: 1.2.1
|
||||||
|
functions-have-names: 1.2.3
|
||||||
|
hasown: 2.0.2
|
||||||
|
is-callable: 1.2.7
|
||||||
|
|
||||||
|
functions-have-names@1.2.3: {}
|
||||||
|
|
||||||
|
generator-function@2.0.1: {}
|
||||||
|
|
||||||
gensync@1.0.0-beta.2: {}
|
gensync@1.0.0-beta.2: {}
|
||||||
|
|
||||||
get-caller-file@2.0.5: {}
|
get-caller-file@2.0.5: {}
|
||||||
@@ -3937,6 +6101,8 @@ snapshots:
|
|||||||
hasown: 2.0.2
|
hasown: 2.0.2
|
||||||
math-intrinsics: 1.1.0
|
math-intrinsics: 1.1.0
|
||||||
|
|
||||||
|
get-own-enumerable-property-symbols@3.0.2: {}
|
||||||
|
|
||||||
get-proto@1.0.1:
|
get-proto@1.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
dunder-proto: 1.0.1
|
dunder-proto: 1.0.1
|
||||||
@@ -3946,6 +6112,12 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
pump: 3.0.3
|
pump: 3.0.3
|
||||||
|
|
||||||
|
get-symbol-description@1.1.0:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
es-errors: 1.3.0
|
||||||
|
get-intrinsic: 1.3.0
|
||||||
|
|
||||||
glob@10.5.0:
|
glob@10.5.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
foreground-child: 3.3.1
|
foreground-child: 3.3.1
|
||||||
@@ -3955,6 +6127,15 @@ snapshots:
|
|||||||
package-json-from-dist: 1.0.1
|
package-json-from-dist: 1.0.1
|
||||||
path-scurry: 1.11.1
|
path-scurry: 1.11.1
|
||||||
|
|
||||||
|
glob@11.1.0:
|
||||||
|
dependencies:
|
||||||
|
foreground-child: 3.3.1
|
||||||
|
jackspeak: 4.1.1
|
||||||
|
minimatch: 10.1.1
|
||||||
|
minipass: 7.1.2
|
||||||
|
package-json-from-dist: 1.0.1
|
||||||
|
path-scurry: 2.0.1
|
||||||
|
|
||||||
glob@7.2.3:
|
glob@7.2.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
fs.realpath: 1.0.0
|
fs.realpath: 1.0.0
|
||||||
@@ -3986,7 +6167,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
define-properties: 1.2.1
|
define-properties: 1.2.1
|
||||||
gopd: 1.2.0
|
gopd: 1.2.0
|
||||||
optional: true
|
|
||||||
|
|
||||||
gopd@1.2.0: {}
|
gopd@1.2.0: {}
|
||||||
|
|
||||||
@@ -4006,12 +6186,17 @@ snapshots:
|
|||||||
|
|
||||||
graceful-fs@4.2.11: {}
|
graceful-fs@4.2.11: {}
|
||||||
|
|
||||||
|
has-bigints@1.1.0: {}
|
||||||
|
|
||||||
has-flag@4.0.0: {}
|
has-flag@4.0.0: {}
|
||||||
|
|
||||||
has-property-descriptors@1.0.2:
|
has-property-descriptors@1.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
es-define-property: 1.0.1
|
es-define-property: 1.0.1
|
||||||
optional: true
|
|
||||||
|
has-proto@1.2.0:
|
||||||
|
dependencies:
|
||||||
|
dunder-proto: 1.0.1
|
||||||
|
|
||||||
has-symbols@1.1.0: {}
|
has-symbols@1.1.0: {}
|
||||||
|
|
||||||
@@ -4077,6 +6262,9 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ms: 2.1.3
|
ms: 2.1.3
|
||||||
|
|
||||||
|
ico-endec@0.1.6:
|
||||||
|
optional: true
|
||||||
|
|
||||||
iconv-corefoundation@1.1.7:
|
iconv-corefoundation@1.1.7:
|
||||||
dependencies:
|
dependencies:
|
||||||
cli-truncate: 2.1.0
|
cli-truncate: 2.1.0
|
||||||
@@ -4087,6 +6275,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
safer-buffer: 2.1.2
|
safer-buffer: 2.1.2
|
||||||
|
|
||||||
|
idb@7.1.1: {}
|
||||||
|
|
||||||
ieee754@1.2.1: {}
|
ieee754@1.2.1: {}
|
||||||
|
|
||||||
imurmurhash@0.1.4: {}
|
imurmurhash@0.1.4: {}
|
||||||
@@ -4102,22 +6292,141 @@ snapshots:
|
|||||||
|
|
||||||
inherits@2.0.4: {}
|
inherits@2.0.4: {}
|
||||||
|
|
||||||
|
internal-slot@1.1.0:
|
||||||
|
dependencies:
|
||||||
|
es-errors: 1.3.0
|
||||||
|
hasown: 2.0.2
|
||||||
|
side-channel: 1.1.0
|
||||||
|
|
||||||
ip-address@10.1.0: {}
|
ip-address@10.1.0: {}
|
||||||
|
|
||||||
|
is-array-buffer@3.0.5:
|
||||||
|
dependencies:
|
||||||
|
call-bind: 1.0.8
|
||||||
|
call-bound: 1.0.4
|
||||||
|
get-intrinsic: 1.3.0
|
||||||
|
|
||||||
|
is-arrayish@0.3.4:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
is-async-function@2.1.1:
|
||||||
|
dependencies:
|
||||||
|
async-function: 1.0.0
|
||||||
|
call-bound: 1.0.4
|
||||||
|
get-proto: 1.0.1
|
||||||
|
has-tostringtag: 1.0.2
|
||||||
|
safe-regex-test: 1.1.0
|
||||||
|
|
||||||
|
is-bigint@1.1.0:
|
||||||
|
dependencies:
|
||||||
|
has-bigints: 1.1.0
|
||||||
|
|
||||||
|
is-boolean-object@1.2.2:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
has-tostringtag: 1.0.2
|
||||||
|
|
||||||
|
is-callable@1.2.7: {}
|
||||||
|
|
||||||
is-ci@3.0.1:
|
is-ci@3.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
ci-info: 3.9.0
|
ci-info: 3.9.0
|
||||||
|
|
||||||
|
is-core-module@2.16.1:
|
||||||
|
dependencies:
|
||||||
|
hasown: 2.0.2
|
||||||
|
|
||||||
|
is-data-view@1.0.2:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
get-intrinsic: 1.3.0
|
||||||
|
is-typed-array: 1.1.15
|
||||||
|
|
||||||
|
is-date-object@1.1.0:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
has-tostringtag: 1.0.2
|
||||||
|
|
||||||
|
is-finalizationregistry@1.1.1:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
|
||||||
is-fullwidth-code-point@3.0.0: {}
|
is-fullwidth-code-point@3.0.0: {}
|
||||||
|
|
||||||
|
is-generator-function@1.1.2:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
generator-function: 2.0.1
|
||||||
|
get-proto: 1.0.1
|
||||||
|
has-tostringtag: 1.0.2
|
||||||
|
safe-regex-test: 1.1.0
|
||||||
|
|
||||||
is-interactive@1.0.0: {}
|
is-interactive@1.0.0: {}
|
||||||
|
|
||||||
is-lambda@1.0.1: {}
|
is-lambda@1.0.1: {}
|
||||||
|
|
||||||
|
is-map@2.0.3: {}
|
||||||
|
|
||||||
|
is-module@1.0.0: {}
|
||||||
|
|
||||||
|
is-negative-zero@2.0.3: {}
|
||||||
|
|
||||||
|
is-number-object@1.1.1:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
has-tostringtag: 1.0.2
|
||||||
|
|
||||||
|
is-obj@1.0.1: {}
|
||||||
|
|
||||||
|
is-regex@1.2.1:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
gopd: 1.2.0
|
||||||
|
has-tostringtag: 1.0.2
|
||||||
|
hasown: 2.0.2
|
||||||
|
|
||||||
|
is-regexp@1.0.0: {}
|
||||||
|
|
||||||
|
is-set@2.0.3: {}
|
||||||
|
|
||||||
|
is-shared-array-buffer@1.0.4:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
|
||||||
|
is-stream@2.0.1: {}
|
||||||
|
|
||||||
|
is-string@1.1.1:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
has-tostringtag: 1.0.2
|
||||||
|
|
||||||
|
is-symbol@1.1.1:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
has-symbols: 1.1.0
|
||||||
|
safe-regex-test: 1.1.0
|
||||||
|
|
||||||
|
is-typed-array@1.1.15:
|
||||||
|
dependencies:
|
||||||
|
which-typed-array: 1.1.19
|
||||||
|
|
||||||
is-unicode-supported@0.1.0: {}
|
is-unicode-supported@0.1.0: {}
|
||||||
|
|
||||||
|
is-weakmap@2.0.2: {}
|
||||||
|
|
||||||
|
is-weakref@1.1.1:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
|
||||||
|
is-weakset@2.0.4:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
get-intrinsic: 1.3.0
|
||||||
|
|
||||||
is-what@5.5.0: {}
|
is-what@5.5.0: {}
|
||||||
|
|
||||||
|
isarray@2.0.5: {}
|
||||||
|
|
||||||
isbinaryfile@4.0.10: {}
|
isbinaryfile@4.0.10: {}
|
||||||
|
|
||||||
isbinaryfile@5.0.7: {}
|
isbinaryfile@5.0.7: {}
|
||||||
@@ -4130,6 +6439,10 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@pkgjs/parseargs': 0.11.0
|
'@pkgjs/parseargs': 0.11.0
|
||||||
|
|
||||||
|
jackspeak@4.1.1:
|
||||||
|
dependencies:
|
||||||
|
'@isaacs/cliui': 8.0.2
|
||||||
|
|
||||||
jake@10.9.4:
|
jake@10.9.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
async: 3.2.6
|
async: 3.2.6
|
||||||
@@ -4150,6 +6463,10 @@ snapshots:
|
|||||||
|
|
||||||
json-schema-traverse@0.4.1: {}
|
json-schema-traverse@0.4.1: {}
|
||||||
|
|
||||||
|
json-schema-traverse@1.0.0: {}
|
||||||
|
|
||||||
|
json-schema@0.4.0: {}
|
||||||
|
|
||||||
json-stringify-safe@5.0.1:
|
json-stringify-safe@5.0.1:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -4165,12 +6482,16 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
|
|
||||||
|
jsonpointer@5.0.1: {}
|
||||||
|
|
||||||
keyv@4.5.4:
|
keyv@4.5.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
json-buffer: 3.0.1
|
json-buffer: 3.0.1
|
||||||
|
|
||||||
lazy-val@1.0.5: {}
|
lazy-val@1.0.5: {}
|
||||||
|
|
||||||
|
leven@3.1.0: {}
|
||||||
|
|
||||||
lightningcss-android-arm64@1.30.2:
|
lightningcss-android-arm64@1.30.2:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -4220,6 +6541,10 @@ snapshots:
|
|||||||
lightningcss-win32-arm64-msvc: 1.30.2
|
lightningcss-win32-arm64-msvc: 1.30.2
|
||||||
lightningcss-win32-x64-msvc: 1.30.2
|
lightningcss-win32-x64-msvc: 1.30.2
|
||||||
|
|
||||||
|
lodash.debounce@4.0.8: {}
|
||||||
|
|
||||||
|
lodash.sortby@4.7.0: {}
|
||||||
|
|
||||||
lodash@4.17.21: {}
|
lodash@4.17.21: {}
|
||||||
|
|
||||||
log-symbols@4.1.0:
|
log-symbols@4.1.0:
|
||||||
@@ -4231,6 +6556,8 @@ snapshots:
|
|||||||
|
|
||||||
lru-cache@10.4.3: {}
|
lru-cache@10.4.3: {}
|
||||||
|
|
||||||
|
lru-cache@11.2.4: {}
|
||||||
|
|
||||||
lru-cache@5.1.1:
|
lru-cache@5.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
yallist: 3.1.1
|
yallist: 3.1.1
|
||||||
@@ -4245,6 +6572,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
vue: 3.5.25(typescript@5.9.3)
|
vue: 3.5.25(typescript@5.9.3)
|
||||||
|
|
||||||
|
magic-string@0.25.9:
|
||||||
|
dependencies:
|
||||||
|
sourcemap-codec: 1.4.8
|
||||||
|
|
||||||
magic-string@0.30.21:
|
magic-string@0.30.21:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/sourcemap-codec': 1.5.5
|
'@jridgewell/sourcemap-codec': 1.5.5
|
||||||
@@ -4271,6 +6602,8 @@ snapshots:
|
|||||||
- bluebird
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
marked@17.0.1: {}
|
||||||
|
|
||||||
matcher@3.0.0:
|
matcher@3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
escape-string-regexp: 4.0.0
|
escape-string-regexp: 4.0.0
|
||||||
@@ -4388,8 +6721,18 @@ snapshots:
|
|||||||
|
|
||||||
normalize-url@6.1.0: {}
|
normalize-url@6.1.0: {}
|
||||||
|
|
||||||
object-keys@1.1.1:
|
object-inspect@1.13.4: {}
|
||||||
optional: true
|
|
||||||
|
object-keys@1.1.1: {}
|
||||||
|
|
||||||
|
object.assign@4.1.7:
|
||||||
|
dependencies:
|
||||||
|
call-bind: 1.0.8
|
||||||
|
call-bound: 1.0.4
|
||||||
|
define-properties: 1.2.1
|
||||||
|
es-object-atoms: 1.1.1
|
||||||
|
has-symbols: 1.1.0
|
||||||
|
object-keys: 1.1.1
|
||||||
|
|
||||||
ohash@2.0.11: {}
|
ohash@2.0.11: {}
|
||||||
|
|
||||||
@@ -4417,6 +6760,12 @@ snapshots:
|
|||||||
strip-ansi: 6.0.1
|
strip-ansi: 6.0.1
|
||||||
wcwidth: 1.0.1
|
wcwidth: 1.0.1
|
||||||
|
|
||||||
|
own-keys@1.0.1:
|
||||||
|
dependencies:
|
||||||
|
get-intrinsic: 1.3.0
|
||||||
|
object-keys: 1.1.1
|
||||||
|
safe-push-apply: 1.0.0
|
||||||
|
|
||||||
p-cancelable@2.1.1: {}
|
p-cancelable@2.1.1: {}
|
||||||
|
|
||||||
p-limit@3.1.0:
|
p-limit@3.1.0:
|
||||||
@@ -4437,11 +6786,18 @@ snapshots:
|
|||||||
|
|
||||||
path-key@3.1.1: {}
|
path-key@3.1.1: {}
|
||||||
|
|
||||||
|
path-parse@1.0.7: {}
|
||||||
|
|
||||||
path-scurry@1.11.1:
|
path-scurry@1.11.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
lru-cache: 10.4.3
|
lru-cache: 10.4.3
|
||||||
minipass: 7.1.2
|
minipass: 7.1.2
|
||||||
|
|
||||||
|
path-scurry@2.0.1:
|
||||||
|
dependencies:
|
||||||
|
lru-cache: 11.2.4
|
||||||
|
minipass: 7.1.2
|
||||||
|
|
||||||
pe-library@0.4.1: {}
|
pe-library@0.4.1: {}
|
||||||
|
|
||||||
pend@1.2.0: {}
|
pend@1.2.0: {}
|
||||||
@@ -4450,6 +6806,8 @@ snapshots:
|
|||||||
|
|
||||||
picocolors@1.1.1: {}
|
picocolors@1.1.1: {}
|
||||||
|
|
||||||
|
picomatch@2.3.1: {}
|
||||||
|
|
||||||
picomatch@4.0.3: {}
|
picomatch@4.0.3: {}
|
||||||
|
|
||||||
pinia-plugin-persistedstate@4.7.1(pinia@3.0.4(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3))):
|
pinia-plugin-persistedstate@4.7.1(pinia@3.0.4(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3))):
|
||||||
@@ -4471,6 +6829,8 @@ snapshots:
|
|||||||
base64-js: 1.5.1
|
base64-js: 1.5.1
|
||||||
xmlbuilder: 15.1.1
|
xmlbuilder: 15.1.1
|
||||||
|
|
||||||
|
possible-typed-array-names@1.1.0: {}
|
||||||
|
|
||||||
postcss@8.5.6:
|
postcss@8.5.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
nanoid: 3.3.11
|
nanoid: 3.3.11
|
||||||
@@ -4482,6 +6842,10 @@ snapshots:
|
|||||||
commander: 9.5.0
|
commander: 9.5.0
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
pretty-bytes@5.6.0: {}
|
||||||
|
|
||||||
|
pretty-bytes@6.1.1: {}
|
||||||
|
|
||||||
proc-log@2.0.1: {}
|
proc-log@2.0.1: {}
|
||||||
|
|
||||||
progress@2.0.3: {}
|
progress@2.0.3: {}
|
||||||
@@ -4500,8 +6864,15 @@ snapshots:
|
|||||||
|
|
||||||
punycode@2.3.1: {}
|
punycode@2.3.1: {}
|
||||||
|
|
||||||
|
quansync@1.0.0:
|
||||||
|
optional: true
|
||||||
|
|
||||||
quick-lru@5.1.1: {}
|
quick-lru@5.1.1: {}
|
||||||
|
|
||||||
|
randombytes@2.1.0:
|
||||||
|
dependencies:
|
||||||
|
safe-buffer: 5.2.1
|
||||||
|
|
||||||
range-parser@1.2.1: {}
|
range-parser@1.2.1: {}
|
||||||
|
|
||||||
read-binary-file-arch@1.0.6:
|
read-binary-file-arch@1.0.6:
|
||||||
@@ -4516,6 +6887,47 @@ snapshots:
|
|||||||
string_decoder: 1.3.0
|
string_decoder: 1.3.0
|
||||||
util-deprecate: 1.0.2
|
util-deprecate: 1.0.2
|
||||||
|
|
||||||
|
reflect.getprototypeof@1.0.10:
|
||||||
|
dependencies:
|
||||||
|
call-bind: 1.0.8
|
||||||
|
define-properties: 1.2.1
|
||||||
|
es-abstract: 1.24.1
|
||||||
|
es-errors: 1.3.0
|
||||||
|
es-object-atoms: 1.1.1
|
||||||
|
get-intrinsic: 1.3.0
|
||||||
|
get-proto: 1.0.1
|
||||||
|
which-builtin-type: 1.2.1
|
||||||
|
|
||||||
|
regenerate-unicode-properties@10.2.2:
|
||||||
|
dependencies:
|
||||||
|
regenerate: 1.4.2
|
||||||
|
|
||||||
|
regenerate@1.4.2: {}
|
||||||
|
|
||||||
|
regexp.prototype.flags@1.5.4:
|
||||||
|
dependencies:
|
||||||
|
call-bind: 1.0.8
|
||||||
|
define-properties: 1.2.1
|
||||||
|
es-errors: 1.3.0
|
||||||
|
get-proto: 1.0.1
|
||||||
|
gopd: 1.2.0
|
||||||
|
set-function-name: 2.0.2
|
||||||
|
|
||||||
|
regexpu-core@6.4.0:
|
||||||
|
dependencies:
|
||||||
|
regenerate: 1.4.2
|
||||||
|
regenerate-unicode-properties: 10.2.2
|
||||||
|
regjsgen: 0.8.0
|
||||||
|
regjsparser: 0.13.0
|
||||||
|
unicode-match-property-ecmascript: 2.0.0
|
||||||
|
unicode-match-property-value-ecmascript: 2.2.1
|
||||||
|
|
||||||
|
regjsgen@0.8.0: {}
|
||||||
|
|
||||||
|
regjsparser@0.13.0:
|
||||||
|
dependencies:
|
||||||
|
jsesc: 3.1.0
|
||||||
|
|
||||||
reka-ui@2.6.1(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)):
|
reka-ui@2.6.1(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@floating-ui/dom': 1.7.4
|
'@floating-ui/dom': 1.7.4
|
||||||
@@ -4535,12 +6947,20 @@ snapshots:
|
|||||||
|
|
||||||
require-directory@2.1.1: {}
|
require-directory@2.1.1: {}
|
||||||
|
|
||||||
|
require-from-string@2.0.2: {}
|
||||||
|
|
||||||
resedit@1.7.2:
|
resedit@1.7.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
pe-library: 0.4.1
|
pe-library: 0.4.1
|
||||||
|
|
||||||
resolve-alpn@1.2.1: {}
|
resolve-alpn@1.2.1: {}
|
||||||
|
|
||||||
|
resolve@1.22.11:
|
||||||
|
dependencies:
|
||||||
|
is-core-module: 2.16.1
|
||||||
|
path-parse: 1.0.7
|
||||||
|
supports-preserve-symlinks-flag: 1.0.0
|
||||||
|
|
||||||
responselike@2.0.1:
|
responselike@2.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
lowercase-keys: 2.0.0
|
lowercase-keys: 2.0.0
|
||||||
@@ -4608,8 +7028,31 @@ snapshots:
|
|||||||
'@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.50
|
'@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.50
|
||||||
'@rolldown/binding-win32-x64-msvc': 1.0.0-beta.50
|
'@rolldown/binding-win32-x64-msvc': 1.0.0-beta.50
|
||||||
|
|
||||||
|
rollup@2.79.2:
|
||||||
|
optionalDependencies:
|
||||||
|
fsevents: 2.3.3
|
||||||
|
|
||||||
|
safe-array-concat@1.1.3:
|
||||||
|
dependencies:
|
||||||
|
call-bind: 1.0.8
|
||||||
|
call-bound: 1.0.4
|
||||||
|
get-intrinsic: 1.3.0
|
||||||
|
has-symbols: 1.1.0
|
||||||
|
isarray: 2.0.5
|
||||||
|
|
||||||
safe-buffer@5.2.1: {}
|
safe-buffer@5.2.1: {}
|
||||||
|
|
||||||
|
safe-push-apply@1.0.0:
|
||||||
|
dependencies:
|
||||||
|
es-errors: 1.3.0
|
||||||
|
isarray: 2.0.5
|
||||||
|
|
||||||
|
safe-regex-test@1.1.0:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
es-errors: 1.3.0
|
||||||
|
is-regex: 1.2.1
|
||||||
|
|
||||||
safer-buffer@2.1.2: {}
|
safer-buffer@2.1.2: {}
|
||||||
|
|
||||||
sanitize-filename@1.6.3:
|
sanitize-filename@1.6.3:
|
||||||
@@ -4648,6 +7091,10 @@ snapshots:
|
|||||||
type-fest: 0.13.1
|
type-fest: 0.13.1
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
serialize-javascript@6.0.2:
|
||||||
|
dependencies:
|
||||||
|
randombytes: 2.1.0
|
||||||
|
|
||||||
serve-static@2.2.0:
|
serve-static@2.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
encodeurl: 2.0.0
|
encodeurl: 2.0.0
|
||||||
@@ -4657,18 +7104,107 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
set-function-length@1.2.2:
|
||||||
|
dependencies:
|
||||||
|
define-data-property: 1.1.4
|
||||||
|
es-errors: 1.3.0
|
||||||
|
function-bind: 1.1.2
|
||||||
|
get-intrinsic: 1.3.0
|
||||||
|
gopd: 1.2.0
|
||||||
|
has-property-descriptors: 1.0.2
|
||||||
|
|
||||||
|
set-function-name@2.0.2:
|
||||||
|
dependencies:
|
||||||
|
define-data-property: 1.1.4
|
||||||
|
es-errors: 1.3.0
|
||||||
|
functions-have-names: 1.2.3
|
||||||
|
has-property-descriptors: 1.0.2
|
||||||
|
|
||||||
|
set-proto@1.0.0:
|
||||||
|
dependencies:
|
||||||
|
dunder-proto: 1.0.1
|
||||||
|
es-errors: 1.3.0
|
||||||
|
es-object-atoms: 1.1.1
|
||||||
|
|
||||||
setprototypeof@1.2.0: {}
|
setprototypeof@1.2.0: {}
|
||||||
|
|
||||||
|
sharp-ico@0.1.5:
|
||||||
|
dependencies:
|
||||||
|
decode-ico: 0.4.1
|
||||||
|
ico-endec: 0.1.6
|
||||||
|
sharp: 0.33.5
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
sharp@0.33.5:
|
||||||
|
dependencies:
|
||||||
|
color: 4.2.3
|
||||||
|
detect-libc: 2.1.2
|
||||||
|
semver: 7.7.3
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-darwin-arm64': 0.33.5
|
||||||
|
'@img/sharp-darwin-x64': 0.33.5
|
||||||
|
'@img/sharp-libvips-darwin-arm64': 1.0.4
|
||||||
|
'@img/sharp-libvips-darwin-x64': 1.0.4
|
||||||
|
'@img/sharp-libvips-linux-arm': 1.0.5
|
||||||
|
'@img/sharp-libvips-linux-arm64': 1.0.4
|
||||||
|
'@img/sharp-libvips-linux-s390x': 1.0.4
|
||||||
|
'@img/sharp-libvips-linux-x64': 1.0.4
|
||||||
|
'@img/sharp-libvips-linuxmusl-arm64': 1.0.4
|
||||||
|
'@img/sharp-libvips-linuxmusl-x64': 1.0.4
|
||||||
|
'@img/sharp-linux-arm': 0.33.5
|
||||||
|
'@img/sharp-linux-arm64': 0.33.5
|
||||||
|
'@img/sharp-linux-s390x': 0.33.5
|
||||||
|
'@img/sharp-linux-x64': 0.33.5
|
||||||
|
'@img/sharp-linuxmusl-arm64': 0.33.5
|
||||||
|
'@img/sharp-linuxmusl-x64': 0.33.5
|
||||||
|
'@img/sharp-wasm32': 0.33.5
|
||||||
|
'@img/sharp-win32-ia32': 0.33.5
|
||||||
|
'@img/sharp-win32-x64': 0.33.5
|
||||||
|
optional: true
|
||||||
|
|
||||||
shebang-command@2.0.0:
|
shebang-command@2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
shebang-regex: 3.0.0
|
shebang-regex: 3.0.0
|
||||||
|
|
||||||
shebang-regex@3.0.0: {}
|
shebang-regex@3.0.0: {}
|
||||||
|
|
||||||
|
side-channel-list@1.0.0:
|
||||||
|
dependencies:
|
||||||
|
es-errors: 1.3.0
|
||||||
|
object-inspect: 1.13.4
|
||||||
|
|
||||||
|
side-channel-map@1.0.1:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
es-errors: 1.3.0
|
||||||
|
get-intrinsic: 1.3.0
|
||||||
|
object-inspect: 1.13.4
|
||||||
|
|
||||||
|
side-channel-weakmap@1.0.2:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
es-errors: 1.3.0
|
||||||
|
get-intrinsic: 1.3.0
|
||||||
|
object-inspect: 1.13.4
|
||||||
|
side-channel-map: 1.0.1
|
||||||
|
|
||||||
|
side-channel@1.1.0:
|
||||||
|
dependencies:
|
||||||
|
es-errors: 1.3.0
|
||||||
|
object-inspect: 1.13.4
|
||||||
|
side-channel-list: 1.0.0
|
||||||
|
side-channel-map: 1.0.1
|
||||||
|
side-channel-weakmap: 1.0.2
|
||||||
|
|
||||||
signal-exit@3.0.7: {}
|
signal-exit@3.0.7: {}
|
||||||
|
|
||||||
signal-exit@4.1.0: {}
|
signal-exit@4.1.0: {}
|
||||||
|
|
||||||
|
simple-swizzle@0.2.4:
|
||||||
|
dependencies:
|
||||||
|
is-arrayish: 0.3.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
simple-update-notifier@2.0.0:
|
simple-update-notifier@2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
semver: 7.7.3
|
semver: 7.7.3
|
||||||
@@ -4682,6 +7218,8 @@ snapshots:
|
|||||||
|
|
||||||
smart-buffer@4.2.0: {}
|
smart-buffer@4.2.0: {}
|
||||||
|
|
||||||
|
smob@1.5.0: {}
|
||||||
|
|
||||||
socks-proxy-agent@7.0.0:
|
socks-proxy-agent@7.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
agent-base: 6.0.2
|
agent-base: 6.0.2
|
||||||
@@ -4704,6 +7242,12 @@ snapshots:
|
|||||||
|
|
||||||
source-map@0.6.1: {}
|
source-map@0.6.1: {}
|
||||||
|
|
||||||
|
source-map@0.8.0-beta.0:
|
||||||
|
dependencies:
|
||||||
|
whatwg-url: 7.1.0
|
||||||
|
|
||||||
|
sourcemap-codec@1.4.8: {}
|
||||||
|
|
||||||
speakingurl@14.0.1: {}
|
speakingurl@14.0.1: {}
|
||||||
|
|
||||||
sprintf-js@1.1.3:
|
sprintf-js@1.1.3:
|
||||||
@@ -4717,6 +7261,11 @@ snapshots:
|
|||||||
|
|
||||||
statuses@2.0.2: {}
|
statuses@2.0.2: {}
|
||||||
|
|
||||||
|
stop-iteration-iterator@1.1.0:
|
||||||
|
dependencies:
|
||||||
|
es-errors: 1.3.0
|
||||||
|
internal-slot: 1.1.0
|
||||||
|
|
||||||
string-width@4.2.3:
|
string-width@4.2.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
emoji-regex: 8.0.0
|
emoji-regex: 8.0.0
|
||||||
@@ -4729,10 +7278,55 @@ snapshots:
|
|||||||
emoji-regex: 9.2.2
|
emoji-regex: 9.2.2
|
||||||
strip-ansi: 7.1.2
|
strip-ansi: 7.1.2
|
||||||
|
|
||||||
|
string.prototype.matchall@4.0.12:
|
||||||
|
dependencies:
|
||||||
|
call-bind: 1.0.8
|
||||||
|
call-bound: 1.0.4
|
||||||
|
define-properties: 1.2.1
|
||||||
|
es-abstract: 1.24.1
|
||||||
|
es-errors: 1.3.0
|
||||||
|
es-object-atoms: 1.1.1
|
||||||
|
get-intrinsic: 1.3.0
|
||||||
|
gopd: 1.2.0
|
||||||
|
has-symbols: 1.1.0
|
||||||
|
internal-slot: 1.1.0
|
||||||
|
regexp.prototype.flags: 1.5.4
|
||||||
|
set-function-name: 2.0.2
|
||||||
|
side-channel: 1.1.0
|
||||||
|
|
||||||
|
string.prototype.trim@1.2.10:
|
||||||
|
dependencies:
|
||||||
|
call-bind: 1.0.8
|
||||||
|
call-bound: 1.0.4
|
||||||
|
define-data-property: 1.1.4
|
||||||
|
define-properties: 1.2.1
|
||||||
|
es-abstract: 1.24.1
|
||||||
|
es-object-atoms: 1.1.1
|
||||||
|
has-property-descriptors: 1.0.2
|
||||||
|
|
||||||
|
string.prototype.trimend@1.0.9:
|
||||||
|
dependencies:
|
||||||
|
call-bind: 1.0.8
|
||||||
|
call-bound: 1.0.4
|
||||||
|
define-properties: 1.2.1
|
||||||
|
es-object-atoms: 1.1.1
|
||||||
|
|
||||||
|
string.prototype.trimstart@1.0.8:
|
||||||
|
dependencies:
|
||||||
|
call-bind: 1.0.8
|
||||||
|
define-properties: 1.2.1
|
||||||
|
es-object-atoms: 1.1.1
|
||||||
|
|
||||||
string_decoder@1.3.0:
|
string_decoder@1.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer: 5.2.1
|
safe-buffer: 5.2.1
|
||||||
|
|
||||||
|
stringify-object@3.3.0:
|
||||||
|
dependencies:
|
||||||
|
get-own-enumerable-property-symbols: 3.0.2
|
||||||
|
is-obj: 1.0.1
|
||||||
|
is-regexp: 1.0.0
|
||||||
|
|
||||||
strip-ansi@6.0.1:
|
strip-ansi@6.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
ansi-regex: 5.0.1
|
ansi-regex: 5.0.1
|
||||||
@@ -4741,6 +7335,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ansi-regex: 6.2.2
|
ansi-regex: 6.2.2
|
||||||
|
|
||||||
|
strip-comments@2.0.1: {}
|
||||||
|
|
||||||
sumchecker@3.0.1:
|
sumchecker@3.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 4.4.3
|
debug: 4.4.3
|
||||||
@@ -4755,6 +7351,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
has-flag: 4.0.0
|
has-flag: 4.0.0
|
||||||
|
|
||||||
|
supports-preserve-symlinks-flag@1.0.0: {}
|
||||||
|
|
||||||
tailwind-merge@3.4.0: {}
|
tailwind-merge@3.4.0: {}
|
||||||
|
|
||||||
tailwindcss@4.1.17: {}
|
tailwindcss@4.1.17: {}
|
||||||
@@ -4770,6 +7368,8 @@ snapshots:
|
|||||||
mkdirp: 1.0.4
|
mkdirp: 1.0.4
|
||||||
yallist: 4.0.0
|
yallist: 4.0.0
|
||||||
|
|
||||||
|
temp-dir@2.0.0: {}
|
||||||
|
|
||||||
temp-file@3.4.0:
|
temp-file@3.4.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
async-exit-hook: 2.0.1
|
async-exit-hook: 2.0.1
|
||||||
@@ -4780,13 +7380,19 @@ snapshots:
|
|||||||
mkdirp: 0.5.6
|
mkdirp: 0.5.6
|
||||||
rimraf: 2.6.3
|
rimraf: 2.6.3
|
||||||
|
|
||||||
|
tempy@0.6.0:
|
||||||
|
dependencies:
|
||||||
|
is-stream: 2.0.1
|
||||||
|
temp-dir: 2.0.0
|
||||||
|
type-fest: 0.16.0
|
||||||
|
unique-string: 2.0.0
|
||||||
|
|
||||||
terser@5.44.1:
|
terser@5.44.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/source-map': 0.3.11
|
'@jridgewell/source-map': 0.3.11
|
||||||
acorn: 8.15.0
|
acorn: 8.15.0
|
||||||
commander: 2.20.3
|
commander: 2.20.3
|
||||||
source-map-support: 0.5.21
|
source-map-support: 0.5.21
|
||||||
optional: true
|
|
||||||
|
|
||||||
tiny-async-pool@1.3.0:
|
tiny-async-pool@1.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -4803,8 +7409,15 @@ snapshots:
|
|||||||
|
|
||||||
tmp@0.2.5: {}
|
tmp@0.2.5: {}
|
||||||
|
|
||||||
|
to-data-view@1.1.0:
|
||||||
|
optional: true
|
||||||
|
|
||||||
toidentifier@1.0.1: {}
|
toidentifier@1.0.1: {}
|
||||||
|
|
||||||
|
tr46@1.0.1:
|
||||||
|
dependencies:
|
||||||
|
punycode: 2.3.1
|
||||||
|
|
||||||
truncate-utf8-bytes@1.0.2:
|
truncate-utf8-bytes@1.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
utf8-byte-length: 1.0.5
|
utf8-byte-length: 1.0.5
|
||||||
@@ -4816,12 +7429,80 @@ snapshots:
|
|||||||
type-fest@0.13.1:
|
type-fest@0.13.1:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
type-fest@0.16.0: {}
|
||||||
|
|
||||||
|
typed-array-buffer@1.0.3:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
es-errors: 1.3.0
|
||||||
|
is-typed-array: 1.1.15
|
||||||
|
|
||||||
|
typed-array-byte-length@1.0.3:
|
||||||
|
dependencies:
|
||||||
|
call-bind: 1.0.8
|
||||||
|
for-each: 0.3.5
|
||||||
|
gopd: 1.2.0
|
||||||
|
has-proto: 1.2.0
|
||||||
|
is-typed-array: 1.1.15
|
||||||
|
|
||||||
|
typed-array-byte-offset@1.0.4:
|
||||||
|
dependencies:
|
||||||
|
available-typed-arrays: 1.0.7
|
||||||
|
call-bind: 1.0.8
|
||||||
|
for-each: 0.3.5
|
||||||
|
gopd: 1.2.0
|
||||||
|
has-proto: 1.2.0
|
||||||
|
is-typed-array: 1.1.15
|
||||||
|
reflect.getprototypeof: 1.0.10
|
||||||
|
|
||||||
|
typed-array-length@1.0.7:
|
||||||
|
dependencies:
|
||||||
|
call-bind: 1.0.8
|
||||||
|
for-each: 0.3.5
|
||||||
|
gopd: 1.2.0
|
||||||
|
is-typed-array: 1.1.15
|
||||||
|
possible-typed-array-names: 1.1.0
|
||||||
|
reflect.getprototypeof: 1.0.10
|
||||||
|
|
||||||
typescript@5.9.3: {}
|
typescript@5.9.3: {}
|
||||||
|
|
||||||
|
unbox-primitive@1.1.0:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
has-bigints: 1.1.0
|
||||||
|
has-symbols: 1.1.0
|
||||||
|
which-boxed-primitive: 1.1.1
|
||||||
|
|
||||||
|
unconfig-core@7.4.2:
|
||||||
|
dependencies:
|
||||||
|
'@quansync/fs': 1.0.0
|
||||||
|
quansync: 1.0.0
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
unconfig@7.4.2:
|
||||||
|
dependencies:
|
||||||
|
'@quansync/fs': 1.0.0
|
||||||
|
defu: 6.1.4
|
||||||
|
jiti: 2.6.1
|
||||||
|
quansync: 1.0.0
|
||||||
|
unconfig-core: 7.4.2
|
||||||
|
optional: true
|
||||||
|
|
||||||
undici-types@6.21.0: {}
|
undici-types@6.21.0: {}
|
||||||
|
|
||||||
undici-types@7.16.0: {}
|
undici-types@7.16.0: {}
|
||||||
|
|
||||||
|
unicode-canonical-property-names-ecmascript@2.0.1: {}
|
||||||
|
|
||||||
|
unicode-match-property-ecmascript@2.0.0:
|
||||||
|
dependencies:
|
||||||
|
unicode-canonical-property-names-ecmascript: 2.0.1
|
||||||
|
unicode-property-aliases-ecmascript: 2.2.0
|
||||||
|
|
||||||
|
unicode-match-property-value-ecmascript@2.2.1: {}
|
||||||
|
|
||||||
|
unicode-property-aliases-ecmascript@2.2.0: {}
|
||||||
|
|
||||||
unique-filename@2.0.1:
|
unique-filename@2.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
unique-slug: 3.0.0
|
unique-slug: 3.0.0
|
||||||
@@ -4830,10 +7511,16 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
imurmurhash: 0.1.4
|
imurmurhash: 0.1.4
|
||||||
|
|
||||||
|
unique-string@2.0.0:
|
||||||
|
dependencies:
|
||||||
|
crypto-random-string: 2.0.0
|
||||||
|
|
||||||
universalify@0.1.2: {}
|
universalify@0.1.2: {}
|
||||||
|
|
||||||
universalify@2.0.1: {}
|
universalify@2.0.1: {}
|
||||||
|
|
||||||
|
upath@1.2.0: {}
|
||||||
|
|
||||||
update-browserslist-db@1.2.2(browserslist@4.28.1):
|
update-browserslist-db@1.2.2(browserslist@4.28.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist: 4.28.1
|
browserslist: 4.28.1
|
||||||
@@ -4861,6 +7548,19 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
vite-plugin-electron-renderer: 0.14.6
|
vite-plugin-electron-renderer: 0.14.6
|
||||||
|
|
||||||
|
vite-plugin-pwa@1.2.0(@vite-pwa/assets-generator@1.0.2)(rolldown-vite@7.2.5(@types/node@24.10.2)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.44.1))(workbox-build@7.4.0)(workbox-window@7.4.0):
|
||||||
|
dependencies:
|
||||||
|
debug: 4.4.3
|
||||||
|
pretty-bytes: 6.1.1
|
||||||
|
tinyglobby: 0.2.15
|
||||||
|
vite: rolldown-vite@7.2.5(@types/node@24.10.2)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.44.1)
|
||||||
|
workbox-build: 7.4.0
|
||||||
|
workbox-window: 7.4.0
|
||||||
|
optionalDependencies:
|
||||||
|
'@vite-pwa/assets-generator': 1.0.2
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
vscode-uri@3.1.0: {}
|
vscode-uri@3.1.0: {}
|
||||||
|
|
||||||
vue-demi@0.14.10(vue@3.5.25(typescript@5.9.3)):
|
vue-demi@0.14.10(vue@3.5.25(typescript@5.9.3)):
|
||||||
@@ -4894,10 +7594,172 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
defaults: 1.0.4
|
defaults: 1.0.4
|
||||||
|
|
||||||
|
webidl-conversions@4.0.2: {}
|
||||||
|
|
||||||
|
whatwg-url@7.1.0:
|
||||||
|
dependencies:
|
||||||
|
lodash.sortby: 4.7.0
|
||||||
|
tr46: 1.0.1
|
||||||
|
webidl-conversions: 4.0.2
|
||||||
|
|
||||||
|
which-boxed-primitive@1.1.1:
|
||||||
|
dependencies:
|
||||||
|
is-bigint: 1.1.0
|
||||||
|
is-boolean-object: 1.2.2
|
||||||
|
is-number-object: 1.1.1
|
||||||
|
is-string: 1.1.1
|
||||||
|
is-symbol: 1.1.1
|
||||||
|
|
||||||
|
which-builtin-type@1.2.1:
|
||||||
|
dependencies:
|
||||||
|
call-bound: 1.0.4
|
||||||
|
function.prototype.name: 1.1.8
|
||||||
|
has-tostringtag: 1.0.2
|
||||||
|
is-async-function: 2.1.1
|
||||||
|
is-date-object: 1.1.0
|
||||||
|
is-finalizationregistry: 1.1.1
|
||||||
|
is-generator-function: 1.1.2
|
||||||
|
is-regex: 1.2.1
|
||||||
|
is-weakref: 1.1.1
|
||||||
|
isarray: 2.0.5
|
||||||
|
which-boxed-primitive: 1.1.1
|
||||||
|
which-collection: 1.0.2
|
||||||
|
which-typed-array: 1.1.19
|
||||||
|
|
||||||
|
which-collection@1.0.2:
|
||||||
|
dependencies:
|
||||||
|
is-map: 2.0.3
|
||||||
|
is-set: 2.0.3
|
||||||
|
is-weakmap: 2.0.2
|
||||||
|
is-weakset: 2.0.4
|
||||||
|
|
||||||
|
which-typed-array@1.1.19:
|
||||||
|
dependencies:
|
||||||
|
available-typed-arrays: 1.0.7
|
||||||
|
call-bind: 1.0.8
|
||||||
|
call-bound: 1.0.4
|
||||||
|
for-each: 0.3.5
|
||||||
|
get-proto: 1.0.1
|
||||||
|
gopd: 1.2.0
|
||||||
|
has-tostringtag: 1.0.2
|
||||||
|
|
||||||
which@2.0.2:
|
which@2.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
isexe: 2.0.0
|
isexe: 2.0.0
|
||||||
|
|
||||||
|
workbox-background-sync@7.4.0:
|
||||||
|
dependencies:
|
||||||
|
idb: 7.1.1
|
||||||
|
workbox-core: 7.4.0
|
||||||
|
|
||||||
|
workbox-broadcast-update@7.4.0:
|
||||||
|
dependencies:
|
||||||
|
workbox-core: 7.4.0
|
||||||
|
|
||||||
|
workbox-build@7.4.0:
|
||||||
|
dependencies:
|
||||||
|
'@apideck/better-ajv-errors': 0.3.6(ajv@8.17.1)
|
||||||
|
'@babel/core': 7.28.5
|
||||||
|
'@babel/preset-env': 7.28.5(@babel/core@7.28.5)
|
||||||
|
'@babel/runtime': 7.28.4
|
||||||
|
'@rollup/plugin-babel': 5.3.1(@babel/core@7.28.5)(rollup@2.79.2)
|
||||||
|
'@rollup/plugin-node-resolve': 15.3.1(rollup@2.79.2)
|
||||||
|
'@rollup/plugin-replace': 2.4.2(rollup@2.79.2)
|
||||||
|
'@rollup/plugin-terser': 0.4.4(rollup@2.79.2)
|
||||||
|
'@surma/rollup-plugin-off-main-thread': 2.2.3
|
||||||
|
ajv: 8.17.1
|
||||||
|
common-tags: 1.8.2
|
||||||
|
fast-json-stable-stringify: 2.1.0
|
||||||
|
fs-extra: 9.1.0
|
||||||
|
glob: 11.1.0
|
||||||
|
lodash: 4.17.21
|
||||||
|
pretty-bytes: 5.6.0
|
||||||
|
rollup: 2.79.2
|
||||||
|
source-map: 0.8.0-beta.0
|
||||||
|
stringify-object: 3.3.0
|
||||||
|
strip-comments: 2.0.1
|
||||||
|
tempy: 0.6.0
|
||||||
|
upath: 1.2.0
|
||||||
|
workbox-background-sync: 7.4.0
|
||||||
|
workbox-broadcast-update: 7.4.0
|
||||||
|
workbox-cacheable-response: 7.4.0
|
||||||
|
workbox-core: 7.4.0
|
||||||
|
workbox-expiration: 7.4.0
|
||||||
|
workbox-google-analytics: 7.4.0
|
||||||
|
workbox-navigation-preload: 7.4.0
|
||||||
|
workbox-precaching: 7.4.0
|
||||||
|
workbox-range-requests: 7.4.0
|
||||||
|
workbox-recipes: 7.4.0
|
||||||
|
workbox-routing: 7.4.0
|
||||||
|
workbox-strategies: 7.4.0
|
||||||
|
workbox-streams: 7.4.0
|
||||||
|
workbox-sw: 7.4.0
|
||||||
|
workbox-window: 7.4.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@types/babel__core'
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
workbox-cacheable-response@7.4.0:
|
||||||
|
dependencies:
|
||||||
|
workbox-core: 7.4.0
|
||||||
|
|
||||||
|
workbox-core@7.4.0: {}
|
||||||
|
|
||||||
|
workbox-expiration@7.4.0:
|
||||||
|
dependencies:
|
||||||
|
idb: 7.1.1
|
||||||
|
workbox-core: 7.4.0
|
||||||
|
|
||||||
|
workbox-google-analytics@7.4.0:
|
||||||
|
dependencies:
|
||||||
|
workbox-background-sync: 7.4.0
|
||||||
|
workbox-core: 7.4.0
|
||||||
|
workbox-routing: 7.4.0
|
||||||
|
workbox-strategies: 7.4.0
|
||||||
|
|
||||||
|
workbox-navigation-preload@7.4.0:
|
||||||
|
dependencies:
|
||||||
|
workbox-core: 7.4.0
|
||||||
|
|
||||||
|
workbox-precaching@7.4.0:
|
||||||
|
dependencies:
|
||||||
|
workbox-core: 7.4.0
|
||||||
|
workbox-routing: 7.4.0
|
||||||
|
workbox-strategies: 7.4.0
|
||||||
|
|
||||||
|
workbox-range-requests@7.4.0:
|
||||||
|
dependencies:
|
||||||
|
workbox-core: 7.4.0
|
||||||
|
|
||||||
|
workbox-recipes@7.4.0:
|
||||||
|
dependencies:
|
||||||
|
workbox-cacheable-response: 7.4.0
|
||||||
|
workbox-core: 7.4.0
|
||||||
|
workbox-expiration: 7.4.0
|
||||||
|
workbox-precaching: 7.4.0
|
||||||
|
workbox-routing: 7.4.0
|
||||||
|
workbox-strategies: 7.4.0
|
||||||
|
|
||||||
|
workbox-routing@7.4.0:
|
||||||
|
dependencies:
|
||||||
|
workbox-core: 7.4.0
|
||||||
|
|
||||||
|
workbox-strategies@7.4.0:
|
||||||
|
dependencies:
|
||||||
|
workbox-core: 7.4.0
|
||||||
|
|
||||||
|
workbox-streams@7.4.0:
|
||||||
|
dependencies:
|
||||||
|
workbox-core: 7.4.0
|
||||||
|
workbox-routing: 7.4.0
|
||||||
|
|
||||||
|
workbox-sw@7.4.0: {}
|
||||||
|
|
||||||
|
workbox-window@7.4.0:
|
||||||
|
dependencies:
|
||||||
|
'@types/trusted-types': 2.0.7
|
||||||
|
workbox-core: 7.4.0
|
||||||
|
|
||||||
wrap-ansi@7.0.0:
|
wrap-ansi@7.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
ansi-styles: 4.3.0
|
ansi-styles: 4.3.0
|
||||||
|
|||||||
1419
src/App.vue
1419
src/App.vue
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<SidebarProvider :open="sidebarOpen" @update:open="sidebarOpen = $event">
|
<SidebarProvider :open="sidebarOpen" @update:open="handleSidebarOpenChange">
|
||||||
<Sidebar collapsible="icon">
|
<Sidebar collapsible="icon">
|
||||||
<!-- Logo -->
|
<!-- Logo -->
|
||||||
<SidebarHeader class="border-b">
|
<SidebarHeader class="border-b">
|
||||||
@@ -13,15 +13,68 @@
|
|||||||
<!-- 星球信息 -->
|
<!-- 星球信息 -->
|
||||||
<SidebarGroup v-if="planet" class="border-b group-data-[collapsible=icon]:hidden">
|
<SidebarGroup v-if="planet" class="border-b group-data-[collapsible=icon]:hidden">
|
||||||
<div class="px-4 py-3 space-y-2 text-sm">
|
<div class="px-4 py-3 space-y-2 text-sm">
|
||||||
<div>
|
<!-- 星球切换器 -->
|
||||||
<p class="font-semibold mb-1">
|
<Popover>
|
||||||
{{ planet.name }}
|
<PopoverTrigger as-child>
|
||||||
<Badge v-if="planet.isMoon" variant="secondary" class="ml-1 text-xs">{{ t('planet.moon') }}</Badge>
|
<Button
|
||||||
</p>
|
data-tutorial="planet-selector"
|
||||||
<p class="text-muted-foreground text-xs">
|
variant="outline"
|
||||||
[{{ planet.position.galaxy }}:{{ planet.position.system }}:{{ planet.position.position }}]
|
class="w-full justify-between h-auto px-3 py-2.5 border-2 hover:bg-accent hover:border-primary transition-colors"
|
||||||
</p>
|
>
|
||||||
</div>
|
<div class="flex items-start gap-2.5 flex-1 min-w-0">
|
||||||
|
<Globe class="h-5 w-5 flex-shrink-0 mt-0.5 text-primary" />
|
||||||
|
<div class="flex-1 min-w-0 text-left">
|
||||||
|
<div class="text-[10px] text-muted-foreground uppercase tracking-wider mb-0.5">
|
||||||
|
{{ t('planet.currentPlanet') }}
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-1.5 mb-0.5">
|
||||||
|
<span class="truncate font-semibold text-sm">{{ planet.name }}</span>
|
||||||
|
<Badge v-if="planet.isMoon" variant="secondary" class="text-[10px] px-1 py-0 h-4">
|
||||||
|
{{ t('planet.moon') }}
|
||||||
|
</Badge>
|
||||||
|
</div>
|
||||||
|
<div class="text-[11px] text-muted-foreground">
|
||||||
|
[{{ planet.position.galaxy }}:{{ planet.position.system }}:{{ planet.position.position }}]
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ChevronsUpDown class="h-4 w-4 flex-shrink-0 text-muted-foreground ml-2" />
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent class="w-72 p-0" side="bottom" align="start">
|
||||||
|
<div class="p-2">
|
||||||
|
<div class="px-2 py-1.5 mb-1 text-xs font-semibold text-muted-foreground">
|
||||||
|
{{ t('planet.switchPlanet') }}
|
||||||
|
</div>
|
||||||
|
<div class="space-y-0.5 max-h-80 overflow-y-auto">
|
||||||
|
<Button
|
||||||
|
v-for="p in gameStore.player.planets"
|
||||||
|
:key="p.id"
|
||||||
|
@click="switchToPlanet(p.id)"
|
||||||
|
:variant="p.id === planet.id ? 'secondary' : 'ghost'"
|
||||||
|
class="w-full justify-start h-auto py-2 px-2"
|
||||||
|
size="sm"
|
||||||
|
>
|
||||||
|
<div class="flex items-start gap-2 w-full min-w-0">
|
||||||
|
<Globe class="h-4 w-4 flex-shrink-0 mt-0.5" :class="p.id === planet.id ? 'text-primary' : ''" />
|
||||||
|
<div class="flex-1 min-w-0 text-left">
|
||||||
|
<div class="flex items-center gap-1.5 mb-0.5">
|
||||||
|
<span class="truncate font-medium text-sm">{{ p.name }}</span>
|
||||||
|
<Badge v-if="p.isMoon" variant="outline" class="text-[10px] px-1 py-0 h-4">
|
||||||
|
{{ t('planet.moon') }}
|
||||||
|
</Badge>
|
||||||
|
</div>
|
||||||
|
<div class="text-[11px] text-muted-foreground">
|
||||||
|
[{{ p.position.galaxy }}:{{ p.position.system }}:{{ p.position.position }}]
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
|
||||||
<!-- 玩家积分显示 -->
|
<!-- 玩家积分显示 -->
|
||||||
<div class="bg-muted/50 rounded-lg p-2">
|
<div class="bg-muted/50 rounded-lg p-2">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
@@ -42,18 +95,35 @@
|
|||||||
</SidebarGroup>
|
</SidebarGroup>
|
||||||
|
|
||||||
<!-- 导航菜单 -->
|
<!-- 导航菜单 -->
|
||||||
<SidebarGroup>
|
<SidebarGroup data-tutorial="navigation">
|
||||||
<SidebarMenu>
|
<SidebarMenu>
|
||||||
<SidebarMenuItem v-for="item in navItems" :key="item.path">
|
<SidebarMenuItem v-for="item in navItems" :key="item.path">
|
||||||
<SidebarMenuButton as-child :is-active="$route.path === item.path" :tooltip="item.name.value">
|
<SidebarMenuButton
|
||||||
<RouterLink :to="item.path">
|
:data-nav-path="item.path"
|
||||||
<component :is="item.icon" />
|
:is-active="$route.path === item.path"
|
||||||
<span>{{ item.name.value }}</span>
|
:tooltip="item.name.value"
|
||||||
<!-- 未读消息数量 -->
|
@click="handleNavClick(item.path, $event)"
|
||||||
<SidebarMenuBadge v-if="item.path === '/messages' && unreadMessagesCount > 0">
|
>
|
||||||
{{ unreadMessagesCount }}
|
<component :is="item.icon" />
|
||||||
</SidebarMenuBadge>
|
<span>{{ item.name.value }}</span>
|
||||||
</RouterLink>
|
<!-- 未读消息数量 -->
|
||||||
|
<SidebarMenuBadge
|
||||||
|
v-if="item.path === '/messages' && unreadMessagesCount > 0"
|
||||||
|
class="bg-destructive text-destructive-foreground"
|
||||||
|
>
|
||||||
|
{{ unreadMessagesCount }}
|
||||||
|
</SidebarMenuBadge>
|
||||||
|
<!-- 正在执行的舰队任务数量 -->
|
||||||
|
<SidebarMenuBadge v-if="item.path === '/fleet' && activeFleetMissionsCount > 0" class="bg-primary text-primary-foreground">
|
||||||
|
{{ activeFleetMissionsCount }}
|
||||||
|
</SidebarMenuBadge>
|
||||||
|
<!-- 未读外交报告数量 -->
|
||||||
|
<SidebarMenuBadge
|
||||||
|
v-if="item.path === '/diplomacy' && unreadDiplomaticReportsCount > 0"
|
||||||
|
class="bg-destructive text-destructive-foreground"
|
||||||
|
>
|
||||||
|
{{ unreadDiplomaticReportsCount }}
|
||||||
|
</SidebarMenuBadge>
|
||||||
</SidebarMenuButton>
|
</SidebarMenuButton>
|
||||||
</SidebarMenuItem>
|
</SidebarMenuItem>
|
||||||
</SidebarMenu>
|
</SidebarMenu>
|
||||||
@@ -72,7 +142,11 @@
|
|||||||
<span>{{ localeNames[gameStore.locale] }}</span>
|
<span>{{ localeNames[gameStore.locale] }}</span>
|
||||||
</SidebarMenuButton>
|
</SidebarMenuButton>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent class="w-48 p-2" side="right" align="end">
|
<PopoverContent
|
||||||
|
class="w-48 p-2"
|
||||||
|
:side="sidebarOpen || innerWidth < 768 ? 'top' : 'right'"
|
||||||
|
:align="sidebarOpen || innerWidth < 768 ? 'center' : 'end'"
|
||||||
|
>
|
||||||
<div class="space-y-1">
|
<div class="space-y-1">
|
||||||
<Button
|
<Button
|
||||||
v-for="locale in locales"
|
v-for="locale in locales"
|
||||||
@@ -111,112 +185,137 @@
|
|||||||
|
|
||||||
<!-- 主内容区 -->
|
<!-- 主内容区 -->
|
||||||
<SidebarInset>
|
<SidebarInset>
|
||||||
<div class="flex flex-col h-full overflow-hidden">
|
<div class="flex flex-col h-full overflow-hidden pt-[60px]">
|
||||||
<!-- 顶部资源栏 -->
|
<!-- 顶部资源栏 - 固定定位 -->
|
||||||
<header v-if="planet" class="bg-card border-b px-4 sm:px-6 py-6.5 shadow-md">
|
<header
|
||||||
<div class="flex items-center justify-between gap-3 sm:gap-6">
|
v-if="planet"
|
||||||
<!-- 汉堡菜单(移动端)- 左侧占位 -->
|
class="fixed top-0 right-0 left-0 z-40 bg-card border-b px-4 sm:px-6 py-3 shadow-md"
|
||||||
<div class="lg:flex-1">
|
:class="sidebarOpen ? 'lg:left-[var(--sidebar-width)]' : 'lg:left-[var(--sidebar-width-icon)]'"
|
||||||
<SidebarTrigger class="lg:hidden" />
|
>
|
||||||
</div>
|
<div class="flex flex-col gap-3">
|
||||||
|
<!-- 第一行:菜单、资源预览、状态 -->
|
||||||
|
<div class="grid items-center gap-3 sm:gap-6" style="grid-template-columns: auto 1fr auto">
|
||||||
|
<!-- 左侧:汉堡菜单(移动端)/ 占位(PC端) -->
|
||||||
|
<div>
|
||||||
|
<SidebarTrigger class="lg:hidden" data-tutorial="mobile-menu" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 资源显示 - PC端居中 -->
|
<!-- 资源显示 - PC端居中,移动端可折叠 -->
|
||||||
<div class="flex items-center gap-3 sm:gap-6 flex-1 lg:flex-none overflow-x-auto lg:justify-center">
|
<div
|
||||||
<div v-for="resourceType in resourceTypes" :key="resourceType.key" class="flex items-center gap-1.5 sm:gap-2 flex-shrink-0">
|
class="resource-bar flex items-center gap-3 sm:gap-6 justify-center"
|
||||||
<ResourceIcon :type="resourceType.key" size="md" />
|
:class="resourceBarExpanded ? 'hidden' : 'overflow-x-auto'"
|
||||||
<div class="min-w-0">
|
>
|
||||||
<!-- 所有资源统一显示:当前值/容量 -->
|
<div v-for="resourceType in resourceTypes" :key="resourceType.key" class="flex items-center gap-1.5 sm:gap-2 flex-shrink-0">
|
||||||
<p
|
<ResourceIcon :type="resourceType.key" size="md" />
|
||||||
class="text-xs sm:text-sm font-medium truncate"
|
<div class="min-w-0">
|
||||||
:class="getResourceColor(planet.resources[resourceType.key], capacity?.[resourceType.key] || Infinity)"
|
<!-- 电力显示净产量和效率 -->
|
||||||
>
|
<template v-if="resourceType.key === 'energy'">
|
||||||
{{ formatNumber(planet.resources[resourceType.key]) }} / {{ formatNumber(capacity?.[resourceType.key] || 0) }}
|
<p
|
||||||
</p>
|
class="text-xs sm:text-sm font-medium truncate"
|
||||||
<p class="text-[10px] sm:text-xs text-muted-foreground truncate">
|
:class="netEnergy >= 0 ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400'"
|
||||||
+{{ formatNumber(Math.round((production?.[resourceType.key] || 0) / 60)) }}/{{ t('resources.perMinute') }}
|
>
|
||||||
</p>
|
{{ netEnergy >= 0 ? '+' : '' }}{{ formatNumber(netEnergy) }}
|
||||||
|
</p>
|
||||||
|
<p class="text-[10px] sm:text-xs text-muted-foreground truncate">
|
||||||
|
{{ formatNumber(production?.energy || 0) }} / {{ formatNumber(energyConsumption) }}
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
<!-- 其他资源统一显示:当前值/容量 -->
|
||||||
|
<template v-else>
|
||||||
|
<p
|
||||||
|
class="text-xs sm:text-sm font-medium truncate"
|
||||||
|
:class="getResourceColor(planet.resources[resourceType.key], capacity?.[resourceType.key] || Infinity)"
|
||||||
|
>
|
||||||
|
{{ formatNumber(planet.resources[resourceType.key]) }} / {{ formatNumber(capacity?.[resourceType.key] || 0) }}
|
||||||
|
</p>
|
||||||
|
<p class="text-[10px] sm:text-xs text-muted-foreground truncate">
|
||||||
|
+{{ formatNumber(Math.round((production?.[resourceType.key] || 0) / 60)) }}/{{ t('resources.perMinute') }}
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 右侧状态 - 右侧占位 -->
|
<!-- 右侧:展开按钮(仅移动端) + 状态 -->
|
||||||
<div class="flex items-center gap-2 sm:gap-4 flex-shrink-0 lg:flex-1 lg:justify-end">
|
<div class="flex items-center gap-2 sm:gap-3 flex-shrink-0 justify-end">
|
||||||
<!-- 建造队列状态 -->
|
<!-- 移动端展开按钮 -->
|
||||||
<div v-if="planet.buildQueue.length > 0" class="flex items-center gap-1.5 sm:gap-2 text-xs sm:text-sm">
|
<Button @click="resourceBarExpanded = !resourceBarExpanded" variant="ghost" size="sm" class="lg:hidden h-8 w-8 p-0">
|
||||||
<div class="h-2 w-2 rounded-full bg-green-500 animate-pulse" />
|
<ChevronDown v-if="!resourceBarExpanded" class="h-4 w-4" />
|
||||||
<span class="text-muted-foreground hidden sm:inline">{{ t('queue.building') }}</span>
|
<ChevronUp v-else class="h-4 w-4" />
|
||||||
</div>
|
</Button>
|
||||||
<div v-if="gameStore.player.researchQueue.length > 0" class="flex items-center gap-1.5 sm:gap-2 text-xs sm:text-sm">
|
|
||||||
<div class="h-2 w-2 rounded-full bg-blue-500 animate-pulse" />
|
<!-- 外交通知 -->
|
||||||
<span class="text-muted-foreground hidden sm:inline">{{ t('queue.researching') }}</span>
|
<DiplomaticNotifications />
|
||||||
|
|
||||||
|
<!-- 队列通知 -->
|
||||||
|
<QueueNotifications />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<!-- 建造队列 -->
|
<!-- 展开的资源详情(仅移动端且展开时显示) - absolute定位覆盖在内容上,带过渡动画 -->
|
||||||
<div
|
<Transition
|
||||||
v-if="planet && (planet.buildQueue.length > 0 || gameStore.player.researchQueue.length > 0)"
|
enter-active-class="transition-all duration-300 ease-out"
|
||||||
class="bg-card border-b px-4 sm:px-6 py-4.5"
|
enter-from-class="opacity-0 -translate-y-2"
|
||||||
|
enter-to-class="opacity-100 translate-y-0"
|
||||||
|
leave-active-class="transition-all duration-200 ease-in"
|
||||||
|
leave-from-class="opacity-100 translate-y-0"
|
||||||
|
leave-to-class="opacity-0 -translate-y-2"
|
||||||
>
|
>
|
||||||
<div class="space-y-3">
|
<div
|
||||||
<!-- 建造队列 -->
|
v-if="planet && resourceBarExpanded"
|
||||||
<div v-for="item in planet.buildQueue" :key="item.id" class="space-y-1.5">
|
class="fixed top-[60px] right-0 left-0 z-30 bg-card border-b px-4 py-3 shadow-md lg:hidden"
|
||||||
<div class="flex items-center justify-between text-xs sm:text-sm gap-2">
|
:class="sidebarOpen ? 'lg:left-[var(--sidebar-width)]' : 'lg:left-[var(--sidebar-width-icon)]'"
|
||||||
<div class="flex items-center gap-1.5 sm:gap-2 min-w-0 flex-1">
|
>
|
||||||
<div class="h-2 w-2 rounded-full bg-green-500 animate-pulse flex-shrink-0" />
|
<div class="grid grid-cols-2 gap-3">
|
||||||
<span class="font-medium truncate">{{ getItemName(item) }}</span>
|
<div v-for="resourceType in resourceTypes" :key="resourceType.key" class="bg-muted/50 rounded-lg p-2.5">
|
||||||
<span class="text-muted-foreground hidden sm:inline flex-shrink-0 text-[10px] sm:text-xs">
|
<div class="flex items-center justify-center gap-2 mb-1.5">
|
||||||
<template v-if="item.type === 'ship' || item.type === 'defense'">
|
<ResourceIcon :type="resourceType.key" size="md" />
|
||||||
→ {{ t('queue.quantity') }} {{ item.quantity }}
|
<span class="text-xs font-medium text-muted-foreground">{{ t(`resources.${resourceType.key}`) }}</span>
|
||||||
</template>
|
|
||||||
<template v-else>→ {{ t('queue.level') }} {{ item.targetLevel }}</template>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2 sm:gap-3 flex-shrink-0">
|
<div class="space-y-0.5 text-center">
|
||||||
<span class="text-muted-foreground text-[10px] sm:text-xs whitespace-nowrap">
|
<!-- 电力显示净产量和效率 -->
|
||||||
{{ formatTime(getRemainingTime(item)) }}
|
<template v-if="resourceType.key === 'energy'">
|
||||||
</span>
|
<p
|
||||||
<Button
|
class="text-sm font-semibold"
|
||||||
@click="handleCancelBuild(item.id)"
|
:class="netEnergy >= 0 ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400'"
|
||||||
variant="ghost"
|
>
|
||||||
size="sm"
|
{{ netEnergy >= 0 ? '+' : '' }}{{ formatNumber(netEnergy) }}
|
||||||
class="h-5 sm:h-6 px-1.5 sm:px-2 text-[10px] sm:text-xs"
|
</p>
|
||||||
>
|
<p class="text-[10px] text-muted-foreground">
|
||||||
{{ t('queue.cancel') }}
|
{{ t('resources.production') }}: {{ formatNumber(production?.energy || 0) }} / {{ formatNumber(energyConsumption) }}
|
||||||
</Button>
|
</p>
|
||||||
|
</template>
|
||||||
|
<!-- 其他资源统一显示:当前值/容量 -->
|
||||||
|
<template v-else>
|
||||||
|
<p
|
||||||
|
class="text-sm font-semibold"
|
||||||
|
:class="getResourceColor(planet.resources[resourceType.key], capacity?.[resourceType.key] || Infinity)"
|
||||||
|
>
|
||||||
|
{{ formatNumber(planet.resources[resourceType.key]) }}
|
||||||
|
</p>
|
||||||
|
<p class="text-[10px] text-muted-foreground">
|
||||||
|
{{ t('resources.capacity') }}: {{ formatNumber(capacity?.[resourceType.key] || 0) }}
|
||||||
|
</p>
|
||||||
|
<p class="text-[10px] text-muted-foreground">
|
||||||
|
{{ t('resources.production') }}: +{{ formatNumber(Math.round((production?.[resourceType.key] || 0) / 60)) }}/{{
|
||||||
|
t('resources.perMinute')
|
||||||
|
}}
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Progress :model-value="getQueueProgress(item)" class="h-1.5" />
|
|
||||||
</div>
|
|
||||||
<!-- 研究队列 -->
|
|
||||||
<div v-for="item in gameStore.player.researchQueue" :key="item.id" class="space-y-1.5">
|
|
||||||
<div class="flex items-center justify-between text-xs sm:text-sm gap-2">
|
|
||||||
<div class="flex items-center gap-1.5 sm:gap-2 min-w-0 flex-1">
|
|
||||||
<div class="h-2 w-2 rounded-full bg-blue-500 animate-pulse flex-shrink-0" />
|
|
||||||
<span class="font-medium truncate">{{ getItemName(item) }}</span>
|
|
||||||
<span class="text-muted-foreground hidden sm:inline flex-shrink-0 text-[10px] sm:text-xs">
|
|
||||||
→ {{ t('queue.level') }} {{ item.targetLevel }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center gap-2 sm:gap-3 flex-shrink-0">
|
|
||||||
<span class="text-muted-foreground text-[10px] sm:text-xs whitespace-nowrap">
|
|
||||||
{{ formatTime(getRemainingTime(item)) }}
|
|
||||||
</span>
|
|
||||||
<Button
|
|
||||||
@click="handleCancelResearch(item.id)"
|
|
||||||
variant="ghost"
|
|
||||||
size="sm"
|
|
||||||
class="h-5 sm:h-6 px-1.5 sm:px-2 text-[10px] sm:text-xs"
|
|
||||||
>
|
|
||||||
{{ t('queue.cancel') }}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Progress :model-value="getQueueProgress(item)" class="h-1.5" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Transition>
|
||||||
|
|
||||||
|
<!-- 即将到来的敌对舰队警告 -->
|
||||||
|
<IncomingFleetAlerts
|
||||||
|
v-if="gameStore.player.incomingFleetAlerts && gameStore.player.incomingFleetAlerts.length > 0"
|
||||||
|
:alerts="gameStore.player.incomingFleetAlerts"
|
||||||
|
@mark-as-read="removeIncomingFleetAlert"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- 内容区域 -->
|
<!-- 内容区域 -->
|
||||||
<main class="flex-1 overflow-y-auto">
|
<main class="flex-1 overflow-y-auto">
|
||||||
@@ -232,11 +331,13 @@
|
|||||||
<AlertDialogContent>
|
<AlertDialogContent>
|
||||||
<AlertDialogHeader>
|
<AlertDialogHeader>
|
||||||
<AlertDialogTitle>{{ confirmDialogTitle }}</AlertDialogTitle>
|
<AlertDialogTitle>{{ confirmDialogTitle }}</AlertDialogTitle>
|
||||||
<AlertDialogDescription>{{ confirmDialogMessage }}</AlertDialogDescription>
|
<AlertDialogDescription class="whitespace-pre-line">
|
||||||
|
{{ confirmDialogMessage }}
|
||||||
|
</AlertDialogDescription>
|
||||||
</AlertDialogHeader>
|
</AlertDialogHeader>
|
||||||
<AlertDialogFooter>
|
<AlertDialogFooter>
|
||||||
<AlertDialogCancel>{{ t('common.cancel') }}</AlertDialogCancel>
|
<AlertDialogCancel>{{ t('common.cancel') }}</AlertDialogCancel>
|
||||||
<AlertDialogAction @click="handleConfirmAction">{{ t('common.confirm') }}</AlertDialogAction>
|
<AlertDialogAction @click="handleConfirmDialogConfirm">{{ t('common.confirm') }}</AlertDialogAction>
|
||||||
</AlertDialogFooter>
|
</AlertDialogFooter>
|
||||||
</AlertDialogContent>
|
</AlertDialogContent>
|
||||||
</AlertDialog>
|
</AlertDialog>
|
||||||
@@ -244,22 +345,34 @@
|
|||||||
<!-- 详情弹窗 -->
|
<!-- 详情弹窗 -->
|
||||||
<DetailDialog />
|
<DetailDialog />
|
||||||
|
|
||||||
|
<!-- 更新弹窗 -->
|
||||||
|
<UpdateDialog v-model:open="showUpdateDialog" :version-info="updateInfo" />
|
||||||
|
|
||||||
|
<!-- 新手引导 -->
|
||||||
|
<TutorialOverlay />
|
||||||
|
|
||||||
<!-- Toast 通知 -->
|
<!-- Toast 通知 -->
|
||||||
<Sonner position="top-center" />
|
<Sonner position="top-center" />
|
||||||
</SidebarProvider>
|
</SidebarProvider>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, onUnmounted, computed, ref } from 'vue'
|
import { onMounted, onUnmounted, computed, ref, watch } from 'vue'
|
||||||
import { RouterView, RouterLink } from 'vue-router'
|
import { RouterView, useRouter } from 'vue-router'
|
||||||
import { useGameStore } from '@/stores/gameStore'
|
import { useGameStore } from '@/stores/gameStore'
|
||||||
|
import { useUniverseStore } from '@/stores/universeStore'
|
||||||
|
import { useNPCStore } from '@/stores/npcStore'
|
||||||
import { useTheme } from '@/composables/useTheme'
|
import { useTheme } from '@/composables/useTheme'
|
||||||
import { useI18n } from '@/composables/useI18n'
|
import { useI18n } from '@/composables/useI18n'
|
||||||
|
import { useGameConfig } from '@/composables/useGameConfig'
|
||||||
|
import { useTutorial } from '@/composables/useTutorial'
|
||||||
import { localeNames, detectBrowserLocale, type Locale } from '@/locales'
|
import { localeNames, detectBrowserLocale, type Locale } from '@/locales'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import { Badge } from '@/components/ui/badge'
|
import { Badge } from '@/components/ui/badge'
|
||||||
import { Progress } from '@/components/ui/progress'
|
|
||||||
import { Popover, PopoverTrigger, PopoverContent } from '@/components/ui/popover'
|
import { Popover, PopoverTrigger, PopoverContent } from '@/components/ui/popover'
|
||||||
|
import IncomingFleetAlerts from '@/components/IncomingFleetAlerts.vue'
|
||||||
|
import DiplomaticNotifications from '@/components/DiplomaticNotifications.vue'
|
||||||
|
import QueueNotifications from '@/components/QueueNotifications.vue'
|
||||||
import {
|
import {
|
||||||
Sidebar,
|
Sidebar,
|
||||||
SidebarContent,
|
SidebarContent,
|
||||||
@@ -275,8 +388,6 @@
|
|||||||
SidebarTrigger
|
SidebarTrigger
|
||||||
} from '@/components/ui/sidebar'
|
} from '@/components/ui/sidebar'
|
||||||
import ResourceIcon from '@/components/ResourceIcon.vue'
|
import ResourceIcon from '@/components/ResourceIcon.vue'
|
||||||
import DetailDialog from '@/components/DetailDialog.vue'
|
|
||||||
import Sonner from '@/components/ui/sonner/Sonner.vue'
|
|
||||||
import {
|
import {
|
||||||
AlertDialog,
|
AlertDialog,
|
||||||
AlertDialogAction,
|
AlertDialogAction,
|
||||||
@@ -287,7 +398,15 @@
|
|||||||
AlertDialogHeader,
|
AlertDialogHeader,
|
||||||
AlertDialogTitle
|
AlertDialogTitle
|
||||||
} from '@/components/ui/alert-dialog'
|
} from '@/components/ui/alert-dialog'
|
||||||
import { formatNumber, formatTime, getResourceColor } from '@/utils/format'
|
import DetailDialog from '@/components/DetailDialog.vue'
|
||||||
|
import UpdateDialog from '@/components/UpdateDialog.vue'
|
||||||
|
import TutorialOverlay from '@/components/TutorialOverlay.vue'
|
||||||
|
import Sonner from '@/components/ui/sonner/Sonner.vue'
|
||||||
|
import { MissionType, BuildingType, DiplomaticEventType } from '@/types/game'
|
||||||
|
import type { FleetMission, NPC, IncomingFleetAlert, MissileAttack } from '@/types/game'
|
||||||
|
import { DIPLOMATIC_CONFIG } from '@/config/gameConfig'
|
||||||
|
import type { VersionInfo } from '@/utils/versionCheck'
|
||||||
|
import { formatNumber, getResourceColor } from '@/utils/format'
|
||||||
import {
|
import {
|
||||||
Moon,
|
Moon,
|
||||||
Sun,
|
Sun,
|
||||||
@@ -304,62 +423,808 @@
|
|||||||
Languages,
|
Languages,
|
||||||
Settings,
|
Settings,
|
||||||
Wrench,
|
Wrench,
|
||||||
ChevronsLeft
|
ChevronsLeft,
|
||||||
|
ChevronsUpDown,
|
||||||
|
ChevronDown,
|
||||||
|
ChevronUp,
|
||||||
|
Handshake
|
||||||
} from 'lucide-vue-next'
|
} from 'lucide-vue-next'
|
||||||
|
import * as gameLogic from '@/logic/gameLogic'
|
||||||
|
import * as planetLogic from '@/logic/planetLogic'
|
||||||
import * as officerLogic from '@/logic/officerLogic'
|
import * as officerLogic from '@/logic/officerLogic'
|
||||||
|
import * as buildingValidation from '@/logic/buildingValidation'
|
||||||
import * as resourceLogic from '@/logic/resourceLogic'
|
import * as resourceLogic from '@/logic/resourceLogic'
|
||||||
import { useGameLifecycle } from '@/composables/useGameLifecycle'
|
import * as researchValidation from '@/logic/researchValidation'
|
||||||
import { useMissionHandler } from '@/composables/useMissionHandler'
|
import * as fleetLogic from '@/logic/fleetLogic'
|
||||||
import { useNPCHandler } from '@/composables/useNPCHandler'
|
import * as shipLogic from '@/logic/shipLogic'
|
||||||
import { useQueueHandler } from '@/composables/useQueueHandler'
|
import * as npcGrowthLogic from '@/logic/npcGrowthLogic'
|
||||||
import { useGameUpdate } from '@/composables/useGameUpdate'
|
import * as npcBehaviorLogic from '@/logic/npcBehaviorLogic'
|
||||||
import { migrateGameData } from '@/utils/migration'
|
import * as diplomaticLogic from '@/logic/diplomaticLogic'
|
||||||
import pkg from '../package.json'
|
import pkg from '../package.json'
|
||||||
|
import { toast } from 'vue-sonner'
|
||||||
|
import { migrateGameData } from '@/utils/migration'
|
||||||
|
import { checkLatestVersion } from '@/utils/versionCheck'
|
||||||
|
|
||||||
|
// 执行数据迁移(在 store 初始化之前)
|
||||||
migrateGameData()
|
migrateGameData()
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
const gameStore = useGameStore()
|
const gameStore = useGameStore()
|
||||||
|
const universeStore = useUniverseStore()
|
||||||
|
const npcStore = useNPCStore()
|
||||||
const { isDark } = useTheme()
|
const { isDark } = useTheme()
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
const { BUILDINGS } = useGameConfig()
|
||||||
|
const { startTutorial, tutorialState, currentStep } = useTutorial()
|
||||||
|
|
||||||
|
// ConfirmDialog 状态
|
||||||
const confirmDialogOpen = ref(false)
|
const confirmDialogOpen = ref(false)
|
||||||
const confirmDialogTitle = ref('')
|
const confirmDialogTitle = ref('')
|
||||||
const confirmDialogMessage = ref('')
|
const confirmDialogMessage = ref('')
|
||||||
|
const innerWidth = computed(() => window.innerWidth)
|
||||||
const confirmDialogAction = ref<(() => void) | null>(null)
|
const confirmDialogAction = ref<(() => void) | null>(null)
|
||||||
|
|
||||||
|
// 更新弹窗状态
|
||||||
|
const showUpdateDialog = ref(false)
|
||||||
|
const updateInfo = ref<VersionInfo | null>(null)
|
||||||
|
|
||||||
|
const handleConfirmDialogConfirm = () => {
|
||||||
|
if (confirmDialogAction.value) {
|
||||||
|
confirmDialogAction.value()
|
||||||
|
}
|
||||||
|
confirmDialogOpen.value = false
|
||||||
|
}
|
||||||
|
|
||||||
// 所有可用的语言选项
|
// 所有可用的语言选项
|
||||||
const locales: Locale[] = ['zh-CN', 'zh-TW', 'en', 'de', 'ru', 'ko', 'ja']
|
const locales: Locale[] = ['zh-CN', 'zh-TW', 'en', 'de', 'ru', 'ko', 'ja']
|
||||||
|
|
||||||
// 侧边栏状态(不持久化,根据屏幕尺寸初始化)
|
// 侧边栏状态(不持久化,根据屏幕尺寸初始化)
|
||||||
|
// PC端(≥1024px)默认打开,移动端默认关闭
|
||||||
const sidebarOpen = ref(window.innerWidth >= 1024)
|
const sidebarOpen = ref(window.innerWidth >= 1024)
|
||||||
|
|
||||||
// 初始化 composables
|
// 移动端资源栏展开状态
|
||||||
const { initGame } = useGameLifecycle()
|
const resourceBarExpanded = ref(false)
|
||||||
|
|
||||||
const { processMissionArrival, processMissionReturn } = useMissionHandler(t)
|
const initGame = async () => {
|
||||||
|
const shouldInit = gameLogic.shouldInitializeGame(gameStore.player.planets)
|
||||||
|
if (!shouldInit) {
|
||||||
|
const now = Date.now()
|
||||||
|
|
||||||
const { processNPCMissionArrival, processNPCMissionReturn, updateNPCGrowth, updateNPCBehavior } = useNPCHandler()
|
// 计算离线收益(直接同步计算,应用游戏速度)
|
||||||
|
const bonuses = officerLogic.calculateActiveBonuses(gameStore.player.officers, now)
|
||||||
|
gameStore.player.planets.forEach(planet => {
|
||||||
|
resourceLogic.updatePlanetResources(planet, now, bonuses, gameStore.gameSpeed)
|
||||||
|
})
|
||||||
|
|
||||||
const { handleCancelBuild, handleCancelResearch, getItemName, getRemainingTime, getQueueProgress } = useQueueHandler(
|
// 只在没有NPC星球时才生成(首次加载已有玩家数据时)
|
||||||
t,
|
if (Object.keys(universeStore.planets).length === 0) {
|
||||||
confirmDialogOpen,
|
generateNPCPlanets()
|
||||||
confirmDialogTitle,
|
}
|
||||||
confirmDialogMessage,
|
return
|
||||||
confirmDialogAction
|
}
|
||||||
)
|
gameStore.player = gameLogic.initializePlayer(gameStore.player.id, t('common.playerName'))
|
||||||
|
const initialPlanet = planetLogic.createInitialPlanet(gameStore.player.id, t('planet.homePlanet'))
|
||||||
|
gameStore.player.planets = [initialPlanet]
|
||||||
|
gameStore.currentPlanetId = initialPlanet.id
|
||||||
|
// 新玩家初始化时生成NPC星球
|
||||||
|
generateNPCPlanets()
|
||||||
|
}
|
||||||
|
|
||||||
const { updateGame } = useGameUpdate(
|
const generateNPCPlanets = () => {
|
||||||
processMissionArrival,
|
const npcCount = 200
|
||||||
processMissionReturn,
|
for (let i = 0; i < npcCount; i++) {
|
||||||
processNPCMissionArrival,
|
const position = gameLogic.generateRandomPosition()
|
||||||
processNPCMissionReturn,
|
const key = gameLogic.generatePositionKey(position.galaxy, position.system, position.position)
|
||||||
updateNPCGrowth,
|
if (universeStore.planets[key]) continue
|
||||||
updateNPCBehavior
|
const npcPlanet = planetLogic.createNPCPlanet(i, position, t('planet.planetPrefix'))
|
||||||
)
|
universeStore.planets[key] = npcPlanet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateGame = async () => {
|
||||||
|
const now = Date.now()
|
||||||
|
gameStore.gameTime = now
|
||||||
|
if (gameStore.isPaused) return
|
||||||
|
// 检查军官过期
|
||||||
|
gameLogic.checkOfficersExpiration(gameStore.player.officers, now)
|
||||||
|
// 处理游戏更新(建造队列、研究队列等)
|
||||||
|
const result = gameLogic.processGameUpdate(gameStore.player, now, gameStore.gameSpeed)
|
||||||
|
gameStore.player.researchQueue = result.updatedResearchQueue
|
||||||
|
// 处理舰队任务
|
||||||
|
gameStore.player.fleetMissions.forEach(mission => {
|
||||||
|
if (mission.status === 'outbound' && now >= mission.arrivalTime) {
|
||||||
|
processMissionArrival(mission)
|
||||||
|
} else if (mission.status === 'returning' && mission.returnTime && now >= mission.returnTime) {
|
||||||
|
processMissionReturn(mission)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 处理导弹攻击任务(使用反向循环以便安全删除)
|
||||||
|
for (let i = gameStore.player.missileAttacks.length - 1; i >= 0; i--) {
|
||||||
|
const missileAttack = gameStore.player.missileAttacks[i]
|
||||||
|
if (missileAttack && missileAttack.status === 'flying' && now >= missileAttack.arrivalTime) {
|
||||||
|
await processMissileAttackArrival(missileAttack)
|
||||||
|
// 导弹攻击是单程的,到达后直接从数组中移除
|
||||||
|
gameStore.player.missileAttacks.splice(i, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理NPC舰队任务
|
||||||
|
npcStore.npcs.forEach(npc => {
|
||||||
|
if (npc.fleetMissions) {
|
||||||
|
npc.fleetMissions.forEach(mission => {
|
||||||
|
if (mission.status === 'outbound' && now >= mission.arrivalTime) {
|
||||||
|
processNPCMissionArrival(npc, mission)
|
||||||
|
} else if (mission.status === 'returning' && mission.returnTime && now >= mission.returnTime) {
|
||||||
|
processNPCMissionReturn(npc, mission)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// NPC成长系统更新
|
||||||
|
updateNPCGrowth(1)
|
||||||
|
|
||||||
|
// NPC行为系统更新(侦查和攻击决策)
|
||||||
|
updateNPCBehavior(1)
|
||||||
|
|
||||||
|
// 检查并处理被消灭的NPC(所有星球都被摧毁的NPC)
|
||||||
|
const eliminatedNpcIds = diplomaticLogic.checkAndHandleEliminatedNPCs(npcStore.npcs, gameStore.player, gameStore.locale)
|
||||||
|
if (eliminatedNpcIds.length > 0) {
|
||||||
|
// 从universeStore中移除被消灭NPC的星球数据
|
||||||
|
eliminatedNpcIds.forEach(npcId => {
|
||||||
|
const npc = npcStore.npcs.find(n => n.id === npcId)
|
||||||
|
if (npc && npc.planets) {
|
||||||
|
// 遍历NPC的所有星球,从universeStore中删除
|
||||||
|
npc.planets.forEach(planet => {
|
||||||
|
const planetKey = gameLogic.generatePositionKey(planet.position.galaxy, planet.position.system, planet.position.position)
|
||||||
|
if (universeStore.planets[planetKey]) {
|
||||||
|
delete universeStore.planets[planetKey]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 从NPC列表中移除被消灭的NPC
|
||||||
|
npcStore.npcs = npcStore.npcs.filter(npc => !eliminatedNpcIds.includes(npc.id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const processMissionArrival = async (mission: FleetMission) => {
|
||||||
|
// 从宇宙星球地图中查找目标星球
|
||||||
|
const targetKey = gameLogic.generatePositionKey(
|
||||||
|
mission.targetPosition.galaxy,
|
||||||
|
mission.targetPosition.system,
|
||||||
|
mission.targetPosition.position
|
||||||
|
)
|
||||||
|
// 先从玩家星球中查找,再从宇宙地图中查找
|
||||||
|
const targetPlanet =
|
||||||
|
gameStore.player.planets.find(
|
||||||
|
p =>
|
||||||
|
p.position.galaxy === mission.targetPosition.galaxy &&
|
||||||
|
p.position.system === mission.targetPosition.system &&
|
||||||
|
p.position.position === mission.targetPosition.position
|
||||||
|
) || universeStore.planets[targetKey]
|
||||||
|
|
||||||
|
// 获取起始星球名称(用于报告)
|
||||||
|
const originPlanet = gameStore.player.planets.find(p => p.id === mission.originPlanetId)
|
||||||
|
const originPlanetName = originPlanet?.name || t('fleetView.unknownPlanet')
|
||||||
|
|
||||||
|
if (mission.missionType === MissionType.Transport) {
|
||||||
|
const result = fleetLogic.processTransportArrival(mission, targetPlanet, gameStore.player, npcStore.npcs)
|
||||||
|
// 生成运输任务报告
|
||||||
|
if (!gameStore.player.missionReports) {
|
||||||
|
gameStore.player.missionReports = []
|
||||||
|
}
|
||||||
|
gameStore.player.missionReports.push({
|
||||||
|
id: `mission-report-${mission.id}`,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
missionType: MissionType.Transport,
|
||||||
|
originPlanetId: mission.originPlanetId,
|
||||||
|
originPlanetName,
|
||||||
|
targetPosition: mission.targetPosition,
|
||||||
|
targetPlanetId: targetPlanet?.id,
|
||||||
|
targetPlanetName:
|
||||||
|
targetPlanet?.name || `[${mission.targetPosition.galaxy}:${mission.targetPosition.system}:${mission.targetPosition.position}]`,
|
||||||
|
success: result.success,
|
||||||
|
message: result.success ? t('missionReports.transportSuccess') : t('missionReports.transportFailed'),
|
||||||
|
details: {
|
||||||
|
transportedResources: mission.cargo
|
||||||
|
},
|
||||||
|
read: false
|
||||||
|
})
|
||||||
|
} else if (mission.missionType === MissionType.Attack) {
|
||||||
|
const attackResult = await fleetLogic.processAttackArrival(mission, targetPlanet, gameStore.player, null, gameStore.player.planets)
|
||||||
|
if (attackResult) {
|
||||||
|
gameStore.player.battleReports.push(attackResult.battleResult)
|
||||||
|
|
||||||
|
// 检查是否攻击了NPC星球,更新外交关系
|
||||||
|
if (targetPlanet) {
|
||||||
|
const targetNpc = npcStore.npcs.find(npc => npc.planets.some(p => p.id === targetPlanet.id))
|
||||||
|
if (targetNpc) {
|
||||||
|
diplomaticLogic.handleAttackReputation(gameStore.player, targetNpc, attackResult.battleResult, npcStore.npcs, gameStore.locale)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attackResult.moon) {
|
||||||
|
gameStore.player.planets.push(attackResult.moon)
|
||||||
|
}
|
||||||
|
if (attackResult.debrisField) {
|
||||||
|
// 将残骸场添加到游戏状态
|
||||||
|
universeStore.debrisFields[attackResult.debrisField.id] = attackResult.debrisField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (mission.missionType === MissionType.Colonize) {
|
||||||
|
const newPlanet = fleetLogic.processColonizeArrival(mission, targetPlanet, gameStore.player, t('planet.colonyPrefix'))
|
||||||
|
// 生成殖民任务报告
|
||||||
|
if (!gameStore.player.missionReports) {
|
||||||
|
gameStore.player.missionReports = []
|
||||||
|
}
|
||||||
|
gameStore.player.missionReports.push({
|
||||||
|
id: `mission-report-${mission.id}`,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
missionType: MissionType.Colonize,
|
||||||
|
originPlanetId: mission.originPlanetId,
|
||||||
|
originPlanetName,
|
||||||
|
targetPosition: mission.targetPosition,
|
||||||
|
targetPlanetId: newPlanet?.id,
|
||||||
|
targetPlanetName: newPlanet?.name,
|
||||||
|
success: !!newPlanet,
|
||||||
|
message: newPlanet ? t('missionReports.colonizeSuccess') : t('missionReports.colonizeFailed'),
|
||||||
|
details: newPlanet
|
||||||
|
? {
|
||||||
|
newPlanetId: newPlanet.id,
|
||||||
|
newPlanetName: newPlanet.name
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
read: false
|
||||||
|
})
|
||||||
|
if (newPlanet) {
|
||||||
|
gameStore.player.planets.push(newPlanet)
|
||||||
|
}
|
||||||
|
} else if (mission.missionType === MissionType.Spy) {
|
||||||
|
const spyReport = fleetLogic.processSpyArrival(mission, targetPlanet, gameStore.player, null, npcStore.npcs)
|
||||||
|
if (spyReport) gameStore.player.spyReports.push(spyReport)
|
||||||
|
} else if (mission.missionType === MissionType.Deploy) {
|
||||||
|
const deployed = fleetLogic.processDeployArrival(mission, targetPlanet, gameStore.player.id)
|
||||||
|
// 生成部署任务报告
|
||||||
|
if (!gameStore.player.missionReports) {
|
||||||
|
gameStore.player.missionReports = []
|
||||||
|
}
|
||||||
|
gameStore.player.missionReports.push({
|
||||||
|
id: `mission-report-${mission.id}`,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
missionType: MissionType.Deploy,
|
||||||
|
originPlanetId: mission.originPlanetId,
|
||||||
|
originPlanetName,
|
||||||
|
targetPosition: mission.targetPosition,
|
||||||
|
targetPlanetId: targetPlanet?.id,
|
||||||
|
targetPlanetName:
|
||||||
|
targetPlanet?.name || `[${mission.targetPosition.galaxy}:${mission.targetPosition.system}:${mission.targetPosition.position}]`,
|
||||||
|
success: deployed,
|
||||||
|
message: deployed ? t('missionReports.deploySuccess') : t('missionReports.deployFailed'),
|
||||||
|
details: {
|
||||||
|
deployedFleet: mission.fleet
|
||||||
|
},
|
||||||
|
read: false
|
||||||
|
})
|
||||||
|
if (deployed) {
|
||||||
|
const missionIndex = gameStore.player.fleetMissions.indexOf(mission)
|
||||||
|
if (missionIndex > -1) gameStore.player.fleetMissions.splice(missionIndex, 1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else if (mission.missionType === MissionType.Recycle) {
|
||||||
|
// 处理回收任务
|
||||||
|
const debrisId = `debris_${mission.targetPosition.galaxy}_${mission.targetPosition.system}_${mission.targetPosition.position}`
|
||||||
|
const debrisField = universeStore.debrisFields[debrisId]
|
||||||
|
const recycleResult = fleetLogic.processRecycleArrival(mission, debrisField)
|
||||||
|
|
||||||
|
// 生成回收任务报告
|
||||||
|
if (!gameStore.player.missionReports) {
|
||||||
|
gameStore.player.missionReports = []
|
||||||
|
}
|
||||||
|
gameStore.player.missionReports.push({
|
||||||
|
id: `mission-report-${mission.id}`,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
missionType: MissionType.Recycle,
|
||||||
|
originPlanetId: mission.originPlanetId,
|
||||||
|
originPlanetName,
|
||||||
|
targetPosition: mission.targetPosition,
|
||||||
|
success: !!recycleResult,
|
||||||
|
message: recycleResult ? t('missionReports.recycleSuccess') : t('missionReports.recycleFailed'),
|
||||||
|
details: recycleResult
|
||||||
|
? {
|
||||||
|
recycledResources: recycleResult.collectedResources,
|
||||||
|
remainingDebris: recycleResult.remainingDebris || undefined
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
read: false
|
||||||
|
})
|
||||||
|
|
||||||
|
if (recycleResult && debrisField) {
|
||||||
|
if (recycleResult.remainingDebris && (recycleResult.remainingDebris.metal > 0 || recycleResult.remainingDebris.crystal > 0)) {
|
||||||
|
// 更新残骸场
|
||||||
|
universeStore.debrisFields[debrisId] = {
|
||||||
|
id: debrisField.id,
|
||||||
|
position: debrisField.position,
|
||||||
|
resources: recycleResult.remainingDebris,
|
||||||
|
createdAt: debrisField.createdAt,
|
||||||
|
expiresAt: debrisField.expiresAt
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 残骸场已被完全收集,删除
|
||||||
|
delete universeStore.debrisFields[debrisId]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (mission.missionType === MissionType.Destroy) {
|
||||||
|
// 处理行星毁灭任务
|
||||||
|
const destroyResult = fleetLogic.processDestroyArrival(mission, targetPlanet, gameStore.player)
|
||||||
|
|
||||||
|
// 生成毁灭任务报告
|
||||||
|
if (!gameStore.player.missionReports) {
|
||||||
|
gameStore.player.missionReports = []
|
||||||
|
}
|
||||||
|
gameStore.player.missionReports.push({
|
||||||
|
id: `mission-report-${mission.id}`,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
missionType: MissionType.Destroy,
|
||||||
|
originPlanetId: mission.originPlanetId,
|
||||||
|
originPlanetName,
|
||||||
|
targetPosition: mission.targetPosition,
|
||||||
|
targetPlanetId: targetPlanet?.id,
|
||||||
|
targetPlanetName: targetPlanet?.name,
|
||||||
|
success: destroyResult?.success || false,
|
||||||
|
message: destroyResult?.success ? t('missionReports.destroySuccess') : t('missionReports.destroyFailed'),
|
||||||
|
details: destroyResult?.success
|
||||||
|
? {
|
||||||
|
destroyedPlanetName:
|
||||||
|
targetPlanet?.name ||
|
||||||
|
`[${mission.targetPosition.galaxy}:${mission.targetPosition.system}:${mission.targetPosition.position}]`
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
read: false
|
||||||
|
})
|
||||||
|
|
||||||
|
if (destroyResult && destroyResult.success && destroyResult.planetId) {
|
||||||
|
// 星球被摧毁
|
||||||
|
|
||||||
|
// 处理外交关系(如果目标是NPC星球)
|
||||||
|
if (targetPlanet && targetPlanet.ownerId) {
|
||||||
|
const planetOwner = npcStore.npcs.find(npc => npc.id === targetPlanet.ownerId)
|
||||||
|
if (planetOwner) {
|
||||||
|
diplomaticLogic.handlePlanetDestructionReputation(gameStore.player, targetPlanet, planetOwner, npcStore.npcs, gameStore.locale)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从玩家星球列表中移除(如果是玩家的星球)
|
||||||
|
const planetIndex = gameStore.player.planets.findIndex(p => p.id === destroyResult.planetId)
|
||||||
|
if (planetIndex > -1) {
|
||||||
|
gameStore.player.planets.splice(planetIndex, 1)
|
||||||
|
} else {
|
||||||
|
// 不是玩家星球,从宇宙地图中移除
|
||||||
|
delete universeStore.planets[targetKey]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const processMissionReturn = (mission: FleetMission) => {
|
||||||
|
const originPlanet = gameStore.player.planets.find(p => p.id === mission.originPlanetId)
|
||||||
|
if (!originPlanet) return
|
||||||
|
shipLogic.addFleet(originPlanet.fleet, mission.fleet)
|
||||||
|
resourceLogic.addResources(originPlanet.resources, mission.cargo)
|
||||||
|
const missionIndex = gameStore.player.fleetMissions.indexOf(mission)
|
||||||
|
if (missionIndex > -1) gameStore.player.fleetMissions.splice(missionIndex, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NPC任务处理
|
||||||
|
const processNPCMissionArrival = (npc: NPC, mission: FleetMission) => {
|
||||||
|
if (mission.missionType === MissionType.Recycle) {
|
||||||
|
// NPC回收任务到达
|
||||||
|
const debrisId = mission.debrisFieldId
|
||||||
|
if (!debrisId) {
|
||||||
|
console.warn('[NPC Mission] Recycle mission missing debrisFieldId')
|
||||||
|
mission.status = 'returning'
|
||||||
|
mission.returnTime = Date.now() + (mission.arrivalTime - mission.departureTime)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const debrisField = universeStore.debrisFields[debrisId]
|
||||||
|
const recycleResult = fleetLogic.processRecycleArrival(mission, debrisField)
|
||||||
|
|
||||||
|
if (recycleResult && debrisField) {
|
||||||
|
if (recycleResult.remainingDebris && (recycleResult.remainingDebris.metal > 0 || recycleResult.remainingDebris.crystal > 0)) {
|
||||||
|
// 更新残骸场
|
||||||
|
universeStore.debrisFields[debrisId] = {
|
||||||
|
id: debrisField.id,
|
||||||
|
position: debrisField.position,
|
||||||
|
resources: recycleResult.remainingDebris,
|
||||||
|
createdAt: debrisField.createdAt
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 残骸已被完全回收,从宇宙中删除
|
||||||
|
delete universeStore.debrisFields[debrisId]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除即将到来的警告(回收任务已到达)
|
||||||
|
removeIncomingFleetAlertById(mission.id)
|
||||||
|
|
||||||
|
// 设置返回时间
|
||||||
|
mission.returnTime = Date.now() + (mission.arrivalTime - mission.departureTime)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 找到目标星球
|
||||||
|
const targetKey = gameLogic.generatePositionKey(
|
||||||
|
mission.targetPosition.galaxy,
|
||||||
|
mission.targetPosition.system,
|
||||||
|
mission.targetPosition.position
|
||||||
|
)
|
||||||
|
const targetPlanet =
|
||||||
|
gameStore.player.planets.find(
|
||||||
|
p =>
|
||||||
|
p.position.galaxy === mission.targetPosition.galaxy &&
|
||||||
|
p.position.system === mission.targetPosition.system &&
|
||||||
|
p.position.position === mission.targetPosition.position
|
||||||
|
) || universeStore.planets[targetKey]
|
||||||
|
|
||||||
|
if (!targetPlanet) {
|
||||||
|
console.warn('[NPC Mission] Target planet not found')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mission.missionType === MissionType.Spy) {
|
||||||
|
// NPC侦查到达
|
||||||
|
const { spiedNotification, spyReport } = npcBehaviorLogic.processNPCSpyArrival(npc, mission, targetPlanet, gameStore.player)
|
||||||
|
|
||||||
|
// 保存侦查报告到NPC(用于后续攻击决策)
|
||||||
|
if (!npc.playerSpyReports) {
|
||||||
|
npc.playerSpyReports = {}
|
||||||
|
}
|
||||||
|
npc.playerSpyReports[targetPlanet.id] = spyReport
|
||||||
|
|
||||||
|
// 添加被侦查通知给玩家
|
||||||
|
if (!gameStore.player.spiedNotifications) {
|
||||||
|
gameStore.player.spiedNotifications = []
|
||||||
|
}
|
||||||
|
gameStore.player.spiedNotifications.push(spiedNotification)
|
||||||
|
|
||||||
|
// 移除即将到来的警告(侦查已到达)
|
||||||
|
removeIncomingFleetAlertById(mission.id)
|
||||||
|
} else if (mission.missionType === MissionType.Attack) {
|
||||||
|
// NPC攻击到达 - 使用专门的NPC攻击处理逻辑
|
||||||
|
fleetLogic.processNPCAttackArrival(npc, mission, targetPlanet, gameStore.player, gameStore.player.planets).then(attackResult => {
|
||||||
|
if (attackResult) {
|
||||||
|
// 添加战斗报告给玩家
|
||||||
|
gameStore.player.battleReports.push(attackResult.battleResult)
|
||||||
|
|
||||||
|
// 如果生成月球,添加到玩家星球列表
|
||||||
|
if (attackResult.moon) {
|
||||||
|
gameStore.player.planets.push(attackResult.moon)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果生成残骸场,添加到宇宙残骸场列表
|
||||||
|
if (attackResult.debrisField) {
|
||||||
|
universeStore.debrisFields[attackResult.debrisField.id] = attackResult.debrisField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除即将到来的警告(攻击已到达)
|
||||||
|
removeIncomingFleetAlertById(mission.id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const processNPCMissionReturn = (npc: NPC, mission: FleetMission) => {
|
||||||
|
// 找到NPC的起始星球
|
||||||
|
const originPlanet = npc.planets.find(p => p.id === mission.originPlanetId)
|
||||||
|
if (!originPlanet) return
|
||||||
|
|
||||||
|
// 返还舰队
|
||||||
|
shipLogic.addFleet(originPlanet.fleet, mission.fleet)
|
||||||
|
|
||||||
|
// 如果携带掠夺资源,给NPC添加资源
|
||||||
|
if (mission.cargo) {
|
||||||
|
originPlanet.resources.metal += mission.cargo.metal
|
||||||
|
originPlanet.resources.crystal += mission.cargo.crystal
|
||||||
|
originPlanet.resources.deuterium += mission.cargo.deuterium
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从NPC任务列表中移除
|
||||||
|
if (npc.fleetMissions) {
|
||||||
|
const missionIndex = npc.fleetMissions.indexOf(mission)
|
||||||
|
if (missionIndex > -1) {
|
||||||
|
npc.fleetMissions.splice(missionIndex, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理导弹攻击到达
|
||||||
|
const processMissileAttackArrival = async (missileAttack: MissileAttack) => {
|
||||||
|
// 动态导入导弹逻辑
|
||||||
|
const missileLogic = await import('@/logic/missileLogic')
|
||||||
|
|
||||||
|
// 找到目标星球
|
||||||
|
const targetKey = gameLogic.generatePositionKey(
|
||||||
|
missileAttack.targetPosition.galaxy,
|
||||||
|
missileAttack.targetPosition.system,
|
||||||
|
missileAttack.targetPosition.position
|
||||||
|
)
|
||||||
|
const targetPlanet =
|
||||||
|
gameStore.player.planets.find(
|
||||||
|
p =>
|
||||||
|
p.position.galaxy === missileAttack.targetPosition.galaxy &&
|
||||||
|
p.position.system === missileAttack.targetPosition.system &&
|
||||||
|
p.position.position === missileAttack.targetPosition.position
|
||||||
|
) || universeStore.planets[targetKey]
|
||||||
|
|
||||||
|
// 如果目标星球不存在,导弹失败
|
||||||
|
if (!targetPlanet) {
|
||||||
|
missileAttack.status = 'arrived'
|
||||||
|
// 生成失败报告
|
||||||
|
if (!gameStore.player.missionReports) {
|
||||||
|
gameStore.player.missionReports = []
|
||||||
|
}
|
||||||
|
gameStore.player.missionReports.push({
|
||||||
|
id: `missile-report-${missileAttack.id}`,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
missionType: MissionType.MissileAttack,
|
||||||
|
originPlanetId: missileAttack.originPlanetId,
|
||||||
|
originPlanetName: gameStore.player.planets.find(p => p.id === missileAttack.originPlanetId)?.name || t('fleetView.unknownPlanet'),
|
||||||
|
targetPosition: missileAttack.targetPosition,
|
||||||
|
targetPlanetId: undefined,
|
||||||
|
targetPlanetName: `[${missileAttack.targetPosition.galaxy}:${missileAttack.targetPosition.system}:${missileAttack.targetPosition.position}]`,
|
||||||
|
success: false,
|
||||||
|
message: t('missionReports.missileAttackFailed'),
|
||||||
|
details: {
|
||||||
|
missileCount: missileAttack.missileCount,
|
||||||
|
missileHits: 0,
|
||||||
|
missileIntercepted: 0,
|
||||||
|
defenseLosses: {}
|
||||||
|
},
|
||||||
|
read: false
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算导弹攻击结果
|
||||||
|
const impactResult = missileLogic.calculateMissileImpact(missileAttack.missileCount, targetPlanet)
|
||||||
|
|
||||||
|
// 应用损失到目标星球
|
||||||
|
missileLogic.applyMissileAttackResult(targetPlanet, impactResult.defenseLosses)
|
||||||
|
|
||||||
|
// 如果目标是NPC的星球,扣除外交好感度
|
||||||
|
if (targetPlanet.ownerId && targetPlanet.ownerId !== gameStore.player.id) {
|
||||||
|
const targetNpc = npcStore.npcs.find(npc => npc.id === targetPlanet.ownerId)
|
||||||
|
if (targetNpc) {
|
||||||
|
// 导弹攻击扣除好感度
|
||||||
|
const { REPUTATION_CHANGES } = DIPLOMATIC_CONFIG
|
||||||
|
const reputationLoss = REPUTATION_CHANGES.ATTACK / 2 // 导弹攻击的好感度惩罚是普通攻击的一半
|
||||||
|
|
||||||
|
// 更新玩家对NPC的关系
|
||||||
|
if (!gameStore.player.diplomaticRelations) {
|
||||||
|
gameStore.player.diplomaticRelations = {}
|
||||||
|
}
|
||||||
|
const relation = diplomaticLogic.getOrCreateRelation(
|
||||||
|
gameStore.player.diplomaticRelations,
|
||||||
|
gameStore.player.id,
|
||||||
|
targetNpc.id
|
||||||
|
)
|
||||||
|
gameStore.player.diplomaticRelations[targetNpc.id] = diplomaticLogic.updateReputation(
|
||||||
|
relation,
|
||||||
|
reputationLoss,
|
||||||
|
DiplomaticEventType.Attack,
|
||||||
|
t('diplomacy.reports.missileAttackNpc', { npcName: targetNpc.name })
|
||||||
|
)
|
||||||
|
|
||||||
|
// 更新NPC对玩家的关系
|
||||||
|
if (!targetNpc.relations) {
|
||||||
|
targetNpc.relations = {}
|
||||||
|
}
|
||||||
|
const npcRelation = diplomaticLogic.getOrCreateRelation(targetNpc.relations, targetNpc.id, gameStore.player.id)
|
||||||
|
targetNpc.relations[gameStore.player.id] = diplomaticLogic.updateReputation(
|
||||||
|
npcRelation,
|
||||||
|
reputationLoss,
|
||||||
|
DiplomaticEventType.Attack,
|
||||||
|
t('diplomacy.reports.wasAttackedByMissile')
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标记导弹攻击为已到达
|
||||||
|
missileAttack.status = 'arrived'
|
||||||
|
|
||||||
|
// 生成导弹攻击报告
|
||||||
|
if (!gameStore.player.missionReports) {
|
||||||
|
gameStore.player.missionReports = []
|
||||||
|
}
|
||||||
|
const reportMessage =
|
||||||
|
impactResult.missileHits > 0
|
||||||
|
? `${t('missionReports.missileAttackSuccess')}: ${impactResult.missileHits} ${t('missionReports.hits')}`
|
||||||
|
: t('missionReports.missileAttackIntercepted')
|
||||||
|
|
||||||
|
gameStore.player.missionReports.push({
|
||||||
|
id: `missile-report-${missileAttack.id}`,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
missionType: MissionType.MissileAttack,
|
||||||
|
originPlanetId: missileAttack.originPlanetId,
|
||||||
|
originPlanetName: gameStore.player.planets.find(p => p.id === missileAttack.originPlanetId)?.name || t('fleetView.unknownPlanet'),
|
||||||
|
targetPosition: missileAttack.targetPosition,
|
||||||
|
targetPlanetId: targetPlanet.id,
|
||||||
|
targetPlanetName: targetPlanet.name,
|
||||||
|
success: true,
|
||||||
|
message: reportMessage,
|
||||||
|
details: {
|
||||||
|
missileCount: missileAttack.missileCount,
|
||||||
|
missileHits: impactResult.missileHits,
|
||||||
|
missileIntercepted: impactResult.missileIntercepted,
|
||||||
|
defenseLosses: impactResult.defenseLosses
|
||||||
|
},
|
||||||
|
read: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除即将到来的舰队警告
|
||||||
|
const removeIncomingFleetAlert = (alert: IncomingFleetAlert) => {
|
||||||
|
if (!gameStore.player.incomingFleetAlerts) return
|
||||||
|
const index = gameStore.player.incomingFleetAlerts.indexOf(alert)
|
||||||
|
if (index > -1) {
|
||||||
|
gameStore.player.incomingFleetAlerts.splice(index, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const removeIncomingFleetAlertById = (missionId: string) => {
|
||||||
|
if (!gameStore.player.incomingFleetAlerts) return
|
||||||
|
const index = gameStore.player.incomingFleetAlerts.findIndex(a => a.id === missionId)
|
||||||
|
if (index > -1) {
|
||||||
|
gameStore.player.incomingFleetAlerts.splice(index, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NPC成长系统更新函数
|
||||||
|
let npcUpdateCounter = 0 // 累计秒数
|
||||||
|
const NPC_UPDATE_INTERVAL = 1 // 每1秒更新一次NPC,确保发育速度与玩家相当
|
||||||
|
|
||||||
|
const updateNPCGrowth = (deltaSeconds: number) => {
|
||||||
|
// 累积时间
|
||||||
|
npcUpdateCounter += deltaSeconds
|
||||||
|
|
||||||
|
// 只在达到更新间隔时才执行
|
||||||
|
if (npcUpdateCounter < NPC_UPDATE_INTERVAL) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取所有星球
|
||||||
|
const allPlanets = Object.values(universeStore.planets)
|
||||||
|
|
||||||
|
// 如果NPC store为空,从星球数据中初始化NPC
|
||||||
|
if (npcStore.npcs.length === 0) {
|
||||||
|
const npcMap = new Map<string, any>()
|
||||||
|
|
||||||
|
allPlanets.forEach(planet => {
|
||||||
|
// 跳过玩家的星球
|
||||||
|
if (planet.ownerId === gameStore.player.id || !planet.ownerId) return
|
||||||
|
|
||||||
|
// 这是NPC的星球
|
||||||
|
if (!npcMap.has(planet.ownerId)) {
|
||||||
|
npcMap.set(planet.ownerId, {
|
||||||
|
id: planet.ownerId,
|
||||||
|
name: `NPC-${planet.ownerId.substring(0, 8)}`,
|
||||||
|
planets: [],
|
||||||
|
technologies: {}, // 初始化空科技树
|
||||||
|
difficulty: 'medium' as const, // 默认中等难度
|
||||||
|
relations: {}, // 外交关系
|
||||||
|
allies: [], // 盟友列表
|
||||||
|
enemies: [] // 敌人列表
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
npcMap.get(planet.ownerId)!.planets.push(planet)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 保存到store
|
||||||
|
npcStore.npcs = Array.from(npcMap.values())
|
||||||
|
|
||||||
|
// 如果有NPC,基于玩家实力初始化NPC
|
||||||
|
if (npcStore.npcs.length > 0) {
|
||||||
|
const gameState: npcGrowthLogic.NPCGrowthGameState = {
|
||||||
|
planets: allPlanets,
|
||||||
|
player: gameStore.player,
|
||||||
|
npcs: npcStore.npcs
|
||||||
|
}
|
||||||
|
|
||||||
|
const playerPower = npcGrowthLogic.calculatePlayerAveragePower(gameState)
|
||||||
|
|
||||||
|
npcStore.npcs.forEach(npc => {
|
||||||
|
npcGrowthLogic.initializeNPCStartingPower(npc, playerPower)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 初始化NPC之间的外交关系(盟友/敌人)
|
||||||
|
npcGrowthLogic.initializeNPCDiplomacy(npcStore.npcs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有NPC,直接返回
|
||||||
|
if (npcStore.npcs.length === 0) {
|
||||||
|
npcUpdateCounter = 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建游戏状态
|
||||||
|
const gameState: npcGrowthLogic.NPCGrowthGameState = {
|
||||||
|
planets: allPlanets,
|
||||||
|
player: gameStore.player,
|
||||||
|
npcs: npcStore.npcs
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用累积的时间更新每个NPC
|
||||||
|
npcStore.npcs.forEach(npc => {
|
||||||
|
npcGrowthLogic.updateNPCGrowth(npc, gameState, npcUpdateCounter)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 重置计数器
|
||||||
|
npcUpdateCounter = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// NPC行为系统更新函数(侦查和攻击决策)
|
||||||
|
let npcBehaviorCounter = 0
|
||||||
|
const NPC_BEHAVIOR_INTERVAL = 5 // 每5秒检查一次NPC行为
|
||||||
|
|
||||||
|
const updateNPCBehavior = (deltaSeconds: number) => {
|
||||||
|
// 累积时间
|
||||||
|
npcBehaviorCounter += deltaSeconds
|
||||||
|
|
||||||
|
// 只在达到更新间隔时才执行
|
||||||
|
if (npcBehaviorCounter < NPC_BEHAVIOR_INTERVAL) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有NPC,直接返回
|
||||||
|
if (npcStore.npcs.length === 0) {
|
||||||
|
npcBehaviorCounter = 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const now = Date.now()
|
||||||
|
const allPlanets = Object.values(universeStore.planets)
|
||||||
|
|
||||||
|
// 更新每个NPC的行为
|
||||||
|
npcStore.npcs.forEach(npc => {
|
||||||
|
npcBehaviorLogic.updateNPCBehavior(npc, gameStore.player, allPlanets, universeStore.debrisFields, now)
|
||||||
|
})
|
||||||
|
|
||||||
|
npcBehaviorCounter = 0
|
||||||
|
}
|
||||||
|
|
||||||
// 游戏循环定时器
|
// 游戏循环定时器
|
||||||
let gameLoop: ReturnType<typeof setInterval> | null = null
|
let gameLoop: ReturnType<typeof setInterval> | null = null
|
||||||
|
let konamiCleanup: (() => void) | null = null
|
||||||
|
let versionCheckInterval: ReturnType<typeof setInterval> | null = null
|
||||||
|
|
||||||
// 清理定时器
|
// 启动游戏循环
|
||||||
onUnmounted(() => {
|
const startGameLoop = () => {
|
||||||
if (gameLoop) clearInterval(gameLoop)
|
// 清理旧的定时器
|
||||||
})
|
if (gameLoop) {
|
||||||
|
clearInterval(gameLoop)
|
||||||
|
}
|
||||||
|
// 根据游戏速度计算间隔时间
|
||||||
|
const interval = 1000 / (gameStore.gameSpeed || 1)
|
||||||
|
// 启动新的游戏循环
|
||||||
|
gameLoop = setInterval(() => {
|
||||||
|
updateGame()
|
||||||
|
}, interval)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听游戏速度变化,重新启动游戏循环
|
||||||
|
watch(
|
||||||
|
() => gameStore.gameSpeed,
|
||||||
|
() => {
|
||||||
|
if (gameLoop) {
|
||||||
|
startGameLoop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// 初始化游戏
|
// 初始化游戏
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
@@ -368,17 +1233,112 @@
|
|||||||
if (isFirstVisit) {
|
if (isFirstVisit) {
|
||||||
gameStore.locale = detectBrowserLocale()
|
gameStore.locale = detectBrowserLocale()
|
||||||
}
|
}
|
||||||
await initGame(t('common.playerName'), t('planet.homePlanet'), t('planet.planetPrefix'))
|
await initGame()
|
||||||
// 启动游戏循环
|
// 启动游戏循环
|
||||||
gameLoop = setInterval(() => {
|
startGameLoop()
|
||||||
updateGame()
|
// 启动科乐美秘籍监听
|
||||||
}, 1000) // 每1秒更新一次
|
konamiCleanup = setupKonamiCode()
|
||||||
|
|
||||||
|
// 启动新手引导(如果尚未完成)
|
||||||
|
startTutorial()
|
||||||
|
|
||||||
|
// 添加队列取消事件监听
|
||||||
|
window.addEventListener('cancel-build', handleCancelBuildEvent as EventListener)
|
||||||
|
window.addEventListener('cancel-research', handleCancelResearchEvent as EventListener)
|
||||||
|
|
||||||
|
// 首次检查版本(被动检测)
|
||||||
|
const versionInfo = await checkLatestVersion(gameStore.player.lastVersionCheckTime || 0, (time: number) => {
|
||||||
|
gameStore.player.lastVersionCheckTime = time
|
||||||
|
})
|
||||||
|
if (versionInfo) {
|
||||||
|
updateInfo.value = versionInfo
|
||||||
|
toast.info(t('settings.newVersionAvailable', { version: versionInfo.version }), {
|
||||||
|
duration: Infinity,
|
||||||
|
dismissible: true,
|
||||||
|
action: {
|
||||||
|
label: t('settings.viewUpdate'),
|
||||||
|
onClick: () => {
|
||||||
|
showUpdateDialog.value = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 启动版本检查定时器(每5分钟被动检查一次)
|
||||||
|
versionCheckInterval = setInterval(async () => {
|
||||||
|
const versionInfo = await checkLatestVersion(gameStore.player.lastVersionCheckTime || 0, (time: number) => {
|
||||||
|
gameStore.player.lastVersionCheckTime = time
|
||||||
|
})
|
||||||
|
if (versionInfo) {
|
||||||
|
updateInfo.value = versionInfo
|
||||||
|
toast.info(t('settings.newVersionAvailable', { version: versionInfo.version }), {
|
||||||
|
duration: Infinity,
|
||||||
|
dismissible: true,
|
||||||
|
action: {
|
||||||
|
label: t('settings.viewUpdate'),
|
||||||
|
onClick: () => {
|
||||||
|
showUpdateDialog.value = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, 5 * 60 * 1000)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 清理定时器
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (gameLoop) clearInterval(gameLoop)
|
||||||
|
if (konamiCleanup) konamiCleanup()
|
||||||
|
if (versionCheckInterval) clearInterval(versionCheckInterval)
|
||||||
|
// 移除队列取消事件监听
|
||||||
|
window.removeEventListener('cancel-build', handleCancelBuildEvent as EventListener)
|
||||||
|
window.removeEventListener('cancel-research', handleCancelResearchEvent as EventListener)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 处理取消建造事件
|
||||||
|
const handleCancelBuildEvent = (event: CustomEvent) => {
|
||||||
|
handleCancelBuild(event.detail)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理取消研究事件
|
||||||
|
const handleCancelResearchEvent = (event: CustomEvent) => {
|
||||||
|
handleCancelResearch(event.detail)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 科乐美秘籍:上上下下左左右右BA
|
||||||
|
const setupKonamiCode = () => {
|
||||||
|
const konamiCode = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowLeft', 'ArrowRight', 'ArrowRight', 'b', 'a']
|
||||||
|
let konamiIndex = 0
|
||||||
|
const handleKeyDown = (event: KeyboardEvent) => {
|
||||||
|
// 如果已经激活GM模式,直接返回
|
||||||
|
if (gameStore.player.isGMEnabled) return
|
||||||
|
|
||||||
|
const key = event.key.toLowerCase()
|
||||||
|
// 检查是否匹配当前秘籍序列
|
||||||
|
if (key === konamiCode[konamiIndex] || event.key === konamiCode[konamiIndex]) {
|
||||||
|
konamiIndex++
|
||||||
|
// 如果完成整个秘籍序列
|
||||||
|
if (konamiIndex === konamiCode.length) {
|
||||||
|
gameStore.player.isGMEnabled = true
|
||||||
|
// 显示成功消息
|
||||||
|
toast.success(t('common.gmModeActivated'))
|
||||||
|
konamiIndex = 0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果按错了键,重置序列
|
||||||
|
konamiIndex = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.addEventListener('keydown', handleKeyDown)
|
||||||
|
// 返回清理函数
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('keydown', handleKeyDown)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 定义 planet computed(需要在 watch 之前定义)
|
// 定义 planet computed(需要在 watch 之前定义)
|
||||||
const planet = computed(() => gameStore.currentPlanet)
|
const planet = computed(() => gameStore.currentPlanet)
|
||||||
|
|
||||||
const navItems = [
|
const navItems = computed(() => [
|
||||||
{ name: computed(() => t('nav.overview')), path: '/', icon: Home },
|
{ name: computed(() => t('nav.overview')), path: '/', icon: Home },
|
||||||
{ name: computed(() => t('nav.buildings')), path: '/buildings', icon: Building2 },
|
{ name: computed(() => t('nav.buildings')), path: '/buildings', icon: Building2 },
|
||||||
{ name: computed(() => t('nav.research')), path: '/research', icon: FlaskConical },
|
{ name: computed(() => t('nav.research')), path: '/research', icon: FlaskConical },
|
||||||
@@ -388,11 +1348,62 @@
|
|||||||
{ name: computed(() => t('nav.officers')), path: '/officers', icon: Users },
|
{ name: computed(() => t('nav.officers')), path: '/officers', icon: Users },
|
||||||
{ name: computed(() => t('nav.simulator')), path: '/battle-simulator', icon: Swords },
|
{ name: computed(() => t('nav.simulator')), path: '/battle-simulator', icon: Swords },
|
||||||
{ name: computed(() => t('nav.galaxy')), path: '/galaxy', icon: Globe },
|
{ name: computed(() => t('nav.galaxy')), path: '/galaxy', icon: Globe },
|
||||||
|
{ name: computed(() => t('nav.diplomacy')), path: '/diplomacy', icon: Handshake },
|
||||||
{ name: computed(() => t('nav.messages')), path: '/messages', icon: Mail },
|
{ name: computed(() => t('nav.messages')), path: '/messages', icon: Mail },
|
||||||
{ name: computed(() => t('nav.settings')), path: '/settings', icon: Settings },
|
{ name: computed(() => t('nav.settings')), path: '/settings', icon: Settings },
|
||||||
// GM菜单仅在开发模式下显示
|
// GM菜单在启用GM模式时显示
|
||||||
...(import.meta.env.DEV ? [{ name: computed(() => t('nav.gm')), path: '/gm', icon: Wrench }] : [])
|
...(gameStore.player.isGMEnabled ? [{ name: computed(() => t('nav.gm')), path: '/gm', icon: Wrench }] : [])
|
||||||
]
|
])
|
||||||
|
|
||||||
|
// 功能解锁要求配置
|
||||||
|
const featureRequirements: Record<string, { building: BuildingType; level: number }> = {
|
||||||
|
'/research': { building: BuildingType.ResearchLab, level: 1 },
|
||||||
|
'/shipyard': { building: BuildingType.Shipyard, level: 1 },
|
||||||
|
'/defense': { building: BuildingType.Shipyard, level: 1 },
|
||||||
|
'/fleet': { building: BuildingType.Shipyard, level: 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查功能是否解锁
|
||||||
|
const checkFeatureUnlocked = (path: string): { unlocked: boolean; requirement?: { building: BuildingType; level: number } } => {
|
||||||
|
const requirement = featureRequirements[path]
|
||||||
|
if (!requirement) {
|
||||||
|
return { unlocked: true }
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentLevel = planet.value?.buildings[requirement.building] || 0
|
||||||
|
return {
|
||||||
|
unlocked: currentLevel >= requirement.level,
|
||||||
|
requirement
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理导航点击
|
||||||
|
const handleNavClick = (path: string, event: Event) => {
|
||||||
|
const { unlocked, requirement } = checkFeatureUnlocked(path)
|
||||||
|
|
||||||
|
if (!unlocked && requirement) {
|
||||||
|
event.preventDefault()
|
||||||
|
event.stopPropagation()
|
||||||
|
|
||||||
|
const buildingName = BUILDINGS.value[requirement.building]?.name || requirement.building
|
||||||
|
const currentLevel = planet.value?.buildings[requirement.building] || 0
|
||||||
|
|
||||||
|
toast.warning(t('common.featureLocked'), {
|
||||||
|
description: `${t('common.requiredBuilding')}: ${buildingName} Lv ${requirement.level} (${t(
|
||||||
|
'common.currentLevel'
|
||||||
|
)}: Lv ${currentLevel})`,
|
||||||
|
action: {
|
||||||
|
label: t('common.goToBuildings'),
|
||||||
|
onClick: () => router.push('/buildings')
|
||||||
|
},
|
||||||
|
duration: 3000
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 功能已解锁,正常导航
|
||||||
|
router.push(path)
|
||||||
|
}
|
||||||
|
|
||||||
// 使用直接计算,不再缓存
|
// 使用直接计算,不再缓存
|
||||||
const production = computed(() => {
|
const production = computed(() => {
|
||||||
@@ -413,11 +1424,40 @@
|
|||||||
return resourceLogic.calculateResourceCapacity(planet.value, bonuses.storageCapacityBonus)
|
return resourceLogic.calculateResourceCapacity(planet.value, bonuses.storageCapacityBonus)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 电力消耗
|
||||||
|
const energyConsumption = computed(() => {
|
||||||
|
if (!planet.value) return 0
|
||||||
|
return resourceLogic.calculateEnergyConsumption(planet.value)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 净电力(产量 - 消耗)
|
||||||
|
const netEnergy = computed(() => {
|
||||||
|
if (!planet.value || !production.value) return 0
|
||||||
|
return production.value.energy - energyConsumption.value
|
||||||
|
})
|
||||||
|
|
||||||
// 未读消息数量
|
// 未读消息数量
|
||||||
const unreadMessagesCount = computed(() => {
|
const unreadMessagesCount = computed(() => {
|
||||||
const unreadBattles = gameStore.player.battleReports.filter(r => !r.read).length
|
const unreadBattles = gameStore.player.battleReports.filter(r => !r.read).length
|
||||||
const unreadSpies = gameStore.player.spyReports.filter(r => !r.read).length
|
const unreadSpies = gameStore.player.spyReports.filter(r => !r.read).length
|
||||||
return unreadBattles + unreadSpies
|
const unreadSpied = gameStore.player.spiedNotifications?.filter(n => !n.read).length || 0
|
||||||
|
const unreadMissions = gameStore.player.missionReports?.filter(r => !r.read).length || 0
|
||||||
|
const unreadNPCActivity = gameStore.player.npcActivityNotifications?.filter(n => !n.read).length || 0
|
||||||
|
const unreadGifts = gameStore.player.giftNotifications?.filter(n => !n.read).length || 0
|
||||||
|
const unreadGiftRejected = gameStore.player.giftRejectedNotifications?.filter(n => !n.read).length || 0
|
||||||
|
return unreadBattles + unreadSpies + unreadSpied + unreadMissions + unreadNPCActivity + unreadGifts + unreadGiftRejected
|
||||||
|
})
|
||||||
|
|
||||||
|
// 正在执行的舰队任务数量(包括飞行中的导弹)
|
||||||
|
const activeFleetMissionsCount = computed(() => {
|
||||||
|
const fleetMissions = gameStore.player.fleetMissions.filter(m => m.status === 'outbound' || m.status === 'returning').length
|
||||||
|
const flyingMissiles = gameStore.player.missileAttacks?.filter(m => m.status === 'flying').length || 0
|
||||||
|
return fleetMissions + flyingMissiles
|
||||||
|
})
|
||||||
|
|
||||||
|
// 未读外交报告数量
|
||||||
|
const unreadDiplomaticReportsCount = computed(() => {
|
||||||
|
return (gameStore.player.diplomaticReports || []).filter(r => !r.read).length
|
||||||
})
|
})
|
||||||
|
|
||||||
// 资源类型配置
|
// 资源类型配置
|
||||||
@@ -450,17 +1490,68 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 切换到指定星球
|
||||||
|
const switchToPlanet = (planetId: string) => {
|
||||||
|
gameStore.currentPlanetId = planetId
|
||||||
|
}
|
||||||
|
|
||||||
// 切换侧边栏
|
// 切换侧边栏
|
||||||
const toggleSidebar = () => {
|
const toggleSidebar = () => {
|
||||||
sidebarOpen.value = !sidebarOpen.value
|
sidebarOpen.value = !sidebarOpen.value
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理确认对话框的确认操作
|
// 处理侧边栏打开/关闭状态变化
|
||||||
const handleConfirmAction = () => {
|
const handleSidebarOpenChange = (open: boolean) => {
|
||||||
if (confirmDialogAction.value) {
|
// 如果是移动端且在教程的菜单相关步骤,阻止关闭侧边栏
|
||||||
confirmDialogAction.value()
|
if (window.innerWidth < 768 && tutorialState.value.isActive && currentStep.value) {
|
||||||
|
// 只在第3步期间阻止关闭侧边栏,让玩家必须手动打开
|
||||||
|
if (currentStep.value.id === 'menu_intro_mobile') {
|
||||||
|
// 只允许打开,不允许关闭
|
||||||
|
if (open) {
|
||||||
|
sidebarOpen.value = true
|
||||||
|
}
|
||||||
|
// 如果试图关闭,忽略该操作,保持打开状态
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
confirmDialogOpen.value = false
|
// 其他情况正常更新
|
||||||
|
sidebarOpen.value = open
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消建造
|
||||||
|
const handleCancelBuild = (queueId: string) => {
|
||||||
|
confirmDialogTitle.value = t('queue.cancelBuild')
|
||||||
|
confirmDialogMessage.value = t('queue.confirmCancel')
|
||||||
|
confirmDialogAction.value = () => {
|
||||||
|
if (!gameStore.currentPlanet) return false
|
||||||
|
const { item, index } = buildingValidation.findQueueItem(gameStore.currentPlanet.buildQueue, queueId)
|
||||||
|
if (!item) return false
|
||||||
|
if (item.type === 'building') {
|
||||||
|
const refund = buildingValidation.cancelBuildingUpgrade(gameStore.currentPlanet, item)
|
||||||
|
resourceLogic.addResources(gameStore.currentPlanet.resources, refund)
|
||||||
|
}
|
||||||
|
gameStore.currentPlanet.buildQueue.splice(index, 1)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
confirmDialogOpen.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消研究
|
||||||
|
const handleCancelResearch = (queueId: string) => {
|
||||||
|
confirmDialogTitle.value = t('queue.cancelResearch')
|
||||||
|
confirmDialogMessage.value = t('queue.confirmCancel')
|
||||||
|
confirmDialogAction.value = () => {
|
||||||
|
if (!gameStore.currentPlanet) return false
|
||||||
|
const { item, index } = buildingValidation.findQueueItem(gameStore.player.researchQueue, queueId)
|
||||||
|
if (!item) return false
|
||||||
|
if (item.type === 'technology') {
|
||||||
|
const refund = researchValidation.cancelTechnologyResearch(item)
|
||||||
|
resourceLogic.addResources(gameStore.currentPlanet.resources, refund)
|
||||||
|
}
|
||||||
|
gameStore.player.researchQueue.splice(index, 1)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
confirmDialogOpen.value = true
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
300
src/components/DiplomaticNotifications.vue
Normal file
300
src/components/DiplomaticNotifications.vue
Normal file
@@ -0,0 +1,300 @@
|
|||||||
|
<template>
|
||||||
|
<Popover v-model:open="isOpen">
|
||||||
|
<PopoverTrigger as-child>
|
||||||
|
<Button variant="outline" size="icon" class="relative">
|
||||||
|
<ScrollText class="h-4 w-4" />
|
||||||
|
<Badge
|
||||||
|
v-if="unreadCount > 0"
|
||||||
|
variant="destructive"
|
||||||
|
class="absolute -top-1 -right-1 h-5 w-5 p-0 flex items-center justify-center text-xs"
|
||||||
|
>
|
||||||
|
{{ unreadCount > 9 ? '9+' : unreadCount }}
|
||||||
|
</Badge>
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent class="w-96 p-0" align="end">
|
||||||
|
<div class="flex items-center justify-between p-4 border-b">
|
||||||
|
<h3 class="font-semibold">{{ t('diplomacy.notifications') }}</h3>
|
||||||
|
<Button v-if="unreadCount > 0" variant="ghost" size="sm" @click="markAllAsRead">
|
||||||
|
{{ t('diplomacy.markAllRead') }}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<ScrollArea class="h-96">
|
||||||
|
<div v-if="reports.length === 0" class="p-8 text-center text-muted-foreground">
|
||||||
|
{{ t('diplomacy.noReports') }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="divide-y">
|
||||||
|
<div
|
||||||
|
v-for="report in reports"
|
||||||
|
:key="report.id"
|
||||||
|
class="p-4 hover:bg-muted/50 cursor-pointer transition-colors"
|
||||||
|
:class="{ 'bg-primary/5': !report.read }"
|
||||||
|
@click="handleReportClick(report)"
|
||||||
|
>
|
||||||
|
<div class="flex items-start gap-3">
|
||||||
|
<div class="flex-shrink-0 mt-1">
|
||||||
|
<component :is="getEventIcon(report.eventType)" class="h-4 w-4" :class="getEventIconColor(report.eventType)" />
|
||||||
|
</div>
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
|
<div class="flex items-center gap-2 mb-1">
|
||||||
|
<span class="font-medium text-sm">{{ report.npcName }}</span>
|
||||||
|
<Badge :variant="getStatusBadgeVariant(report.newStatus)" class="text-xs">
|
||||||
|
{{ getStatusText(report.newStatus) }}
|
||||||
|
</Badge>
|
||||||
|
<span v-if="!report.read" class="ml-auto">
|
||||||
|
<Badge variant="destructive" class="h-2 w-2 p-0 rounded-full" />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-sm text-muted-foreground line-clamp-2">
|
||||||
|
{{ report.messageKey && report.messageParams ? t(report.messageKey, report.messageParams) : report.message }}
|
||||||
|
</p>
|
||||||
|
<p class="text-xs text-muted-foreground mt-1">
|
||||||
|
{{ formatRelativeTime((Date.now() - report.timestamp) / 1000, t) }}{{ t('diplomacy.ago') }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ScrollArea>
|
||||||
|
<div v-if="reports.length > 0" class="p-2 border-t">
|
||||||
|
<Button variant="ghost" size="sm" class="w-full" @click="goToDiplomacy">
|
||||||
|
{{ t('diplomacy.viewAll') }}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
|
||||||
|
<!-- 外交报告详情对话框 -->
|
||||||
|
<Dialog :open="detailDialogOpen" @update:open="detailDialogOpen = $event">
|
||||||
|
<DialogContent class="max-w-2xl">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle class="flex items-center gap-2">
|
||||||
|
<component
|
||||||
|
v-if="selectedReport"
|
||||||
|
:is="getEventIcon(selectedReport.eventType)"
|
||||||
|
class="h-5 w-5"
|
||||||
|
:class="getEventIconColor(selectedReport.eventType)"
|
||||||
|
/>
|
||||||
|
{{ t('diplomacy.reportDetails') }}
|
||||||
|
</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
|
||||||
|
<div v-if="selectedReport" class="space-y-4">
|
||||||
|
<!-- NPC信息 -->
|
||||||
|
<div class="flex items-center gap-3 p-4 bg-muted/50 rounded-lg">
|
||||||
|
<div class="flex-1">
|
||||||
|
<div class="flex items-center gap-2 mb-1">
|
||||||
|
<h3 class="font-semibold text-lg">{{ selectedReport.npcName }}</h3>
|
||||||
|
<Badge :variant="getStatusBadgeVariant(selectedReport.newStatus)">
|
||||||
|
{{ getStatusText(selectedReport.newStatus) }}
|
||||||
|
</Badge>
|
||||||
|
</div>
|
||||||
|
<p class="text-sm text-muted-foreground">
|
||||||
|
{{ formatRelativeTime((Date.now() - selectedReport.timestamp) / 1000, t) }}{{ t('diplomacy.ago') }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 事件描述 -->
|
||||||
|
<div class="space-y-2">
|
||||||
|
<h4 class="font-semibold text-sm">{{ t('diplomacy.eventDescription') }}</h4>
|
||||||
|
<p class="text-sm p-3 bg-muted/30 rounded-md">
|
||||||
|
{{
|
||||||
|
selectedReport.messageKey && selectedReport.messageParams
|
||||||
|
? t(selectedReport.messageKey, selectedReport.messageParams)
|
||||||
|
: selectedReport.message
|
||||||
|
}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 关系变化 -->
|
||||||
|
<div class="grid grid-cols-2 gap-4">
|
||||||
|
<!-- 好感度变化 -->
|
||||||
|
<div class="space-y-2">
|
||||||
|
<h4 class="font-semibold text-sm">{{ t('diplomacy.reputationChange') }}</h4>
|
||||||
|
<div class="p-3 bg-muted/30 rounded-md">
|
||||||
|
<div class="flex items-center justify-between text-sm mb-2">
|
||||||
|
<span class="text-muted-foreground">{{ t('diplomacy.before') }}</span>
|
||||||
|
<span class="font-semibold" :class="getReputationColor(selectedReport.newReputation - selectedReport.reputationChange)">
|
||||||
|
{{ selectedReport.newReputation - selectedReport.reputationChange > 0 ? '+' : ''
|
||||||
|
}}{{ selectedReport.newReputation - selectedReport.reputationChange }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="flex items-center justify-center text-lg font-bold my-1"
|
||||||
|
:class="selectedReport.reputationChange >= 0 ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400'"
|
||||||
|
>
|
||||||
|
{{ selectedReport.reputationChange >= 0 ? '+' : '' }}{{ selectedReport.reputationChange }}
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center justify-between text-sm mt-2">
|
||||||
|
<span class="text-muted-foreground">{{ t('diplomacy.after') }}</span>
|
||||||
|
<span class="font-semibold" :class="getReputationColor(selectedReport.newReputation)">
|
||||||
|
{{ selectedReport.newReputation > 0 ? '+' : '' }}{{ selectedReport.newReputation }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 关系状态变化 -->
|
||||||
|
<div class="space-y-2">
|
||||||
|
<h4 class="font-semibold text-sm">{{ t('diplomacy.statusChange') }}</h4>
|
||||||
|
<div class="p-3 bg-muted/30 rounded-md">
|
||||||
|
<div class="flex items-center justify-between text-sm mb-2">
|
||||||
|
<span class="text-muted-foreground">{{ t('diplomacy.before') }}</span>
|
||||||
|
<Badge :variant="getStatusBadgeVariant(selectedReport.oldStatus)" class="text-xs">
|
||||||
|
{{ getStatusText(selectedReport.oldStatus) }}
|
||||||
|
</Badge>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center justify-center my-3">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="h-6 w-6 text-muted-foreground"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 14l-7 7m0 0l-7-7m7 7V3" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center justify-between text-sm mt-2">
|
||||||
|
<span class="text-muted-foreground">{{ t('diplomacy.after') }}</span>
|
||||||
|
<Badge :variant="getStatusBadgeVariant(selectedReport.newStatus)" class="text-xs">
|
||||||
|
{{ getStatusText(selectedReport.newStatus) }}
|
||||||
|
</Badge>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<DialogFooter>
|
||||||
|
<Button variant="outline" @click="detailDialogOpen = false">{{ t('common.close') }}</Button>
|
||||||
|
<Button @click="goToDiplomacyFromDialog">{{ t('diplomacy.viewDiplomacy') }}</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { useGameStore } from '@/stores/gameStore'
|
||||||
|
import { useI18n } from '@/composables/useI18n'
|
||||||
|
import { Button } from '@/components/ui/button'
|
||||||
|
import { Badge } from '@/components/ui/badge'
|
||||||
|
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
|
||||||
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog'
|
||||||
|
import { ScrollArea } from '@/components/ui/scroll-area'
|
||||||
|
import { ScrollText, Gift, Sword, Eye, Trash2, Skull } from 'lucide-vue-next'
|
||||||
|
import { RelationStatus, DiplomaticEventType } from '@/types/game'
|
||||||
|
import type { DiplomaticReport } from '@/types/game'
|
||||||
|
import { formatRelativeTime } from '@/utils/format'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const gameStore = useGameStore()
|
||||||
|
const { t } = useI18n()
|
||||||
|
const isOpen = ref(false)
|
||||||
|
const detailDialogOpen = ref(false)
|
||||||
|
const selectedReport = ref<DiplomaticReport | null>(null)
|
||||||
|
|
||||||
|
const reports = computed(() => {
|
||||||
|
return (gameStore.player.diplomaticReports || []).slice().reverse().slice(0, 20) // 最近20条
|
||||||
|
})
|
||||||
|
|
||||||
|
const unreadCount = computed(() => {
|
||||||
|
return (gameStore.player.diplomaticReports || []).filter(r => !r.read).length
|
||||||
|
})
|
||||||
|
|
||||||
|
const getEventIcon = (eventType: DiplomaticReport['eventType']) => {
|
||||||
|
switch (eventType) {
|
||||||
|
case DiplomaticEventType.GiftResources:
|
||||||
|
return Gift
|
||||||
|
case DiplomaticEventType.Attack:
|
||||||
|
case DiplomaticEventType.AllyAttacked:
|
||||||
|
return Sword
|
||||||
|
case DiplomaticEventType.Spy:
|
||||||
|
return Eye
|
||||||
|
case DiplomaticEventType.StealDebris:
|
||||||
|
return Trash2
|
||||||
|
case DiplomaticEventType.DestroyPlanet:
|
||||||
|
return Skull
|
||||||
|
default:
|
||||||
|
return ScrollText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getEventIconColor = (eventType: DiplomaticReport['eventType']) => {
|
||||||
|
switch (eventType) {
|
||||||
|
case DiplomaticEventType.GiftResources:
|
||||||
|
return 'text-green-500'
|
||||||
|
case DiplomaticEventType.Attack:
|
||||||
|
case DiplomaticEventType.DestroyPlanet:
|
||||||
|
return 'text-red-500'
|
||||||
|
case DiplomaticEventType.AllyAttacked:
|
||||||
|
return 'text-orange-500'
|
||||||
|
case DiplomaticEventType.Spy:
|
||||||
|
return 'text-purple-500'
|
||||||
|
case DiplomaticEventType.StealDebris:
|
||||||
|
return 'text-yellow-500'
|
||||||
|
default:
|
||||||
|
return 'text-muted-foreground'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getStatusBadgeVariant = (status: RelationStatus) => {
|
||||||
|
switch (status) {
|
||||||
|
case RelationStatus.Hostile:
|
||||||
|
return 'destructive'
|
||||||
|
case RelationStatus.Friendly:
|
||||||
|
return 'default'
|
||||||
|
case RelationStatus.Neutral:
|
||||||
|
default:
|
||||||
|
return 'secondary'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getStatusText = (status: RelationStatus) => {
|
||||||
|
switch (status) {
|
||||||
|
case RelationStatus.Hostile:
|
||||||
|
return t('diplomacy.status.hostile')
|
||||||
|
case RelationStatus.Friendly:
|
||||||
|
return t('diplomacy.status.friendly')
|
||||||
|
case RelationStatus.Neutral:
|
||||||
|
default:
|
||||||
|
return t('diplomacy.status.neutral')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getReputationColor = (reputation: number | null) => {
|
||||||
|
if (reputation === null) return 'text-muted-foreground'
|
||||||
|
if (reputation >= 20) return 'text-green-600 dark:text-green-400'
|
||||||
|
if (reputation <= -20) return 'text-red-600 dark:text-red-400'
|
||||||
|
return 'text-muted-foreground'
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleReportClick = (report: DiplomaticReport) => {
|
||||||
|
// 标记为已读
|
||||||
|
report.read = true
|
||||||
|
// 设置选中的报告并打开详情对话框
|
||||||
|
selectedReport.value = report
|
||||||
|
detailDialogOpen.value = true
|
||||||
|
// 关闭通知面板
|
||||||
|
isOpen.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const markAllAsRead = () => {
|
||||||
|
gameStore.player.diplomaticReports?.forEach(report => {
|
||||||
|
report.read = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const goToDiplomacy = () => {
|
||||||
|
isOpen.value = false
|
||||||
|
router.push('/diplomacy')
|
||||||
|
}
|
||||||
|
|
||||||
|
const goToDiplomacyFromDialog = () => {
|
||||||
|
detailDialogOpen.value = false
|
||||||
|
router.push('/diplomacy')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -15,23 +15,37 @@
|
|||||||
<TableHead v-if="type === 'building' && showProductionColumn" class="text-center">{{ t('buildings.production') }}</TableHead>
|
<TableHead v-if="type === 'building' && showProductionColumn" class="text-center">{{ t('buildings.production') }}</TableHead>
|
||||||
<TableHead v-if="type === 'building' && showConsumptionColumn" class="text-center">{{ t('buildings.consumption') }}</TableHead>
|
<TableHead v-if="type === 'building' && showConsumptionColumn" class="text-center">{{ t('buildings.consumption') }}</TableHead>
|
||||||
<TableHead v-if="type === 'building' && showCapacityColumn" class="text-center">{{ t('buildings.storageCapacity') }}</TableHead>
|
<TableHead v-if="type === 'building' && showCapacityColumn" class="text-center">{{ t('buildings.storageCapacity') }}</TableHead>
|
||||||
<TableHead v-if="type === 'building' && showFleetStorageColumn" class="text-center">{{ t('buildings.fleetStorage') }}</TableHead>
|
<TableHead v-if="type === 'building' && showFleetStorageColumn" class="text-center">
|
||||||
<TableHead v-if="type === 'building' && showBuildQueueColumn" class="text-center">{{ t('buildings.buildQueueBonus') }}</TableHead>
|
{{ t('buildings.fleetStorage') }}
|
||||||
|
</TableHead>
|
||||||
|
<TableHead v-if="type === 'building' && showBuildQueueColumn" class="text-center">
|
||||||
|
{{ t('buildings.buildQueueBonus') }}
|
||||||
|
</TableHead>
|
||||||
<TableHead v-if="type === 'building' && showSpaceColumn" class="text-center">{{ t('buildings.spaceBonus') }}</TableHead>
|
<TableHead v-if="type === 'building' && showSpaceColumn" class="text-center">{{ t('buildings.spaceBonus') }}</TableHead>
|
||||||
<TableHead v-if="type === 'building' && showMissileColumn" class="text-center">{{ t('buildings.missileCapacity') }}</TableHead>
|
<TableHead v-if="type === 'building' && showMissileColumn" class="text-center">{{ t('buildings.missileCapacity') }}</TableHead>
|
||||||
<TableHead v-if="type === 'building' && showBuildSpeedColumn" class="text-center">{{ t('buildings.buildSpeedBonus') }}</TableHead>
|
<TableHead v-if="type === 'building' && showBuildSpeedColumn" class="text-center">
|
||||||
<TableHead v-if="type === 'building' && showResearchSpeedColumn" class="text-center">{{ t('buildings.researchSpeedBonus') }}</TableHead>
|
{{ t('buildings.buildSpeedBonus') }}
|
||||||
|
</TableHead>
|
||||||
|
<TableHead v-if="type === 'building' && showResearchSpeedColumn" class="text-center">
|
||||||
|
{{ t('buildings.researchSpeedBonus') }}
|
||||||
|
</TableHead>
|
||||||
<!-- 科技相关列 -->
|
<!-- 科技相关列 -->
|
||||||
<TableHead v-if="type === 'technology' && showAttackBonusColumn" class="text-center">{{ t('research.attackBonus') }}</TableHead>
|
<TableHead v-if="type === 'technology' && showAttackBonusColumn" class="text-center">{{ t('research.attackBonus') }}</TableHead>
|
||||||
<TableHead v-if="type === 'technology' && showShieldBonusColumn" class="text-center">{{ t('research.shieldBonus') }}</TableHead>
|
<TableHead v-if="type === 'technology' && showShieldBonusColumn" class="text-center">{{ t('research.shieldBonus') }}</TableHead>
|
||||||
<TableHead v-if="type === 'technology' && showArmorBonusColumn" class="text-center">{{ t('research.armorBonus') }}</TableHead>
|
<TableHead v-if="type === 'technology' && showArmorBonusColumn" class="text-center">{{ t('research.armorBonus') }}</TableHead>
|
||||||
<TableHead v-if="type === 'technology' && showSpyLevelColumn" class="text-center">{{ t('research.spyLevel') }}</TableHead>
|
<TableHead v-if="type === 'technology' && showSpyLevelColumn" class="text-center">{{ t('research.spyLevel') }}</TableHead>
|
||||||
<TableHead v-if="type === 'technology' && showFleetStorageColumn" class="text-center">{{ t('buildings.fleetStorage') }}</TableHead>
|
<TableHead v-if="type === 'technology' && showFleetStorageColumn" class="text-center">
|
||||||
<TableHead v-if="type === 'technology' && showResearchQueueColumn" class="text-center">{{ t('research.researchQueueBonus') }}</TableHead>
|
{{ t('buildings.fleetStorage') }}
|
||||||
|
</TableHead>
|
||||||
|
<TableHead v-if="type === 'technology' && showResearchQueueColumn" class="text-center">
|
||||||
|
{{ t('research.researchQueueBonus') }}
|
||||||
|
</TableHead>
|
||||||
<TableHead v-if="type === 'technology' && showColonySlotsColumn" class="text-center">{{ t('research.colonySlots') }}</TableHead>
|
<TableHead v-if="type === 'technology' && showColonySlotsColumn" class="text-center">{{ t('research.colonySlots') }}</TableHead>
|
||||||
<TableHead v-if="type === 'technology' && showSpaceColumn" class="text-center">{{ t('buildings.spaceBonus') }}</TableHead>
|
<TableHead v-if="type === 'technology' && showSpaceColumn" class="text-center">{{ t('buildings.spaceBonus') }}</TableHead>
|
||||||
<TableHead v-if="type === 'technology' && showSpeedBonusColumn" class="text-center">{{ t('research.speedBonus') }}</TableHead>
|
<TableHead v-if="type === 'technology' && showSpeedBonusColumn" class="text-center">{{ t('research.speedBonus') }}</TableHead>
|
||||||
<TableHead v-if="type === 'technology' && showResearchSpeedColumn" class="text-center">{{ t('buildings.researchSpeedBonus') }}</TableHead>
|
<TableHead v-if="type === 'technology' && showResearchSpeedColumn" class="text-center">
|
||||||
|
{{ t('buildings.researchSpeedBonus') }}
|
||||||
|
</TableHead>
|
||||||
<TableHead class="text-center">{{ t('player.points') }}</TableHead>
|
<TableHead class="text-center">{{ t('player.points') }}</TableHead>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
@@ -78,7 +92,8 @@
|
|||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell v-if="type === 'building' && showFleetStorageColumn" class="text-center text-sm">
|
<TableCell v-if="type === 'building' && showFleetStorageColumn" class="text-center text-sm">
|
||||||
<span v-if="getLevelData(level).fleetStorage > 0" class="text-blue-600 dark:text-blue-400">
|
<span v-if="getLevelData(level).fleetStorage > 0" class="text-blue-600 dark:text-blue-400">
|
||||||
+<NumberWithTooltip :value="getLevelData(level).fleetStorage" />
|
+
|
||||||
|
<NumberWithTooltip :value="getLevelData(level).fleetStorage" />
|
||||||
</span>
|
</span>
|
||||||
<span v-else>-</span>
|
<span v-else>-</span>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
@@ -87,7 +102,8 @@
|
|||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell v-if="type === 'building' && showSpaceColumn" class="text-center text-sm">
|
<TableCell v-if="type === 'building' && showSpaceColumn" class="text-center text-sm">
|
||||||
<span v-if="getLevelData(level).spaceBonus > 0" class="text-green-600 dark:text-green-400">
|
<span v-if="getLevelData(level).spaceBonus > 0" class="text-green-600 dark:text-green-400">
|
||||||
+<NumberWithTooltip :value="getLevelData(level).spaceBonus" />
|
+
|
||||||
|
<NumberWithTooltip :value="getLevelData(level).spaceBonus" />
|
||||||
</span>
|
</span>
|
||||||
<span v-else>-</span>
|
<span v-else>-</span>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
@@ -95,8 +111,12 @@
|
|||||||
<span class="text-orange-600 dark:text-orange-400">+10</span>
|
<span class="text-orange-600 dark:text-orange-400">+10</span>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell v-if="type === 'building' && showBuildSpeedColumn" class="text-center text-sm">
|
<TableCell v-if="type === 'building' && showBuildSpeedColumn" class="text-center text-sm">
|
||||||
<span v-if="itemType === 'roboticsFactory'" class="text-cyan-600 dark:text-cyan-400">+{{ getLevelData(level).buildSpeedBonus * 100 }}%</span>
|
<span v-if="itemType === 'roboticsFactory'" class="text-cyan-600 dark:text-cyan-400">
|
||||||
<span v-else-if="itemType === 'naniteFactory'" class="text-cyan-600 dark:text-cyan-400">+{{ getLevelData(level).buildSpeedBonus * 100 }}%</span>
|
+{{ getLevelData(level).buildSpeedBonus * 100 }}%
|
||||||
|
</span>
|
||||||
|
<span v-else-if="itemType === 'naniteFactory'" class="text-cyan-600 dark:text-cyan-400">
|
||||||
|
+{{ getLevelData(level).buildSpeedBonus * 100 }}%
|
||||||
|
</span>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell v-if="type === 'building' && showResearchSpeedColumn" class="text-center text-sm">
|
<TableCell v-if="type === 'building' && showResearchSpeedColumn" class="text-center text-sm">
|
||||||
<span class="text-indigo-600 dark:text-indigo-400">+{{ (getLevelData(level).researchSpeedBonus - 1) * 100 }}%</span>
|
<span class="text-indigo-600 dark:text-indigo-400">+{{ (getLevelData(level).researchSpeedBonus - 1) * 100 }}%</span>
|
||||||
@@ -115,7 +135,10 @@
|
|||||||
<span class="text-purple-600 dark:text-purple-400">+{{ level }}</span>
|
<span class="text-purple-600 dark:text-purple-400">+{{ level }}</span>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell v-if="type === 'technology' && showFleetStorageColumn" class="text-center text-sm">
|
<TableCell v-if="type === 'technology' && showFleetStorageColumn" class="text-center text-sm">
|
||||||
<span class="text-blue-600 dark:text-blue-400">+<NumberWithTooltip :value="level * 500" /></span>
|
<span class="text-blue-600 dark:text-blue-400">
|
||||||
|
+
|
||||||
|
<NumberWithTooltip :value="level * 500" />
|
||||||
|
</span>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell v-if="type === 'technology' && showResearchQueueColumn" class="text-center text-sm">
|
<TableCell v-if="type === 'technology' && showResearchQueueColumn" class="text-center text-sm">
|
||||||
<span class="text-purple-600 dark:text-purple-400">+1</span>
|
<span class="text-purple-600 dark:text-purple-400">+1</span>
|
||||||
@@ -124,7 +147,7 @@
|
|||||||
<span class="text-green-600 dark:text-green-400">+1</span>
|
<span class="text-green-600 dark:text-green-400">+1</span>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell v-if="type === 'technology' && showSpaceColumn" class="text-center text-sm">
|
<TableCell v-if="type === 'technology' && showSpaceColumn" class="text-center text-sm">
|
||||||
<span class="text-green-600 dark:text-green-400">+5 {{ t('research.forAllPlanets') }}</span>
|
<span class="text-green-600 dark:text-green-400">+30 {{ t('research.forAllPlanets') }}</span>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell v-if="type === 'technology' && showSpeedBonusColumn" class="text-center text-sm">
|
<TableCell v-if="type === 'technology' && showSpeedBonusColumn" class="text-center text-sm">
|
||||||
<span class="text-yellow-600 dark:text-yellow-400">+{{ level * 10 }}%</span>
|
<span class="text-yellow-600 dark:text-yellow-400">+{{ level * 10 }}%</span>
|
||||||
@@ -152,15 +175,21 @@
|
|||||||
<CardContent class="space-y-2">
|
<CardContent class="space-y-2">
|
||||||
<div class="flex items-center justify-between text-sm">
|
<div class="flex items-center justify-between text-sm">
|
||||||
<span class="text-muted-foreground">{{ t('resources.metal') }}:</span>
|
<span class="text-muted-foreground">{{ t('resources.metal') }}:</span>
|
||||||
<span class="font-medium"><NumberWithTooltip :value="totalStats.metal" /></span>
|
<span class="font-medium">
|
||||||
|
<NumberWithTooltip :value="totalStats.metal" />
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between text-sm">
|
<div class="flex items-center justify-between text-sm">
|
||||||
<span class="text-muted-foreground">{{ t('resources.crystal') }}:</span>
|
<span class="text-muted-foreground">{{ t('resources.crystal') }}:</span>
|
||||||
<span class="font-medium"><NumberWithTooltip :value="totalStats.crystal" /></span>
|
<span class="font-medium">
|
||||||
|
<NumberWithTooltip :value="totalStats.crystal" />
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between text-sm">
|
<div class="flex items-center justify-between text-sm">
|
||||||
<span class="text-muted-foreground">{{ t('resources.deuterium') }}:</span>
|
<span class="text-muted-foreground">{{ t('resources.deuterium') }}:</span>
|
||||||
<span class="font-medium"><NumberWithTooltip :value="totalStats.deuterium" /></span>
|
<span class="font-medium">
|
||||||
|
<NumberWithTooltip :value="totalStats.deuterium" />
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -275,13 +304,22 @@
|
|||||||
<CardTitle class="text-sm">{{ t(`${typeKey}.buildCost`) }}</CardTitle>
|
<CardTitle class="text-sm">{{ t(`${typeKey}.buildCost`) }}</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent class="space-y-2">
|
<CardContent class="space-y-2">
|
||||||
<div v-for="resourceType in costResourceTypes" :key="resourceType.key" v-show="unitCost[resourceType.key] > 0" class="flex items-center justify-between text-sm">
|
<div
|
||||||
|
v-for="resourceType in costResourceTypes"
|
||||||
|
:key="resourceType.key"
|
||||||
|
v-show="unitCost[resourceType.key] > 0"
|
||||||
|
class="flex items-center justify-between text-sm"
|
||||||
|
>
|
||||||
<span class="text-muted-foreground">{{ t(`resources.${resourceType.key}`) }}:</span>
|
<span class="text-muted-foreground">{{ t(`resources.${resourceType.key}`) }}:</span>
|
||||||
<span class="font-medium"><NumberWithTooltip :value="unitCost[resourceType.key]" /></span>
|
<span class="font-medium">
|
||||||
|
<NumberWithTooltip :value="unitCost[resourceType.key]" />
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between text-sm pt-2 border-t">
|
<div class="flex items-center justify-between text-sm pt-2 border-t">
|
||||||
<span class="text-muted-foreground">{{ t('player.points') }}:</span>
|
<span class="text-muted-foreground">{{ t('player.points') }}:</span>
|
||||||
<span class="font-bold text-primary"><NumberWithTooltip :value="pointsPerUnit" /></span>
|
<span class="font-bold text-primary">
|
||||||
|
<NumberWithTooltip :value="pointsPerUnit" />
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -311,9 +349,23 @@
|
|||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<p class="text-sm text-muted-foreground">{{ t(`${typeKey}.totalCost`) }}:</p>
|
<p class="text-sm text-muted-foreground">{{ t(`${typeKey}.totalCost`) }}:</p>
|
||||||
<div class="space-y-1 text-sm">
|
<div class="space-y-1 text-sm">
|
||||||
<div v-for="resourceType in costResourceTypes" :key="resourceType.key" class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<span>{{ t(`resources.${resourceType.key}`) }}:</span>
|
<span>{{ t('resources.metal') }}:</span>
|
||||||
<span class="font-medium"><NumberWithTooltip :value="batchCost[resourceType.key]" /></span>
|
<span class="font-medium">
|
||||||
|
<NumberWithTooltip :value="batchCost.metal" />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span>{{ t('resources.crystal') }}:</span>
|
||||||
|
<span class="font-medium">
|
||||||
|
<NumberWithTooltip :value="batchCost.crystal" />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span>{{ t('resources.deuterium') }}:</span>
|
||||||
|
<span class="font-medium">
|
||||||
|
<NumberWithTooltip :value="batchCost.deuterium" />
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -434,7 +486,7 @@
|
|||||||
const showFleetStorageColumn = computed(() => {
|
const showFleetStorageColumn = computed(() => {
|
||||||
if (props.type === 'building') {
|
if (props.type === 'building') {
|
||||||
const buildingType = props.itemType as BuildingType
|
const buildingType = props.itemType as BuildingType
|
||||||
return buildingType === 'shipyard'
|
return buildingType === 'shipyard' || buildingType === 'hangar'
|
||||||
} else if (props.type === 'technology') {
|
} else if (props.type === 'technology') {
|
||||||
const techType = props.itemType as TechnologyType
|
const techType = props.itemType as TechnologyType
|
||||||
return techType === 'computerTechnology'
|
return techType === 'computerTechnology'
|
||||||
@@ -626,43 +678,84 @@
|
|||||||
const storageBonus = 1 + (activeBonuses.value.storageCapacityBonus || 0) / 100
|
const storageBonus = 1 + (activeBonuses.value.storageCapacityBonus || 0) / 100
|
||||||
const baseCapacity = 10000
|
const baseCapacity = 10000
|
||||||
|
|
||||||
if (buildingType === 'metalMine') {
|
// Building calculation configuration
|
||||||
production = Math.floor(1500 * level * Math.pow(1.5, level) * resourceBonus)
|
const buildingCalculations: Record<string, (level: number) => Partial<{
|
||||||
consumption = Math.floor(10 * level * Math.pow(1.1, level))
|
production: number
|
||||||
} else if (buildingType === 'crystalMine') {
|
consumption: number
|
||||||
production = Math.floor(1000 * level * Math.pow(1.5, level) * resourceBonus)
|
capacity: number
|
||||||
consumption = Math.floor(10 * level * Math.pow(1.1, level))
|
fleetStorage: number
|
||||||
} else if (buildingType === 'deuteriumSynthesizer') {
|
spaceBonus: number
|
||||||
production = Math.floor(500 * level * Math.pow(1.5, level) * resourceBonus)
|
buildSpeedBonus: number
|
||||||
consumption = Math.floor(10 * level * Math.pow(1.1, level))
|
researchSpeedBonus: number
|
||||||
} else if (buildingType === 'solarPlant') {
|
}>> = {
|
||||||
production = Math.floor(50 * level * Math.pow(1.1, level) * energyBonus)
|
metalMine: (lvl) => ({
|
||||||
} else if (buildingType === 'metalStorage') {
|
production: Math.floor(1500 * lvl * Math.pow(1.5, lvl) * resourceBonus),
|
||||||
capacity = Math.floor(baseCapacity * Math.pow(2, level) * storageBonus)
|
consumption: Math.floor(10 * lvl * Math.pow(1.1, lvl))
|
||||||
} else if (buildingType === 'crystalStorage') {
|
}),
|
||||||
capacity = Math.floor(baseCapacity * Math.pow(2, level) * storageBonus)
|
crystalMine: (lvl) => ({
|
||||||
} else if (buildingType === 'deuteriumTank') {
|
production: Math.floor(1000 * lvl * Math.pow(1.5, lvl) * resourceBonus),
|
||||||
capacity = Math.floor(baseCapacity * Math.pow(2, level) * storageBonus)
|
consumption: Math.floor(10 * lvl * Math.pow(1.1, lvl))
|
||||||
} else if (buildingType === 'darkMatterCollector') {
|
}),
|
||||||
capacity = 1000 + level * 100
|
deuteriumSynthesizer: (lvl) => ({
|
||||||
production = Math.floor(25 * level * Math.pow(1.5, level))
|
production: Math.floor(500 * lvl * Math.pow(1.5, lvl) * resourceBonus),
|
||||||
} else if (buildingType === 'darkMatterTank') {
|
consumption: Math.floor(10 * lvl * Math.pow(1.1, lvl))
|
||||||
const darkMatterBaseCapacity = 1000
|
}),
|
||||||
capacity = Math.floor(darkMatterBaseCapacity * Math.pow(2, level) * storageBonus)
|
solarPlant: (lvl) => ({
|
||||||
} else if (buildingType === 'fusionReactor') {
|
production: Math.floor(50 * lvl * Math.pow(1.1, lvl) * energyBonus)
|
||||||
production = Math.floor(150 * level * Math.pow(1.15, level))
|
}),
|
||||||
} else if (buildingType === 'shipyard') {
|
metalStorage: (lvl) => ({
|
||||||
fleetStorage = 1000 * level
|
capacity: Math.floor(baseCapacity * Math.pow(2, lvl) * storageBonus)
|
||||||
} else if (buildingType === 'terraformer') {
|
}),
|
||||||
spaceBonus = 5
|
crystalStorage: (lvl) => ({
|
||||||
} else if (buildingType === 'lunarBase') {
|
capacity: Math.floor(baseCapacity * Math.pow(2, lvl) * storageBonus)
|
||||||
spaceBonus = 5
|
}),
|
||||||
} else if (buildingType === 'roboticsFactory') {
|
deuteriumTank: (lvl) => ({
|
||||||
buildSpeedBonus = level
|
capacity: Math.floor(baseCapacity * Math.pow(2, lvl) * storageBonus)
|
||||||
} else if (buildingType === 'naniteFactory') {
|
}),
|
||||||
buildSpeedBonus = level * 2
|
darkMatterCollector: (lvl) => ({
|
||||||
} else if (buildingType === 'researchLab') {
|
capacity: 1000 + lvl * 100,
|
||||||
researchSpeedBonus = level
|
production: Math.floor(25 * lvl * Math.pow(1.5, lvl))
|
||||||
|
}),
|
||||||
|
darkMatterTank: (lvl) => ({
|
||||||
|
capacity: Math.floor(1000 * Math.pow(2, lvl) * storageBonus)
|
||||||
|
}),
|
||||||
|
fusionReactor: (lvl) => ({
|
||||||
|
production: Math.floor(150 * lvl * Math.pow(1.15, lvl))
|
||||||
|
}),
|
||||||
|
shipyard: (lvl) => ({
|
||||||
|
fleetStorage: 1000 * lvl
|
||||||
|
}),
|
||||||
|
hangar: (lvl) => ({
|
||||||
|
fleetStorage: 500 * lvl
|
||||||
|
}),
|
||||||
|
terraformer: () => ({
|
||||||
|
spaceBonus: 30
|
||||||
|
}),
|
||||||
|
lunarBase: () => ({
|
||||||
|
spaceBonus: 30
|
||||||
|
}),
|
||||||
|
roboticsFactory: (lvl) => ({
|
||||||
|
buildSpeedBonus: lvl
|
||||||
|
}),
|
||||||
|
naniteFactory: (lvl) => ({
|
||||||
|
buildSpeedBonus: lvl * 2
|
||||||
|
}),
|
||||||
|
researchLab: (lvl) => ({
|
||||||
|
researchSpeedBonus: lvl
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply calculations if configuration exists
|
||||||
|
const calc = buildingCalculations[buildingType]
|
||||||
|
if (calc) {
|
||||||
|
const result = calc(level)
|
||||||
|
production = result.production ?? production
|
||||||
|
consumption = result.consumption ?? consumption
|
||||||
|
capacity = result.capacity ?? capacity
|
||||||
|
fleetStorage = result.fleetStorage ?? fleetStorage
|
||||||
|
spaceBonus = result.spaceBonus ?? spaceBonus
|
||||||
|
buildSpeedBonus = result.buildSpeedBonus ?? buildSpeedBonus
|
||||||
|
researchSpeedBonus = result.researchSpeedBonus ?? researchSpeedBonus
|
||||||
}
|
}
|
||||||
|
|
||||||
const points = pointsLogic.calculateBuildingPoints(buildingType, level - 1, level)
|
const points = pointsLogic.calculateBuildingPoints(buildingType, level - 1, level)
|
||||||
@@ -685,7 +778,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const points = pointsLogic.calculateTechnologyPoints(techType, level - 1, level)
|
const points = pointsLogic.calculateTechnologyPoints(techType, level - 1, level)
|
||||||
return { cost, time, production: 0, consumption: 0, points, capacity: 0, fleetStorage: 0, spaceBonus: 0, buildSpeedBonus: 0, researchSpeedBonus }
|
return {
|
||||||
|
cost,
|
||||||
|
time,
|
||||||
|
production: 0,
|
||||||
|
consumption: 0,
|
||||||
|
points,
|
||||||
|
capacity: 0,
|
||||||
|
fleetStorage: 0,
|
||||||
|
spaceBonus: 0,
|
||||||
|
buildSpeedBonus: 0,
|
||||||
|
researchSpeedBonus
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,13 @@
|
|||||||
<div v-if="npc.allies && npc.allies.length > 0" class="pt-2 border-t">
|
<div v-if="npc.allies && npc.allies.length > 0" class="pt-2 border-t">
|
||||||
<p class="text-sm text-muted-foreground mb-2">{{ t('diplomacy.alliedWith') }}:</p>
|
<p class="text-sm text-muted-foreground mb-2">{{ t('diplomacy.alliedWith') }}:</p>
|
||||||
<div class="flex flex-wrap gap-1">
|
<div class="flex flex-wrap gap-1">
|
||||||
<Badge v-for="allyId in npc.allies.slice(0, 3)" :key="allyId" variant="outline" class="text-xs">
|
<Badge
|
||||||
|
v-for="allyId in npc.allies.slice(0, 3)"
|
||||||
|
:key="allyId"
|
||||||
|
variant="outline"
|
||||||
|
class="text-xs cursor-pointer hover:bg-accent transition-colors"
|
||||||
|
@click="scrollToAlly(allyId)"
|
||||||
|
>
|
||||||
{{ getAllyName(allyId) }}
|
{{ getAllyName(allyId) }}
|
||||||
</Badge>
|
</Badge>
|
||||||
<Badge v-if="npc.allies.length > 3" variant="outline" class="text-xs">
|
<Badge v-if="npc.allies.length > 3" variant="outline" class="text-xs">
|
||||||
@@ -80,7 +86,9 @@
|
|||||||
<div class="flex items-center gap-2 text-xs">
|
<div class="flex items-center gap-2 text-xs">
|
||||||
<component :is="getEventIcon(recentEvent.reason)" class="h-3 w-3" />
|
<component :is="getEventIcon(recentEvent.reason)" class="h-3 w-3" />
|
||||||
<span>{{ getEventText(recentEvent.reason) }}</span>
|
<span>{{ getEventText(recentEvent.reason) }}</span>
|
||||||
<span class="text-muted-foreground">{{ formatTime(Date.now() - recentEvent.timestamp) }} {{ t('diplomacy.ago') }}</span>
|
<span class="text-muted-foreground">
|
||||||
|
{{ formatRelativeTime((Date.now() - recentEvent.timestamp) / 1000, t) }}{{ t('diplomacy.ago') }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
@@ -98,7 +106,7 @@
|
|||||||
import { Gift, Globe, Sword, Eye, Trash2 } from 'lucide-vue-next'
|
import { Gift, Globe, Sword, Eye, Trash2 } from 'lucide-vue-next'
|
||||||
import { RelationStatus, DiplomaticEventType } from '@/types/game'
|
import { RelationStatus, DiplomaticEventType } from '@/types/game'
|
||||||
import type { DiplomaticRelation, NPC } from '@/types/game'
|
import type { DiplomaticRelation, NPC } from '@/types/game'
|
||||||
import { formatTime } from '@/utils/format'
|
import { formatRelativeTime } from '@/utils/format'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
npc: NPC
|
npc: NPC
|
||||||
@@ -229,4 +237,12 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 滚动到盟友卡片
|
||||||
|
const scrollToAlly = (allyId: string) => {
|
||||||
|
// 触发父组件的滚动事件
|
||||||
|
// 通过emit通知父组件滚动到指定的NPC卡片
|
||||||
|
const event = new CustomEvent('scrollToNpc', { detail: { npcId: allyId }, bubbles: true })
|
||||||
|
document.dispatchEvent(event)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
166
src/components/QueueNotifications.vue
Normal file
166
src/components/QueueNotifications.vue
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
<template>
|
||||||
|
<Popover v-model:open="isOpen">
|
||||||
|
<PopoverTrigger as-child>
|
||||||
|
<Button data-tutorial="queue-button" variant="outline" size="icon" class="relative">
|
||||||
|
<ListOrdered class="h-4 w-4" />
|
||||||
|
<Badge
|
||||||
|
v-if="totalQueueCount > 0"
|
||||||
|
variant="default"
|
||||||
|
class="absolute -top-1 -right-1 h-5 w-5 p-0 flex items-center justify-center text-xs"
|
||||||
|
>
|
||||||
|
{{ totalQueueCount > 9 ? '9+' : totalQueueCount }}
|
||||||
|
</Badge>
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent class="w-96 p-0" align="end">
|
||||||
|
<div class="flex items-center justify-between p-4 border-b">
|
||||||
|
<h3 class="font-semibold">{{ t('queue.title') }}</h3>
|
||||||
|
</div>
|
||||||
|
<ScrollArea class="max-h-96">
|
||||||
|
<div v-if="totalQueueCount === 0" class="p-8 text-center text-muted-foreground">
|
||||||
|
{{ t('queue.empty') }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="divide-y p-4 space-y-3">
|
||||||
|
<!-- 建造队列 -->
|
||||||
|
<div v-for="item in buildQueue" :key="item.id" class="space-y-1.5">
|
||||||
|
<div class="flex items-center justify-between text-xs sm:text-sm gap-2">
|
||||||
|
<div class="flex items-center gap-1.5 sm:gap-2 min-w-0 flex-1">
|
||||||
|
<div
|
||||||
|
class="h-2 w-2 rounded-full animate-pulse flex-shrink-0"
|
||||||
|
:class="item.type === 'demolish' ? 'bg-destructive' : 'bg-green-500'"
|
||||||
|
/>
|
||||||
|
<span class="font-medium truncate">{{ getItemName(item) }}</span>
|
||||||
|
<span class="text-muted-foreground text-[10px] sm:text-xs">
|
||||||
|
<template v-if="item.type === 'ship' || item.type === 'defense'">
|
||||||
|
→ {{ t('queue.quantity') }} {{ item.quantity }}
|
||||||
|
</template>
|
||||||
|
<template v-else-if="item.type === 'demolish'">→ {{ t('queue.demolishing') }}</template>
|
||||||
|
<template v-else>→ {{ t('queue.level') }} {{ item.targetLevel }}</template>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-2 sm:gap-3 flex-shrink-0">
|
||||||
|
<span class="text-muted-foreground text-[10px] sm:text-xs whitespace-nowrap">
|
||||||
|
{{ formatTime(getRemainingTime(item)) }}
|
||||||
|
</span>
|
||||||
|
<Button @click="handleCancel(item)" variant="ghost" size="sm" class="h-5 sm:h-6 px-1.5 sm:px-2 text-[10px] sm:text-xs">
|
||||||
|
{{ t('queue.cancel') }}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Progress :model-value="getQueueProgress(item)" class="h-1.5" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 研究队列 -->
|
||||||
|
<div v-for="item in researchQueue" :key="item.id" class="space-y-1.5">
|
||||||
|
<div class="flex items-center justify-between text-xs sm:text-sm gap-2">
|
||||||
|
<div class="flex items-center gap-1.5 sm:gap-2 min-w-0 flex-1">
|
||||||
|
<div class="h-2 w-2 rounded-full bg-blue-500 animate-pulse flex-shrink-0" />
|
||||||
|
<span class="font-medium truncate">{{ getItemName(item) }}</span>
|
||||||
|
<span class="text-muted-foreground text-[10px] sm:text-xs">→ {{ t('queue.level') }} {{ item.targetLevel }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-2 sm:gap-3 flex-shrink-0">
|
||||||
|
<span class="text-muted-foreground text-[10px] sm:text-xs whitespace-nowrap">
|
||||||
|
{{ formatTime(getRemainingTime(item)) }}
|
||||||
|
</span>
|
||||||
|
<Button
|
||||||
|
@click="handleCancelResearch(item.id)"
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
class="h-5 sm:h-6 px-1.5 sm:px-2 text-[10px] sm:text-xs"
|
||||||
|
>
|
||||||
|
{{ t('queue.cancel') }}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Progress :model-value="getQueueProgress(item)" class="h-1.5" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ScrollArea>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
|
import { ListOrdered } from 'lucide-vue-next'
|
||||||
|
import { Button } from '@/components/ui/button'
|
||||||
|
import { Badge } from '@/components/ui/badge'
|
||||||
|
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
|
||||||
|
import { ScrollArea } from '@/components/ui/scroll-area'
|
||||||
|
import { Progress } from '@/components/ui/progress'
|
||||||
|
import { useGameStore } from '@/stores/gameStore'
|
||||||
|
import { useGameConfig } from '@/composables/useGameConfig'
|
||||||
|
import { useI18n } from '@/composables/useI18n'
|
||||||
|
import { formatTime } from '@/utils/format'
|
||||||
|
import type { BuildQueueItem, BuildingType, ShipType, DefenseType, TechnologyType } from '@/types/game'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
const gameStore = useGameStore()
|
||||||
|
const { BUILDINGS, SHIPS, DEFENSES, TECHNOLOGIES } = useGameConfig()
|
||||||
|
|
||||||
|
const isOpen = ref(false)
|
||||||
|
|
||||||
|
// 获取当前星球的建造队列
|
||||||
|
const buildQueue = computed(() => {
|
||||||
|
return gameStore.currentPlanet?.buildQueue || []
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取研究队列
|
||||||
|
const researchQueue = computed(() => {
|
||||||
|
return gameStore.player.researchQueue || []
|
||||||
|
})
|
||||||
|
|
||||||
|
// 总队列数量
|
||||||
|
const totalQueueCount = computed(() => {
|
||||||
|
return buildQueue.value.length + researchQueue.value.length
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取队列项名称
|
||||||
|
const getItemName = (item: BuildQueueItem): string => {
|
||||||
|
if (item.type === 'building' || item.type === 'demolish') {
|
||||||
|
return BUILDINGS.value[item.itemType as BuildingType].name
|
||||||
|
} else if (item.type === 'ship') {
|
||||||
|
return SHIPS.value[item.itemType as ShipType].name
|
||||||
|
} else if (item.type === 'defense') {
|
||||||
|
return DEFENSES.value[item.itemType as DefenseType].name
|
||||||
|
} else if (item.type === 'technology') {
|
||||||
|
return TECHNOLOGIES.value[item.itemType as TechnologyType].name
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取剩余时间
|
||||||
|
const getRemainingTime = (item: BuildQueueItem): number => {
|
||||||
|
const now = Date.now()
|
||||||
|
return Math.max(0, Math.floor((item.endTime - now) / 1000))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取队列进度
|
||||||
|
const getQueueProgress = (item: BuildQueueItem): number => {
|
||||||
|
const now = Date.now()
|
||||||
|
const elapsed = now - item.startTime
|
||||||
|
const total = item.endTime - item.startTime
|
||||||
|
return Math.min(100, (elapsed / total) * 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 统一的取消处理
|
||||||
|
const handleCancel = (item: BuildQueueItem) => {
|
||||||
|
let eventName: string
|
||||||
|
if (item.type === 'building' || item.type === 'ship' || item.type === 'defense' || item.type === 'demolish') {
|
||||||
|
eventName = 'cancel-build'
|
||||||
|
} else if (item.type === 'technology') {
|
||||||
|
eventName = 'cancel-research'
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const event = new CustomEvent(eventName, { detail: item.id })
|
||||||
|
window.dispatchEvent(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消研究
|
||||||
|
const handleCancelResearch = (queueId: string) => {
|
||||||
|
const event = new CustomEvent('cancel-research', { detail: queueId })
|
||||||
|
window.dispatchEvent(event)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
438
src/components/TutorialOverlay.vue
Normal file
438
src/components/TutorialOverlay.vue
Normal file
@@ -0,0 +1,438 @@
|
|||||||
|
<template>
|
||||||
|
<Teleport to="body">
|
||||||
|
<div v-if="tutorialState.isActive && currentStep" class="tutorial-overlay">
|
||||||
|
<!-- Dark overlay parts (4 rectangles around the highlight) -->
|
||||||
|
<template v-if="highlightRect && currentStep.target">
|
||||||
|
<!-- Top overlay -->
|
||||||
|
<div
|
||||||
|
class="tutorial-backdrop-part"
|
||||||
|
:style="{
|
||||||
|
top: '0',
|
||||||
|
left: '0',
|
||||||
|
width: '100%',
|
||||||
|
height: `${highlightRect.top}px`
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<!-- Bottom overlay -->
|
||||||
|
<div
|
||||||
|
class="tutorial-backdrop-part"
|
||||||
|
:style="{
|
||||||
|
top: `${highlightRect.bottom}px`,
|
||||||
|
left: '0',
|
||||||
|
width: '100%',
|
||||||
|
height: `calc(100% - ${highlightRect.bottom}px)`
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<!-- Left overlay -->
|
||||||
|
<div
|
||||||
|
class="tutorial-backdrop-part"
|
||||||
|
:style="{
|
||||||
|
top: `${highlightRect.top}px`,
|
||||||
|
left: '0',
|
||||||
|
width: `${highlightRect.left}px`,
|
||||||
|
height: `${highlightRect.height}px`
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<!-- Right overlay -->
|
||||||
|
<div
|
||||||
|
class="tutorial-backdrop-part"
|
||||||
|
:style="{
|
||||||
|
top: `${highlightRect.top}px`,
|
||||||
|
left: `${highlightRect.right}px`,
|
||||||
|
width: `calc(100% - ${highlightRect.right}px)`,
|
||||||
|
height: `${highlightRect.height}px`
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<!-- Highlight border -->
|
||||||
|
<div
|
||||||
|
class="tutorial-highlight-border"
|
||||||
|
:style="{
|
||||||
|
top: `${highlightRect.top}px`,
|
||||||
|
left: `${highlightRect.left}px`,
|
||||||
|
width: `${highlightRect.width}px`,
|
||||||
|
height: `${highlightRect.height}px`
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- Full overlay for center placement (no target) -->
|
||||||
|
<div v-else class="tutorial-backdrop-full" />
|
||||||
|
|
||||||
|
<!-- Tutorial tooltip -->
|
||||||
|
<div
|
||||||
|
v-if="tooltipPosition"
|
||||||
|
class="tutorial-tooltip"
|
||||||
|
:class="`tutorial-tooltip-${currentStep.placement || 'center'}`"
|
||||||
|
:style="{
|
||||||
|
top: tooltipPosition.top,
|
||||||
|
left: tooltipPosition.left,
|
||||||
|
transform: tooltipPosition.transform
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<Card class="tutorial-card">
|
||||||
|
<CardHeader class="pb-3">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<CardTitle class="text-lg">{{ t(currentStep.title) }}</CardTitle>
|
||||||
|
<Button v-if="currentStep.canSkip" variant="ghost" size="icon" class="h-6 w-6" @click="skipTutorial">
|
||||||
|
<XIcon :size="16" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<CardDescription class="text-sm mt-2">
|
||||||
|
{{ t(currentStep.content) }}
|
||||||
|
</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
|
||||||
|
<CardContent class="pt-0 space-y-3">
|
||||||
|
<!-- Progress bar -->
|
||||||
|
<div class="space-y-1">
|
||||||
|
<div class="flex justify-between text-xs text-muted-foreground">
|
||||||
|
<span>{{ t('tutorial.progress') }}</span>
|
||||||
|
<span>{{ tutorialState.currentStepIndex + 1 }} / {{ totalSteps }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="w-full bg-secondary rounded-full h-1.5">
|
||||||
|
<div class="bg-primary h-1.5 rounded-full transition-all duration-300" :style="{ width: `${progress}%` }" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Navigation buttons -->
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<Button v-if="tutorialState.currentStepIndex > 0" variant="outline" size="sm" @click="previousStep">
|
||||||
|
<ChevronLeftIcon :size="16" class="mr-1" />
|
||||||
|
{{ t('tutorial.previous') }}
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button v-if="!isLastStep" class="ml-auto" size="sm" @click="handleNext" :disabled="!canProceed">
|
||||||
|
{{ t('tutorial.next') }}
|
||||||
|
<ChevronRightIcon :size="16" class="ml-1" />
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button v-else class="ml-auto" size="sm" @click="completeTutorial">
|
||||||
|
{{ t('tutorial.completeButton') }}
|
||||||
|
<CheckIcon :size="16" class="ml-1" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Teleport>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
|
||||||
|
import { useTutorial, getTutorialSteps } from '@/composables/useTutorial'
|
||||||
|
import { useI18n } from '@/composables/useI18n'
|
||||||
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
||||||
|
import { Button } from '@/components/ui/button'
|
||||||
|
import { XIcon, ChevronLeftIcon, ChevronRightIcon, CheckIcon } from 'lucide-vue-next'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
const { tutorialState, currentStep, progress, isLastStep, nextStep, previousStep, skipTutorial, completeTutorial } = useTutorial()
|
||||||
|
|
||||||
|
const highlightRect = ref<DOMRect | null>(null)
|
||||||
|
const tooltipPosition = ref<{ top: string; left: string; transform: string } | null>(null)
|
||||||
|
const totalSteps = computed(() => getTutorialSteps().length)
|
||||||
|
const isMobile = ref(false)
|
||||||
|
|
||||||
|
// Check if current step can proceed
|
||||||
|
const canProceed = computed(() => {
|
||||||
|
if (!currentStep.value) return false
|
||||||
|
|
||||||
|
// 所有步骤都允许手动点击下一步
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
// 检测是否为移动端
|
||||||
|
const checkMobile = () => {
|
||||||
|
isMobile.value = window.innerWidth < 768
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate highlight and tooltip positions
|
||||||
|
const updatePositions = () => {
|
||||||
|
if (!currentStep.value) {
|
||||||
|
highlightRect.value = null
|
||||||
|
tooltipPosition.value = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测移动端
|
||||||
|
checkMobile()
|
||||||
|
|
||||||
|
// For center placement, no target element needed
|
||||||
|
if (!currentStep.value.target || currentStep.value.placement === 'center') {
|
||||||
|
highlightRect.value = null
|
||||||
|
tooltipPosition.value = {
|
||||||
|
top: '50%',
|
||||||
|
left: '50%',
|
||||||
|
transform: 'translate(-50%, -50%)'
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find target element
|
||||||
|
const targetElement = document.querySelector(currentStep.value.target)
|
||||||
|
if (!targetElement) {
|
||||||
|
// Fallback to center if target not found
|
||||||
|
highlightRect.value = null
|
||||||
|
tooltipPosition.value = {
|
||||||
|
top: '50%',
|
||||||
|
left: '50%',
|
||||||
|
transform: 'translate(-50%, -50%)'
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-scroll target element into view
|
||||||
|
targetElement.scrollIntoView({
|
||||||
|
behavior: 'smooth',
|
||||||
|
block: 'center',
|
||||||
|
inline: 'center'
|
||||||
|
})
|
||||||
|
|
||||||
|
// Get target element rect
|
||||||
|
const rect = targetElement.getBoundingClientRect()
|
||||||
|
const padding = currentStep.value.highlightPadding || 8
|
||||||
|
|
||||||
|
// Set highlight rect with padding
|
||||||
|
highlightRect.value = new DOMRect(rect.left - padding, rect.top - padding, rect.width + padding * 2, rect.height + padding * 2)
|
||||||
|
|
||||||
|
// 获取视口尺寸
|
||||||
|
const viewportWidth = window.innerWidth
|
||||||
|
const viewportHeight = window.innerHeight
|
||||||
|
|
||||||
|
// 气泡的预估尺寸(根据视口大小响应式调整)
|
||||||
|
const tooltipWidth = isMobile.value ? Math.min(viewportWidth - 32, 360) : 480
|
||||||
|
const tooltipHeight = isMobile.value ? 280 : 300 // 预估高度
|
||||||
|
|
||||||
|
// 计算各个方向的可用空间
|
||||||
|
const spaceTop = rect.top
|
||||||
|
const spaceBottom = viewportHeight - rect.bottom
|
||||||
|
const spaceLeft = rect.left
|
||||||
|
const spaceRight = viewportWidth - rect.right
|
||||||
|
|
||||||
|
const tooltipOffset = isMobile.value ? 8 : 16 // 移动端使用更小的间距
|
||||||
|
const edgeMargin = isMobile.value ? 8 : 16 // 距离边缘的最小距离
|
||||||
|
|
||||||
|
// 根据优先级和可用空间自动选择最佳位置
|
||||||
|
let placement = currentStep.value.placement || 'bottom'
|
||||||
|
let finalPosition: { top: string; left: string; transform: string }
|
||||||
|
|
||||||
|
// 移动端优先使用 bottom 或 top 位置
|
||||||
|
if (isMobile.value) {
|
||||||
|
// 移动端强制使用 top/bottom,忽略 left/right
|
||||||
|
if (placement === 'left' || placement === 'right') {
|
||||||
|
placement = spaceBottom > spaceTop ? 'bottom' : 'top'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 智能位置选择:如果指定位置空间不足,自动调整
|
||||||
|
const canFitTop = spaceTop >= tooltipHeight + tooltipOffset + edgeMargin
|
||||||
|
const canFitBottom = spaceBottom >= tooltipHeight + tooltipOffset + edgeMargin
|
||||||
|
const canFitLeft = spaceLeft >= tooltipWidth + tooltipOffset + edgeMargin
|
||||||
|
const canFitRight = spaceRight >= tooltipWidth + tooltipOffset + edgeMargin
|
||||||
|
|
||||||
|
// 自动调整位置
|
||||||
|
if (placement === 'top' && !canFitTop && canFitBottom) {
|
||||||
|
placement = 'bottom'
|
||||||
|
} else if (placement === 'bottom' && !canFitBottom && canFitTop) {
|
||||||
|
placement = 'top'
|
||||||
|
} else if (placement === 'left' && !canFitLeft && canFitRight) {
|
||||||
|
placement = 'right'
|
||||||
|
} else if (placement === 'right' && !canFitRight && canFitLeft) {
|
||||||
|
placement = 'left'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算位置
|
||||||
|
switch (placement) {
|
||||||
|
case 'top': {
|
||||||
|
let left = rect.left + rect.width / 2
|
||||||
|
// 确保不超出左右边界
|
||||||
|
left = Math.max(tooltipWidth / 2 + edgeMargin, Math.min(left, viewportWidth - tooltipWidth / 2 - edgeMargin))
|
||||||
|
finalPosition = {
|
||||||
|
top: `${Math.max(edgeMargin, rect.top - tooltipOffset)}px`,
|
||||||
|
left: `${left}px`,
|
||||||
|
transform: 'translate(-50%, -100%)'
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'bottom': {
|
||||||
|
let left = rect.left + rect.width / 2
|
||||||
|
// 确保不超出左右边界
|
||||||
|
left = Math.max(tooltipWidth / 2 + edgeMargin, Math.min(left, viewportWidth - tooltipWidth / 2 - edgeMargin))
|
||||||
|
finalPosition = {
|
||||||
|
top: `${Math.min(viewportHeight - tooltipHeight - edgeMargin, rect.bottom + tooltipOffset)}px`,
|
||||||
|
left: `${left}px`,
|
||||||
|
transform: 'translate(-50%, 0)'
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'left': {
|
||||||
|
let top = rect.top + rect.height / 2
|
||||||
|
// 确保不超出上下边界
|
||||||
|
top = Math.max(tooltipHeight / 2 + edgeMargin, Math.min(top, viewportHeight - tooltipHeight / 2 - edgeMargin))
|
||||||
|
finalPosition = {
|
||||||
|
top: `${top}px`,
|
||||||
|
left: `${Math.max(edgeMargin, rect.left - tooltipOffset)}px`,
|
||||||
|
transform: 'translate(-100%, -50%)'
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'right': {
|
||||||
|
let top = rect.top + rect.height / 2
|
||||||
|
// 确保不超出上下边界
|
||||||
|
top = Math.max(tooltipHeight / 2 + edgeMargin, Math.min(top, viewportHeight - tooltipHeight / 2 - edgeMargin))
|
||||||
|
finalPosition = {
|
||||||
|
top: `${top}px`,
|
||||||
|
left: `${Math.min(viewportWidth - tooltipWidth - edgeMargin, rect.right + tooltipOffset)}px`,
|
||||||
|
transform: 'translate(0, -50%)'
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
finalPosition = {
|
||||||
|
top: '50%',
|
||||||
|
left: '50%',
|
||||||
|
transform: 'translate(-50%, -50%)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tooltipPosition.value = finalPosition
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle next step
|
||||||
|
const handleNext = () => {
|
||||||
|
if (canProceed.value) {
|
||||||
|
nextStep()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update positions when step changes
|
||||||
|
watch(
|
||||||
|
() => currentStep.value,
|
||||||
|
() => {
|
||||||
|
// Wait for DOM update and route change
|
||||||
|
setTimeout(() => {
|
||||||
|
updatePositions()
|
||||||
|
}, 100)
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
// Update positions on window resize or scroll
|
||||||
|
const handleResize = () => {
|
||||||
|
checkMobile()
|
||||||
|
updatePositions()
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
checkMobile()
|
||||||
|
window.addEventListener('resize', handleResize)
|
||||||
|
window.addEventListener('scroll', handleResize, true)
|
||||||
|
updatePositions()
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
window.removeEventListener('resize', handleResize)
|
||||||
|
window.removeEventListener('scroll', handleResize, true)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.tutorial-overlay {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 9999;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tutorial-backdrop-part {
|
||||||
|
position: fixed;
|
||||||
|
background: rgba(0, 0, 0, 0.7);
|
||||||
|
pointer-events: auto;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tutorial-backdrop-full {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.7);
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tutorial-highlight-border {
|
||||||
|
position: fixed;
|
||||||
|
background: transparent;
|
||||||
|
border: 4px solid rgba(59, 130, 246, 0.5);
|
||||||
|
border-radius: 8px;
|
||||||
|
pointer-events: none;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
z-index: 10000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tutorial-tooltip {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 10001;
|
||||||
|
pointer-events: auto;
|
||||||
|
max-width: 480px;
|
||||||
|
min-width: 320px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 移动端样式调整 */
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.tutorial-tooltip {
|
||||||
|
max-width: calc(100vw - 32px);
|
||||||
|
min-width: calc(100vw - 32px);
|
||||||
|
width: calc(100vw - 32px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tutorial-tooltip-center {
|
||||||
|
max-width: calc(100vw - 32px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tutorial-card {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tutorial-highlight-border {
|
||||||
|
border-width: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tutorial-tooltip-center {
|
||||||
|
max-width: 560px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.tutorial-tooltip-center {
|
||||||
|
max-width: calc(100vw - 32px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tutorial-card {
|
||||||
|
animation: tutorial-fade-in 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes tutorial-fade-in {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark mode adjustments */
|
||||||
|
.dark .tutorial-backdrop-part {
|
||||||
|
background: rgba(0, 0, 0, 0.85);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .tutorial-backdrop-full {
|
||||||
|
background: rgba(0, 0, 0, 0.85);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .tutorial-highlight-border {
|
||||||
|
border-color: rgba(59, 130, 246, 0.6);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
120
src/components/UpdateDialog.vue
Normal file
120
src/components/UpdateDialog.vue
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog :open="open" @update:open="$emit('update:open', $event)">
|
||||||
|
<DialogScrollContent class="max-w-2xl max-h-[80vh] flex flex-col">
|
||||||
|
<DialogHeader class="flex-shrink-0">
|
||||||
|
<DialogTitle>{{ t('settings.newVersionAvailable', { version: versionInfo?.version || '' }) }}</DialogTitle>
|
||||||
|
<DialogDescription>{{ t('settings.updateAvailable') }}</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
|
||||||
|
<div class="flex-1 overflow-y-auto min-h-0 mt-4 pr-2">
|
||||||
|
<div class="prose prose-sm dark:prose-invert max-w-none" v-html="renderedMarkdown" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<DialogFooter class="flex gap-2 flex-shrink-0 mt-4">
|
||||||
|
<Button variant="outline" @click="$emit('update:open', false)">
|
||||||
|
{{ t('common.cancel') }}
|
||||||
|
</Button>
|
||||||
|
<Button @click="handleDownload">
|
||||||
|
<Download class="mr-2 h-4 w-4" />
|
||||||
|
{{ t('settings.download') }}
|
||||||
|
</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
</DialogScrollContent>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { marked } from 'marked'
|
||||||
|
import { useI18n } from '@/composables/useI18n'
|
||||||
|
import { Dialog, DialogScrollContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog'
|
||||||
|
import { Button } from '@/components/ui/button'
|
||||||
|
import { Download } from 'lucide-vue-next'
|
||||||
|
import type { VersionInfo } from '@/utils/versionCheck'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
open: boolean
|
||||||
|
versionInfo: VersionInfo | null
|
||||||
|
}>()
|
||||||
|
|
||||||
|
defineEmits<{
|
||||||
|
'update:open': [value: boolean]
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const renderedMarkdown = computed(() => {
|
||||||
|
if (!props.versionInfo?.releaseNotes) return ''
|
||||||
|
return marked(props.versionInfo.releaseNotes)
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleDownload = () => {
|
||||||
|
if (props.versionInfo?.downloadUrl) {
|
||||||
|
window.open(props.versionInfo.downloadUrl, '_blank')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
:deep(.prose) {
|
||||||
|
color: hsl(var(--foreground));
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.prose h1) {
|
||||||
|
font-size: 1.5em;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.prose h2) {
|
||||||
|
font-size: 1.25em;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-top: 0.8em;
|
||||||
|
margin-bottom: 0.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.prose h3) {
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-top: 0.6em;
|
||||||
|
margin-bottom: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.prose p) {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.prose ul) {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
padding-left: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.prose li) {
|
||||||
|
margin-top: 0.25em;
|
||||||
|
margin-bottom: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.prose code) {
|
||||||
|
background: hsl(var(--muted));
|
||||||
|
padding: 0.2em 0.4em;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
font-size: 0.875em;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.prose pre) {
|
||||||
|
background: hsl(var(--muted));
|
||||||
|
padding: 1em;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
overflow-x: auto;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.prose a) {
|
||||||
|
color: hsl(var(--primary));
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
v-bind="{ ...$attrs, ...forwarded }"
|
v-bind="{ ...$attrs, ...forwarded }"
|
||||||
:class="
|
:class="
|
||||||
cn(
|
cn(
|
||||||
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg',
|
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-2xl',
|
||||||
props.class
|
props.class
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
v-bind="{ ...$attrs, ...forwarded }"
|
v-bind="{ ...$attrs, ...forwarded }"
|
||||||
:class="
|
:class="
|
||||||
cn(
|
cn(
|
||||||
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 w-[calc(100vw-3rem)] translate-x-[-50%] translate-y-[-50%] rounded-lg border shadow-lg duration-200 sm:w-auto flex flex-col p-0',
|
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 w-[calc(100vw-3rem)] translate-x-[-50%] translate-y-[-50%] rounded-lg border shadow-lg duration-200 sm:w-auto sm:min-w-[764px] flex flex-col p-0',
|
||||||
containerClass
|
containerClass
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
|
|||||||
22
src/components/ui/empty/Empty.vue
Normal file
22
src/components/ui/empty/Empty.vue
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
data-slot="empty"
|
||||||
|
:class="
|
||||||
|
cn(
|
||||||
|
'flex min-w-0 flex-1 flex-col items-center justify-center gap-6 text-balance rounded-lg border-dashed p-6 text-center md:p-12',
|
||||||
|
props.class
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { HTMLAttributes } from 'vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
class?: HTMLAttributes['class']
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
14
src/components/ui/empty/EmptyContent.vue
Normal file
14
src/components/ui/empty/EmptyContent.vue
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<template>
|
||||||
|
<div data-slot="empty-content" :class="cn('flex w-full min-w-0 max-w-sm flex-col items-center gap-4 text-balance text-sm', props.class)">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { HTMLAttributes } from 'vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
class?: HTMLAttributes['class']
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
19
src/components/ui/empty/EmptyDescription.vue
Normal file
19
src/components/ui/empty/EmptyDescription.vue
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<template>
|
||||||
|
<p
|
||||||
|
data-slot="empty-description"
|
||||||
|
:class="
|
||||||
|
cn('text-muted-foreground [&>a:hover]:text-primary text-sm/relaxed [&>a]:underline [&>a]:underline-offset-4', $attrs.class ?? '')
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { HTMLAttributes } from 'vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
class?: HTMLAttributes['class']
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
14
src/components/ui/empty/EmptyHeader.vue
Normal file
14
src/components/ui/empty/EmptyHeader.vue
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<template>
|
||||||
|
<div data-slot="empty-header" :class="cn('flex max-w-sm flex-col items-center gap-2 text-center', props.class)">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { HTMLAttributes } from 'vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
class?: HTMLAttributes['class']
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
17
src/components/ui/empty/EmptyMedia.vue
Normal file
17
src/components/ui/empty/EmptyMedia.vue
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<template>
|
||||||
|
<div data-slot="empty-icon" :data-variant="variant" :class="cn(emptyMediaVariants({ variant }), props.class)">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { HTMLAttributes } from 'vue'
|
||||||
|
import type { EmptyMediaVariants } from '.'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
import { emptyMediaVariants } from '.'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
class?: HTMLAttributes['class']
|
||||||
|
variant?: EmptyMediaVariants['variant']
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
14
src/components/ui/empty/EmptyTitle.vue
Normal file
14
src/components/ui/empty/EmptyTitle.vue
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<template>
|
||||||
|
<div data-slot="empty-title" :class="cn('text-lg font-medium tracking-tight', props.class)">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { HTMLAttributes } from 'vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
class?: HTMLAttributes['class']
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
23
src/components/ui/empty/index.ts
Normal file
23
src/components/ui/empty/index.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import type { VariantProps } from 'class-variance-authority'
|
||||||
|
import { cva } from 'class-variance-authority'
|
||||||
|
|
||||||
|
export { default as Empty } from './Empty.vue'
|
||||||
|
export { default as EmptyContent } from './EmptyContent.vue'
|
||||||
|
export { default as EmptyDescription } from './EmptyDescription.vue'
|
||||||
|
export { default as EmptyHeader } from './EmptyHeader.vue'
|
||||||
|
export { default as EmptyMedia } from './EmptyMedia.vue'
|
||||||
|
export { default as EmptyTitle } from './EmptyTitle.vue'
|
||||||
|
|
||||||
|
export const emptyMediaVariants = cva('mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0', {
|
||||||
|
variants: {
|
||||||
|
variant: {
|
||||||
|
default: 'bg-transparent',
|
||||||
|
icon: "bg-muted text-foreground flex size-10 shrink-0 items-center justify-center rounded-lg [&_svg:not([class*='size-'])]:size-6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
variant: 'default'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export type EmptyMediaVariants = VariantProps<typeof emptyMediaVariants>
|
||||||
25
src/components/ui/scroll-area/ScrollArea.vue
Normal file
25
src/components/ui/scroll-area/ScrollArea.vue
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<template>
|
||||||
|
<ScrollAreaRoot data-slot="scroll-area" v-bind="delegatedProps" :class="cn('relative', props.class)">
|
||||||
|
<ScrollAreaViewport
|
||||||
|
data-slot="scroll-area-viewport"
|
||||||
|
class="focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</ScrollAreaViewport>
|
||||||
|
<ScrollBar />
|
||||||
|
<ScrollAreaCorner />
|
||||||
|
</ScrollAreaRoot>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { ScrollAreaRootProps } from 'reka-ui'
|
||||||
|
import type { HTMLAttributes } from 'vue'
|
||||||
|
import { reactiveOmit } from '@vueuse/core'
|
||||||
|
import { ScrollAreaCorner, ScrollAreaRoot, ScrollAreaViewport } from 'reka-ui'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
import ScrollBar from './ScrollBar.vue'
|
||||||
|
|
||||||
|
const props = defineProps<ScrollAreaRootProps & { class?: HTMLAttributes['class'] }>()
|
||||||
|
|
||||||
|
const delegatedProps = reactiveOmit(props, 'class')
|
||||||
|
</script>
|
||||||
30
src/components/ui/scroll-area/ScrollBar.vue
Normal file
30
src/components/ui/scroll-area/ScrollBar.vue
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<template>
|
||||||
|
<ScrollAreaScrollbar
|
||||||
|
data-slot="scroll-area-scrollbar"
|
||||||
|
v-bind="delegatedProps"
|
||||||
|
:class="
|
||||||
|
cn(
|
||||||
|
'flex touch-none p-px transition-colors select-none',
|
||||||
|
orientation === 'vertical' && 'h-full w-2.5 border-l border-l-transparent',
|
||||||
|
orientation === 'horizontal' && 'h-2.5 flex-col border-t border-t-transparent',
|
||||||
|
props.class
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<ScrollAreaThumb data-slot="scroll-area-thumb" class="bg-border relative flex-1 rounded-full" />
|
||||||
|
</ScrollAreaScrollbar>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { ScrollAreaScrollbarProps } from 'reka-ui'
|
||||||
|
import type { HTMLAttributes } from 'vue'
|
||||||
|
import { reactiveOmit } from '@vueuse/core'
|
||||||
|
import { ScrollAreaScrollbar, ScrollAreaThumb } from 'reka-ui'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<ScrollAreaScrollbarProps & { class?: HTMLAttributes['class'] }>(), {
|
||||||
|
orientation: 'vertical'
|
||||||
|
})
|
||||||
|
|
||||||
|
const delegatedProps = reactiveOmit(props, 'class')
|
||||||
|
</script>
|
||||||
2
src/components/ui/scroll-area/index.ts
Normal file
2
src/components/ui/scroll-area/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export { default as ScrollArea } from './ScrollArea.vue'
|
||||||
|
export { default as ScrollBar } from './ScrollBar.vue'
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Sheet v-else-if="isMobile" :open="openMobile" v-bind="$attrs" @update:open="setOpenMobile">
|
<Sheet v-else-if="isMobile" :open="openMobile" v-bind="$attrs" @update:open="handleOpenMobileChange">
|
||||||
<SheetContent
|
<SheetContent
|
||||||
data-sidebar="sidebar"
|
data-sidebar="sidebar"
|
||||||
data-slot="sidebar"
|
data-slot="sidebar"
|
||||||
@@ -79,12 +79,15 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { SidebarProps } from '.'
|
import type { SidebarProps } from '.'
|
||||||
|
import { watch } from 'vue'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
import { Sheet, SheetContent } from '@/components/ui/sheet'
|
import { Sheet, SheetContent } from '@/components/ui/sheet'
|
||||||
import SheetDescription from '@/components/ui/sheet/SheetDescription.vue'
|
import SheetDescription from '@/components/ui/sheet/SheetDescription.vue'
|
||||||
import SheetHeader from '@/components/ui/sheet/SheetHeader.vue'
|
import SheetHeader from '@/components/ui/sheet/SheetHeader.vue'
|
||||||
import SheetTitle from '@/components/ui/sheet/SheetTitle.vue'
|
import SheetTitle from '@/components/ui/sheet/SheetTitle.vue'
|
||||||
import { SIDEBAR_WIDTH_MOBILE, useSidebar } from './utils'
|
import { SIDEBAR_WIDTH_MOBILE, useSidebar } from './utils'
|
||||||
|
import { useTutorial } from '@/composables/useTutorial'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
inheritAttrs: false
|
inheritAttrs: false
|
||||||
@@ -96,5 +99,51 @@
|
|||||||
collapsible: 'offcanvas'
|
collapsible: 'offcanvas'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
const { isMobile, state, openMobile, setOpenMobile } = useSidebar()
|
const { isMobile, state, openMobile, setOpenMobile } = useSidebar()
|
||||||
|
const { tutorialState, currentStep, nextStep } = useTutorial()
|
||||||
|
|
||||||
|
// 包装setOpenMobile以拦截教程期间的关闭操作
|
||||||
|
const handleOpenMobileChange = (open: boolean) => {
|
||||||
|
// 如果是移动端且在教程的菜单相关步骤,阻止关闭侧边栏
|
||||||
|
if (tutorialState.value.isActive && currentStep.value) {
|
||||||
|
// 只在第3步期间阻止关闭侧边栏,让玩家必须手动打开
|
||||||
|
if (currentStep.value.id === 'menu_intro_mobile') {
|
||||||
|
// 只允许打开,不允许关闭
|
||||||
|
if (open) {
|
||||||
|
setOpenMobile(true)
|
||||||
|
}
|
||||||
|
// 如果试图关闭,忽略该操作,保持打开状态
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 其他情况正常更新
|
||||||
|
setOpenMobile(open)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听openMobile变化,在移动端教程第3步时,侧边栏打开后自动推进到第4步
|
||||||
|
watch(
|
||||||
|
() => openMobile.value,
|
||||||
|
(isOpen) => {
|
||||||
|
if (isMobile.value && tutorialState.value.isActive && currentStep.value) {
|
||||||
|
// 如果在第3步且侧边栏刚打开,自动推进到第4步
|
||||||
|
if (currentStep.value.id === 'menu_intro_mobile' && isOpen) {
|
||||||
|
setTimeout(() => {
|
||||||
|
nextStep()
|
||||||
|
}, 300) // 延迟300ms让侧边栏动画完成
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// 监听路由变化,在移动端关闭侧边栏
|
||||||
|
watch(
|
||||||
|
() => router.currentRoute.value.path,
|
||||||
|
() => {
|
||||||
|
if (isMobile.value && openMobile.value) {
|
||||||
|
// 路由变化时关闭移动端侧边栏
|
||||||
|
setOpenMobile(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -37,6 +37,13 @@
|
|||||||
import { CircleCheckIcon, InfoIcon, Loader2Icon, OctagonXIcon, TriangleAlertIcon, XIcon } from 'lucide-vue-next'
|
import { CircleCheckIcon, InfoIcon, Loader2Icon, OctagonXIcon, TriangleAlertIcon, XIcon } from 'lucide-vue-next'
|
||||||
import { Toaster as Sonner } from 'vue-sonner'
|
import { Toaster as Sonner } from 'vue-sonner'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
|
import 'vue-sonner/style.css'
|
||||||
|
|
||||||
const props = defineProps<ToasterProps>()
|
const props = defineProps<ToasterProps>()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.dark [data-sonner-toast][data-styled='true'] [data-description] {
|
||||||
|
color: oklch(0.91 0 0 / 1);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export const useGameConfig = () => {
|
|||||||
[BuildingType.RoboticsFactory]: 'roboticsFactory',
|
[BuildingType.RoboticsFactory]: 'roboticsFactory',
|
||||||
[BuildingType.NaniteFactory]: 'naniteFactory',
|
[BuildingType.NaniteFactory]: 'naniteFactory',
|
||||||
[BuildingType.Shipyard]: 'shipyard',
|
[BuildingType.Shipyard]: 'shipyard',
|
||||||
|
[BuildingType.Hangar]: 'hangar',
|
||||||
[BuildingType.ResearchLab]: 'researchLab',
|
[BuildingType.ResearchLab]: 'researchLab',
|
||||||
[BuildingType.MetalStorage]: 'metalStorage',
|
[BuildingType.MetalStorage]: 'metalStorage',
|
||||||
[BuildingType.CrystalStorage]: 'crystalStorage',
|
[BuildingType.CrystalStorage]: 'crystalStorage',
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
import { useGameStore } from '@/stores/gameStore'
|
|
||||||
import { useUniverseStore } from '@/stores/universeStore'
|
|
||||||
import * as gameLogic from '@/logic/gameLogic'
|
|
||||||
import * as planetLogic from '@/logic/planetLogic'
|
|
||||||
import * as resourceLogic from '@/logic/resourceLogic'
|
|
||||||
import * as officerLogic from '@/logic/officerLogic'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 游戏生命周期管理
|
|
||||||
* 处理游戏初始化、NPC星球生成等
|
|
||||||
*/
|
|
||||||
export const useGameLifecycle = () => {
|
|
||||||
const gameStore = useGameStore()
|
|
||||||
const universeStore = useUniverseStore()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成NPC星球
|
|
||||||
*/
|
|
||||||
const generateNPCPlanets = (npcCount: number, planetPrefix: string) => {
|
|
||||||
for (let i = 0; i < npcCount; i++) {
|
|
||||||
const position = gameLogic.generateRandomPosition()
|
|
||||||
const key = gameLogic.generatePositionKey(position.galaxy, position.system, position.position)
|
|
||||||
if (universeStore.planets[key]) continue
|
|
||||||
const npcPlanet = planetLogic.createNPCPlanet(i, position, planetPrefix)
|
|
||||||
universeStore.planets[key] = npcPlanet
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化游戏
|
|
||||||
*/
|
|
||||||
const initGame = async (playerName: string, homePlanetName: string, planetPrefix: string) => {
|
|
||||||
const shouldInit = gameLogic.shouldInitializeGame(gameStore.player.planets)
|
|
||||||
|
|
||||||
if (!shouldInit) {
|
|
||||||
const now = Date.now()
|
|
||||||
|
|
||||||
// 计算离线收益(直接同步计算)
|
|
||||||
const bonuses = officerLogic.calculateActiveBonuses(gameStore.player.officers, now)
|
|
||||||
gameStore.player.planets.forEach(planet => {
|
|
||||||
resourceLogic.updatePlanetResources(planet, now, bonuses)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 只在没有NPC星球时才生成(首次加载已有玩家数据时)
|
|
||||||
if (Object.keys(universeStore.planets).length === 0) {
|
|
||||||
generateNPCPlanets(200, planetPrefix)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
gameStore.player = gameLogic.initializePlayer(gameStore.player.id, playerName)
|
|
||||||
const initialPlanet = planetLogic.createInitialPlanet(gameStore.player.id, homePlanetName)
|
|
||||||
gameStore.player.planets = [initialPlanet]
|
|
||||||
gameStore.currentPlanetId = initialPlanet.id
|
|
||||||
// 新玩家初始化时生成NPC星球
|
|
||||||
generateNPCPlanets(200, planetPrefix)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
initGame,
|
|
||||||
generateNPCPlanets
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
import { useGameStore } from '@/stores/gameStore'
|
|
||||||
import { useNPCStore } from '@/stores/npcStore'
|
|
||||||
import type { FleetMission } from '@/types/game'
|
|
||||||
import * as gameLogic from '@/logic/gameLogic'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 游戏更新循环
|
|
||||||
* 处理游戏状态的定期更新
|
|
||||||
*/
|
|
||||||
export const useGameUpdate = (
|
|
||||||
processMissionArrival: (mission: FleetMission) => Promise<void>,
|
|
||||||
processMissionReturn: (mission: FleetMission) => void,
|
|
||||||
processNPCMissionArrival: (npc: any, mission: FleetMission) => void,
|
|
||||||
processNPCMissionReturn: (npc: any, mission: FleetMission) => void,
|
|
||||||
updateNPCGrowth: (deltaSeconds: number) => void,
|
|
||||||
updateNPCBehavior: (deltaSeconds: number) => void
|
|
||||||
) => {
|
|
||||||
const gameStore = useGameStore()
|
|
||||||
const npcStore = useNPCStore()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 游戏主更新函数
|
|
||||||
*/
|
|
||||||
const updateGame = () => {
|
|
||||||
if (gameStore.isPaused) return
|
|
||||||
const now = Date.now()
|
|
||||||
gameStore.gameTime = now
|
|
||||||
|
|
||||||
// 检查军官过期
|
|
||||||
gameLogic.checkOfficersExpiration(gameStore.player.officers, now)
|
|
||||||
|
|
||||||
// 处理游戏更新(建造队列、研究队列等)
|
|
||||||
const result = gameLogic.processGameUpdate(gameStore.player, now)
|
|
||||||
gameStore.player.researchQueue = result.updatedResearchQueue
|
|
||||||
|
|
||||||
// 处理舰队任务
|
|
||||||
gameStore.player.fleetMissions.forEach(mission => {
|
|
||||||
if (mission.status === 'outbound' && now >= mission.arrivalTime) {
|
|
||||||
processMissionArrival(mission)
|
|
||||||
} else if (mission.status === 'returning' && mission.returnTime && now >= mission.returnTime) {
|
|
||||||
processMissionReturn(mission)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 处理NPC舰队任务
|
|
||||||
npcStore.npcs.forEach(npc => {
|
|
||||||
if (npc.fleetMissions) {
|
|
||||||
npc.fleetMissions.forEach(mission => {
|
|
||||||
if (mission.status === 'outbound' && now >= mission.arrivalTime) {
|
|
||||||
processNPCMissionArrival(npc, mission)
|
|
||||||
} else if (mission.status === 'returning' && mission.returnTime && now >= mission.returnTime) {
|
|
||||||
processNPCMissionReturn(npc, mission)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// NPC成长系统更新
|
|
||||||
updateNPCGrowth(1) // 传入1秒的时间间隔
|
|
||||||
|
|
||||||
// NPC行为系统更新(侦查和攻击决策)
|
|
||||||
updateNPCBehavior(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
updateGame
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,7 +10,7 @@ export const useI18n = () => {
|
|||||||
const messages = computed(() => locales[currentLocale.value])
|
const messages = computed(() => locales[currentLocale.value])
|
||||||
|
|
||||||
// 获取翻译文本的辅助函数
|
// 获取翻译文本的辅助函数
|
||||||
const t = (key: string): string => {
|
const t = (key: string, params?: Record<string, string | number>): string => {
|
||||||
const keys = key.split('.')
|
const keys = key.split('.')
|
||||||
let value: any = messages.value
|
let value: any = messages.value
|
||||||
|
|
||||||
@@ -22,7 +22,16 @@ export const useI18n = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return typeof value === 'string' ? value : key
|
let result = typeof value === 'string' ? value : key
|
||||||
|
|
||||||
|
// 替换参数占位符
|
||||||
|
if (params) {
|
||||||
|
Object.entries(params).forEach(([paramKey, paramValue]) => {
|
||||||
|
result = result.replace(new RegExp(`\\{${paramKey}\\}`, 'g'), String(paramValue))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
const setLocale = (locale: Locale) => {
|
const setLocale = (locale: Locale) => {
|
||||||
|
|||||||
@@ -1,249 +0,0 @@
|
|||||||
import { useGameStore } from '@/stores/gameStore'
|
|
||||||
import { useUniverseStore } from '@/stores/universeStore'
|
|
||||||
import { useNPCStore } from '@/stores/npcStore'
|
|
||||||
import type { FleetMission } from '@/types/game'
|
|
||||||
import { MissionType } from '@/types/game'
|
|
||||||
import * as gameLogic from '@/logic/gameLogic'
|
|
||||||
import * as fleetLogic from '@/logic/fleetLogic'
|
|
||||||
import * as shipLogic from '@/logic/shipLogic'
|
|
||||||
import * as resourceLogic from '@/logic/resourceLogic'
|
|
||||||
import * as diplomaticLogic from '@/logic/diplomaticLogic'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 舰队任务处理
|
|
||||||
* 处理玩家舰队任务的到达和返回
|
|
||||||
*/
|
|
||||||
export const useMissionHandler = (t: (key: string) => string) => {
|
|
||||||
const gameStore = useGameStore()
|
|
||||||
const universeStore = useUniverseStore()
|
|
||||||
const npcStore = useNPCStore()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理任务到达
|
|
||||||
*/
|
|
||||||
const processMissionArrival = async (mission: FleetMission) => {
|
|
||||||
// 从宇宙星球地图中查找目标星球
|
|
||||||
const targetKey = gameLogic.generatePositionKey(
|
|
||||||
mission.targetPosition.galaxy,
|
|
||||||
mission.targetPosition.system,
|
|
||||||
mission.targetPosition.position
|
|
||||||
)
|
|
||||||
// 先从玩家星球中查找,再从宇宙地图中查找
|
|
||||||
const targetPlanet =
|
|
||||||
gameStore.player.planets.find(
|
|
||||||
p =>
|
|
||||||
p.position.galaxy === mission.targetPosition.galaxy &&
|
|
||||||
p.position.system === mission.targetPosition.system &&
|
|
||||||
p.position.position === mission.targetPosition.position
|
|
||||||
) || universeStore.planets[targetKey]
|
|
||||||
|
|
||||||
// 获取起始星球名称(用于报告)
|
|
||||||
const originPlanet = gameStore.player.planets.find(p => p.id === mission.originPlanetId)
|
|
||||||
const originPlanetName = originPlanet?.name || t('fleetView.unknownPlanet')
|
|
||||||
|
|
||||||
if (mission.missionType === MissionType.Transport) {
|
|
||||||
const result = fleetLogic.processTransportArrival(mission, targetPlanet, gameStore.player, npcStore.npcs)
|
|
||||||
// 生成运输任务报告
|
|
||||||
if (!gameStore.player.missionReports) {
|
|
||||||
gameStore.player.missionReports = []
|
|
||||||
}
|
|
||||||
gameStore.player.missionReports.push({
|
|
||||||
id: `mission-report-${mission.id}`,
|
|
||||||
timestamp: Date.now(),
|
|
||||||
missionType: MissionType.Transport,
|
|
||||||
originPlanetId: mission.originPlanetId,
|
|
||||||
originPlanetName,
|
|
||||||
targetPosition: mission.targetPosition,
|
|
||||||
targetPlanetId: targetPlanet?.id,
|
|
||||||
targetPlanetName:
|
|
||||||
targetPlanet?.name || `[${mission.targetPosition.galaxy}:${mission.targetPosition.system}:${mission.targetPosition.position}]`,
|
|
||||||
success: result.success,
|
|
||||||
message: result.success ? t('missionReports.transportSuccess') : t('missionReports.transportFailed'),
|
|
||||||
details: {
|
|
||||||
transportedResources: mission.cargo
|
|
||||||
},
|
|
||||||
read: false
|
|
||||||
})
|
|
||||||
} else if (mission.missionType === MissionType.Attack) {
|
|
||||||
const attackResult = await fleetLogic.processAttackArrival(mission, targetPlanet, gameStore.player, null, gameStore.player.planets)
|
|
||||||
if (attackResult) {
|
|
||||||
gameStore.player.battleReports.push(attackResult.battleResult)
|
|
||||||
|
|
||||||
// 检查是否攻击了NPC星球,更新外交关系
|
|
||||||
if (targetPlanet) {
|
|
||||||
const targetNpc = npcStore.npcs.find(npc => npc.planets.some(p => p.id === targetPlanet.id))
|
|
||||||
if (targetNpc) {
|
|
||||||
diplomaticLogic.handleAttackReputation(gameStore.player, targetNpc, attackResult.battleResult, npcStore.npcs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attackResult.moon) {
|
|
||||||
gameStore.player.planets.push(attackResult.moon)
|
|
||||||
}
|
|
||||||
if (attackResult.debrisField) {
|
|
||||||
// 将残骸场添加到游戏状态
|
|
||||||
universeStore.debrisFields[attackResult.debrisField.id] = attackResult.debrisField
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (mission.missionType === MissionType.Colonize) {
|
|
||||||
const newPlanet = fleetLogic.processColonizeArrival(mission, targetPlanet, gameStore.player, t('planet.colonyPrefix'))
|
|
||||||
// 生成殖民任务报告
|
|
||||||
if (!gameStore.player.missionReports) {
|
|
||||||
gameStore.player.missionReports = []
|
|
||||||
}
|
|
||||||
gameStore.player.missionReports.push({
|
|
||||||
id: `mission-report-${mission.id}`,
|
|
||||||
timestamp: Date.now(),
|
|
||||||
missionType: MissionType.Colonize,
|
|
||||||
originPlanetId: mission.originPlanetId,
|
|
||||||
originPlanetName,
|
|
||||||
targetPosition: mission.targetPosition,
|
|
||||||
targetPlanetId: newPlanet?.id,
|
|
||||||
targetPlanetName: newPlanet?.name,
|
|
||||||
success: !!newPlanet,
|
|
||||||
message: newPlanet ? t('missionReports.colonizeSuccess') : t('missionReports.colonizeFailed'),
|
|
||||||
details: newPlanet
|
|
||||||
? {
|
|
||||||
newPlanetId: newPlanet.id,
|
|
||||||
newPlanetName: newPlanet.name
|
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
read: false
|
|
||||||
})
|
|
||||||
if (newPlanet) {
|
|
||||||
gameStore.player.planets.push(newPlanet)
|
|
||||||
}
|
|
||||||
} else if (mission.missionType === MissionType.Spy) {
|
|
||||||
const spyReport = fleetLogic.processSpyArrival(mission, targetPlanet, gameStore.player, null, npcStore.npcs)
|
|
||||||
if (spyReport) gameStore.player.spyReports.push(spyReport)
|
|
||||||
} else if (mission.missionType === MissionType.Deploy) {
|
|
||||||
const deployed = fleetLogic.processDeployArrival(mission, targetPlanet, gameStore.player.id)
|
|
||||||
// 生成部署任务报告
|
|
||||||
if (!gameStore.player.missionReports) {
|
|
||||||
gameStore.player.missionReports = []
|
|
||||||
}
|
|
||||||
gameStore.player.missionReports.push({
|
|
||||||
id: `mission-report-${mission.id}`,
|
|
||||||
timestamp: Date.now(),
|
|
||||||
missionType: MissionType.Deploy,
|
|
||||||
originPlanetId: mission.originPlanetId,
|
|
||||||
originPlanetName,
|
|
||||||
targetPosition: mission.targetPosition,
|
|
||||||
targetPlanetId: targetPlanet?.id,
|
|
||||||
targetPlanetName:
|
|
||||||
targetPlanet?.name || `[${mission.targetPosition.galaxy}:${mission.targetPosition.system}:${mission.targetPosition.position}]`,
|
|
||||||
success: deployed,
|
|
||||||
message: deployed ? t('missionReports.deploySuccess') : t('missionReports.deployFailed'),
|
|
||||||
details: {
|
|
||||||
deployedFleet: mission.fleet
|
|
||||||
},
|
|
||||||
read: false
|
|
||||||
})
|
|
||||||
if (deployed) {
|
|
||||||
const missionIndex = gameStore.player.fleetMissions.indexOf(mission)
|
|
||||||
if (missionIndex > -1) gameStore.player.fleetMissions.splice(missionIndex, 1)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else if (mission.missionType === MissionType.Recycle) {
|
|
||||||
// 处理回收任务
|
|
||||||
const debrisId = `debris_${mission.targetPosition.galaxy}_${mission.targetPosition.system}_${mission.targetPosition.position}`
|
|
||||||
const debrisField = universeStore.debrisFields[debrisId]
|
|
||||||
const recycleResult = fleetLogic.processRecycleArrival(mission, debrisField)
|
|
||||||
|
|
||||||
// 生成回收任务报告
|
|
||||||
if (!gameStore.player.missionReports) {
|
|
||||||
gameStore.player.missionReports = []
|
|
||||||
}
|
|
||||||
gameStore.player.missionReports.push({
|
|
||||||
id: `mission-report-${mission.id}`,
|
|
||||||
timestamp: Date.now(),
|
|
||||||
missionType: MissionType.Recycle,
|
|
||||||
originPlanetId: mission.originPlanetId,
|
|
||||||
originPlanetName,
|
|
||||||
targetPosition: mission.targetPosition,
|
|
||||||
success: !!recycleResult,
|
|
||||||
message: recycleResult ? t('missionReports.recycleSuccess') : t('missionReports.recycleFailed'),
|
|
||||||
details: recycleResult
|
|
||||||
? {
|
|
||||||
recycledResources: recycleResult.collectedResources,
|
|
||||||
remainingDebris: recycleResult.remainingDebris || undefined
|
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
read: false
|
|
||||||
})
|
|
||||||
|
|
||||||
if (recycleResult && debrisField) {
|
|
||||||
if (recycleResult.remainingDebris && (recycleResult.remainingDebris.metal > 0 || recycleResult.remainingDebris.crystal > 0)) {
|
|
||||||
// 更新残骸场
|
|
||||||
universeStore.debrisFields[debrisId] = {
|
|
||||||
id: debrisField.id,
|
|
||||||
position: debrisField.position,
|
|
||||||
resources: recycleResult.remainingDebris,
|
|
||||||
createdAt: debrisField.createdAt,
|
|
||||||
expiresAt: debrisField.expiresAt
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 残骸场已被完全收集,删除
|
|
||||||
delete universeStore.debrisFields[debrisId]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (mission.missionType === MissionType.Destroy) {
|
|
||||||
// 处理行星毁灭任务
|
|
||||||
const destroyResult = fleetLogic.processDestroyArrival(mission, targetPlanet, gameStore.player)
|
|
||||||
|
|
||||||
// 生成毁灭任务报告
|
|
||||||
if (!gameStore.player.missionReports) {
|
|
||||||
gameStore.player.missionReports = []
|
|
||||||
}
|
|
||||||
gameStore.player.missionReports.push({
|
|
||||||
id: `mission-report-${mission.id}`,
|
|
||||||
timestamp: Date.now(),
|
|
||||||
missionType: MissionType.Destroy,
|
|
||||||
originPlanetId: mission.originPlanetId,
|
|
||||||
originPlanetName,
|
|
||||||
targetPosition: mission.targetPosition,
|
|
||||||
targetPlanetId: targetPlanet?.id,
|
|
||||||
targetPlanetName: targetPlanet?.name,
|
|
||||||
success: destroyResult?.success || false,
|
|
||||||
message: destroyResult?.success ? t('missionReports.destroySuccess') : t('missionReports.destroyFailed'),
|
|
||||||
details: destroyResult?.success
|
|
||||||
? {
|
|
||||||
destroyedPlanetName:
|
|
||||||
targetPlanet?.name ||
|
|
||||||
`[${mission.targetPosition.galaxy}:${mission.targetPosition.system}:${mission.targetPosition.position}]`
|
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
read: false
|
|
||||||
})
|
|
||||||
|
|
||||||
if (destroyResult && destroyResult.success && destroyResult.planetId) {
|
|
||||||
// 星球被摧毁
|
|
||||||
// 从玩家星球列表中移除(如果是玩家的星球)
|
|
||||||
const planetIndex = gameStore.player.planets.findIndex(p => p.id === destroyResult.planetId)
|
|
||||||
if (planetIndex > -1) {
|
|
||||||
gameStore.player.planets.splice(planetIndex, 1)
|
|
||||||
} else {
|
|
||||||
// 不是玩家星球,从宇宙地图中移除
|
|
||||||
delete universeStore.planets[targetKey]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理任务返回
|
|
||||||
*/
|
|
||||||
const processMissionReturn = (mission: FleetMission) => {
|
|
||||||
const originPlanet = gameStore.player.planets.find(p => p.id === mission.originPlanetId)
|
|
||||||
if (!originPlanet) return
|
|
||||||
shipLogic.addFleet(originPlanet.fleet, mission.fleet)
|
|
||||||
resourceLogic.addResources(originPlanet.resources, mission.cargo)
|
|
||||||
const missionIndex = gameStore.player.fleetMissions.indexOf(mission)
|
|
||||||
if (missionIndex > -1) gameStore.player.fleetMissions.splice(missionIndex, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
processMissionArrival,
|
|
||||||
processMissionReturn
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,300 +0,0 @@
|
|||||||
import { useGameStore } from '@/stores/gameStore'
|
|
||||||
import { useUniverseStore } from '@/stores/universeStore'
|
|
||||||
import { useNPCStore } from '@/stores/npcStore'
|
|
||||||
import type { NPC, FleetMission, IncomingFleetAlert } from '@/types/game'
|
|
||||||
import { MissionType } from '@/types/game'
|
|
||||||
import * as gameLogic from '@/logic/gameLogic'
|
|
||||||
import * as fleetLogic from '@/logic/fleetLogic'
|
|
||||||
import * as shipLogic from '@/logic/shipLogic'
|
|
||||||
import * as npcGrowthLogic from '@/logic/npcGrowthLogic'
|
|
||||||
import * as npcBehaviorLogic from '@/logic/npcBehaviorLogic'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NPC处理
|
|
||||||
* 处理NPC舰队任务、成长系统、行为系统
|
|
||||||
*/
|
|
||||||
export const useNPCHandler = () => {
|
|
||||||
const gameStore = useGameStore()
|
|
||||||
const universeStore = useUniverseStore()
|
|
||||||
const npcStore = useNPCStore()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 移除即将到来的舰队警告
|
|
||||||
*/
|
|
||||||
const removeIncomingFleetAlert = (alert: IncomingFleetAlert) => {
|
|
||||||
if (!gameStore.player.incomingFleetAlerts) return
|
|
||||||
const index = gameStore.player.incomingFleetAlerts.indexOf(alert)
|
|
||||||
if (index > -1) {
|
|
||||||
gameStore.player.incomingFleetAlerts.splice(index, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据任务ID移除即将到来的舰队警告
|
|
||||||
*/
|
|
||||||
const removeIncomingFleetAlertById = (missionId: string) => {
|
|
||||||
if (!gameStore.player.incomingFleetAlerts) return
|
|
||||||
const index = gameStore.player.incomingFleetAlerts.findIndex(a => a.id === missionId)
|
|
||||||
if (index > -1) {
|
|
||||||
gameStore.player.incomingFleetAlerts.splice(index, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理NPC任务到达
|
|
||||||
*/
|
|
||||||
const processNPCMissionArrival = (npc: NPC, mission: FleetMission) => {
|
|
||||||
if (mission.missionType === MissionType.Recycle) {
|
|
||||||
// NPC回收任务到达
|
|
||||||
const debrisId = mission.debrisFieldId
|
|
||||||
if (!debrisId) {
|
|
||||||
console.warn('[NPC Mission] Recycle mission missing debrisFieldId')
|
|
||||||
mission.status = 'returning'
|
|
||||||
mission.returnTime = Date.now() + (mission.arrivalTime - mission.departureTime)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const debrisField = universeStore.debrisFields[debrisId]
|
|
||||||
const recycleResult = fleetLogic.processRecycleArrival(mission, debrisField)
|
|
||||||
|
|
||||||
if (recycleResult && debrisField) {
|
|
||||||
if (recycleResult.remainingDebris && (recycleResult.remainingDebris.metal > 0 || recycleResult.remainingDebris.crystal > 0)) {
|
|
||||||
// 更新残骸场
|
|
||||||
universeStore.debrisFields[debrisId] = {
|
|
||||||
id: debrisField.id,
|
|
||||||
position: debrisField.position,
|
|
||||||
resources: recycleResult.remainingDebris,
|
|
||||||
createdAt: debrisField.createdAt
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 残骸已被完全回收,从宇宙中删除
|
|
||||||
delete universeStore.debrisFields[debrisId]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 移除即将到来的警告(回收任务已到达)
|
|
||||||
removeIncomingFleetAlertById(mission.id)
|
|
||||||
|
|
||||||
// 设置返回时间
|
|
||||||
mission.returnTime = Date.now() + (mission.arrivalTime - mission.departureTime)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 找到目标星球
|
|
||||||
const targetKey = gameLogic.generatePositionKey(
|
|
||||||
mission.targetPosition.galaxy,
|
|
||||||
mission.targetPosition.system,
|
|
||||||
mission.targetPosition.position
|
|
||||||
)
|
|
||||||
const targetPlanet =
|
|
||||||
gameStore.player.planets.find(
|
|
||||||
p =>
|
|
||||||
p.position.galaxy === mission.targetPosition.galaxy &&
|
|
||||||
p.position.system === mission.targetPosition.system &&
|
|
||||||
p.position.position === mission.targetPosition.position
|
|
||||||
) || universeStore.planets[targetKey]
|
|
||||||
|
|
||||||
if (!targetPlanet) {
|
|
||||||
console.warn('[NPC Mission] Target planet not found')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mission.missionType === MissionType.Spy) {
|
|
||||||
// NPC侦查到达
|
|
||||||
const { spiedNotification, spyReport } = npcBehaviorLogic.processNPCSpyArrival(npc, mission, targetPlanet, gameStore.player)
|
|
||||||
|
|
||||||
// 保存侦查报告到NPC(用于后续攻击决策)
|
|
||||||
if (!npc.playerSpyReports) {
|
|
||||||
npc.playerSpyReports = {}
|
|
||||||
}
|
|
||||||
npc.playerSpyReports[targetPlanet.id] = spyReport
|
|
||||||
|
|
||||||
// 添加被侦查通知给玩家
|
|
||||||
if (!gameStore.player.spiedNotifications) {
|
|
||||||
gameStore.player.spiedNotifications = []
|
|
||||||
}
|
|
||||||
gameStore.player.spiedNotifications.push(spiedNotification)
|
|
||||||
|
|
||||||
// 移除即将到来的警告(侦查已到达)
|
|
||||||
removeIncomingFleetAlertById(mission.id)
|
|
||||||
} else if (mission.missionType === MissionType.Attack) {
|
|
||||||
// NPC攻击到达 - 使用专门的NPC攻击处理逻辑
|
|
||||||
fleetLogic.processNPCAttackArrival(npc, mission, targetPlanet, gameStore.player, gameStore.player.planets).then(attackResult => {
|
|
||||||
if (attackResult) {
|
|
||||||
// 添加战斗报告给玩家
|
|
||||||
gameStore.player.battleReports.push(attackResult.battleResult)
|
|
||||||
|
|
||||||
// 如果生成月球,添加到玩家星球列表
|
|
||||||
if (attackResult.moon) {
|
|
||||||
gameStore.player.planets.push(attackResult.moon)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果生成残骸场,添加到宇宙残骸场列表
|
|
||||||
if (attackResult.debrisField) {
|
|
||||||
universeStore.debrisFields[attackResult.debrisField.id] = attackResult.debrisField
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 移除即将到来的警告(攻击已到达)
|
|
||||||
removeIncomingFleetAlertById(mission.id)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理NPC任务返回
|
|
||||||
*/
|
|
||||||
const processNPCMissionReturn = (npc: NPC, mission: FleetMission) => {
|
|
||||||
// 找到NPC的起始星球
|
|
||||||
const originPlanet = npc.planets.find(p => p.id === mission.originPlanetId)
|
|
||||||
if (!originPlanet) return
|
|
||||||
|
|
||||||
// 返还舰队
|
|
||||||
shipLogic.addFleet(originPlanet.fleet, mission.fleet)
|
|
||||||
|
|
||||||
// 如果携带掠夺资源,给NPC添加资源
|
|
||||||
if (mission.cargo) {
|
|
||||||
originPlanet.resources.metal += mission.cargo.metal
|
|
||||||
originPlanet.resources.crystal += mission.cargo.crystal
|
|
||||||
originPlanet.resources.deuterium += mission.cargo.deuterium
|
|
||||||
}
|
|
||||||
|
|
||||||
// 从NPC任务列表中移除
|
|
||||||
if (npc.fleetMissions) {
|
|
||||||
const missionIndex = npc.fleetMissions.indexOf(mission)
|
|
||||||
if (missionIndex > -1) {
|
|
||||||
npc.fleetMissions.splice(missionIndex, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NPC成长系统更新
|
|
||||||
let npcUpdateCounter = 0
|
|
||||||
const NPC_UPDATE_INTERVAL = 10
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新NPC成长系统
|
|
||||||
*/
|
|
||||||
const updateNPCGrowth = (deltaSeconds: number) => {
|
|
||||||
// 累积时间
|
|
||||||
npcUpdateCounter += deltaSeconds
|
|
||||||
|
|
||||||
// 只在达到更新间隔时才执行
|
|
||||||
if (npcUpdateCounter < NPC_UPDATE_INTERVAL) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取所有星球
|
|
||||||
const allPlanets = Object.values(universeStore.planets)
|
|
||||||
|
|
||||||
// 如果NPC store为空,从星球数据中初始化NPC
|
|
||||||
if (npcStore.npcs.length === 0) {
|
|
||||||
const npcMap = new Map<string, any>()
|
|
||||||
|
|
||||||
allPlanets.forEach(planet => {
|
|
||||||
// 跳过玩家的星球
|
|
||||||
if (planet.ownerId === gameStore.player.id || !planet.ownerId) return
|
|
||||||
|
|
||||||
// 这是NPC的星球
|
|
||||||
if (!npcMap.has(planet.ownerId)) {
|
|
||||||
npcMap.set(planet.ownerId, {
|
|
||||||
id: planet.ownerId,
|
|
||||||
name: `NPC-${planet.ownerId.substring(0, 8)}`,
|
|
||||||
planets: [],
|
|
||||||
technologies: {},
|
|
||||||
difficulty: 'medium' as const,
|
|
||||||
relations: {},
|
|
||||||
allies: [],
|
|
||||||
enemies: []
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
npcMap.get(planet.ownerId)!.planets.push(planet)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 保存到store
|
|
||||||
npcStore.npcs = Array.from(npcMap.values())
|
|
||||||
|
|
||||||
// 如果有NPC,基于玩家实力初始化NPC
|
|
||||||
if (npcStore.npcs.length > 0) {
|
|
||||||
const gameState: npcGrowthLogic.NPCGrowthGameState = {
|
|
||||||
planets: allPlanets,
|
|
||||||
player: gameStore.player,
|
|
||||||
npcs: npcStore.npcs
|
|
||||||
}
|
|
||||||
|
|
||||||
const playerPower = npcGrowthLogic.calculatePlayerAveragePower(gameState)
|
|
||||||
|
|
||||||
npcStore.npcs.forEach(npc => {
|
|
||||||
npcGrowthLogic.initializeNPCStartingPower(npc, playerPower)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 初始化NPC之间的外交关系(盟友/敌人)
|
|
||||||
npcGrowthLogic.initializeNPCDiplomacy(npcStore.npcs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果没有NPC,直接返回
|
|
||||||
if (npcStore.npcs.length === 0) {
|
|
||||||
npcUpdateCounter = 0
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 构建游戏状态
|
|
||||||
const gameState: npcGrowthLogic.NPCGrowthGameState = {
|
|
||||||
planets: allPlanets,
|
|
||||||
player: gameStore.player,
|
|
||||||
npcs: npcStore.npcs
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用累积的时间更新每个NPC
|
|
||||||
npcStore.npcs.forEach(npc => {
|
|
||||||
npcGrowthLogic.updateNPCGrowth(npc, gameState, npcUpdateCounter)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 重置计数器
|
|
||||||
npcUpdateCounter = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// NPC行为系统更新
|
|
||||||
let npcBehaviorCounter = 0
|
|
||||||
const NPC_BEHAVIOR_INTERVAL = 5
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新NPC行为系统
|
|
||||||
*/
|
|
||||||
const updateNPCBehavior = (deltaSeconds: number) => {
|
|
||||||
// 累积时间
|
|
||||||
npcBehaviorCounter += deltaSeconds
|
|
||||||
|
|
||||||
// 只在达到更新间隔时才执行
|
|
||||||
if (npcBehaviorCounter < NPC_BEHAVIOR_INTERVAL) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果没有NPC,直接返回
|
|
||||||
if (npcStore.npcs.length === 0) {
|
|
||||||
npcBehaviorCounter = 0
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const now = Date.now()
|
|
||||||
const allPlanets = Object.values(universeStore.planets)
|
|
||||||
|
|
||||||
// 更新每个NPC的行为
|
|
||||||
npcStore.npcs.forEach(npc => {
|
|
||||||
npcBehaviorLogic.updateNPCBehavior(npc, gameStore.player, allPlanets, universeStore.debrisFields, now)
|
|
||||||
})
|
|
||||||
|
|
||||||
npcBehaviorCounter = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
processNPCMissionArrival,
|
|
||||||
processNPCMissionReturn,
|
|
||||||
removeIncomingFleetAlert,
|
|
||||||
removeIncomingFleetAlertById,
|
|
||||||
updateNPCGrowth,
|
|
||||||
updateNPCBehavior
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
import type { Ref } from 'vue'
|
|
||||||
import { useGameStore } from '@/stores/gameStore'
|
|
||||||
import type { BuildQueueItem } from '@/types/game'
|
|
||||||
import * as buildingValidation from '@/logic/buildingValidation'
|
|
||||||
import * as resourceLogic from '@/logic/resourceLogic'
|
|
||||||
import * as researchValidation from '@/logic/researchValidation'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 队列处理
|
|
||||||
* 处理建造队列和研究队列的取消操作
|
|
||||||
*/
|
|
||||||
export const useQueueHandler = (
|
|
||||||
t: (key: string) => string,
|
|
||||||
confirmDialogOpen: Ref<boolean>,
|
|
||||||
confirmDialogTitle: Ref<string>,
|
|
||||||
confirmDialogMessage: Ref<string>,
|
|
||||||
confirmDialogAction: Ref<(() => void) | null>
|
|
||||||
) => {
|
|
||||||
const gameStore = useGameStore()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 取消建造
|
|
||||||
*/
|
|
||||||
const handleCancelBuild = (queueId: string) => {
|
|
||||||
confirmDialogTitle.value = t('queue.cancelBuild')
|
|
||||||
confirmDialogMessage.value = t('queue.confirmCancel')
|
|
||||||
confirmDialogAction.value = () => {
|
|
||||||
if (!gameStore.currentPlanet) return false
|
|
||||||
const { item, index } = buildingValidation.findQueueItem(gameStore.currentPlanet.buildQueue, queueId)
|
|
||||||
if (!item) return false
|
|
||||||
if (item.type === 'building') {
|
|
||||||
const refund = buildingValidation.cancelBuildingUpgrade(gameStore.currentPlanet, item)
|
|
||||||
resourceLogic.addResources(gameStore.currentPlanet.resources, refund)
|
|
||||||
}
|
|
||||||
gameStore.currentPlanet.buildQueue.splice(index, 1)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
confirmDialogOpen.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 取消研究
|
|
||||||
*/
|
|
||||||
const handleCancelResearch = (queueId: string) => {
|
|
||||||
confirmDialogTitle.value = t('queue.cancelResearch')
|
|
||||||
confirmDialogMessage.value = t('queue.confirmCancel')
|
|
||||||
confirmDialogAction.value = () => {
|
|
||||||
if (!gameStore.currentPlanet) return false
|
|
||||||
const { item, index } = buildingValidation.findQueueItem(gameStore.player.researchQueue, queueId)
|
|
||||||
if (!item) return false
|
|
||||||
if (item.type === 'technology') {
|
|
||||||
const refund = researchValidation.cancelTechnologyResearch(item)
|
|
||||||
resourceLogic.addResources(gameStore.currentPlanet.resources, refund)
|
|
||||||
}
|
|
||||||
gameStore.player.researchQueue.splice(index, 1)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
confirmDialogOpen.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取队列项名称
|
|
||||||
*/
|
|
||||||
const getItemName = (item: BuildQueueItem): string => {
|
|
||||||
if (item.type === 'building' || item.type === 'demolish') {
|
|
||||||
const buildingName = t(`buildings.${item.itemType}`)
|
|
||||||
return item.type === 'demolish' ? `${t('buildingsView.demolish')} - ${buildingName}` : buildingName
|
|
||||||
} else if (item.type === 'technology') {
|
|
||||||
return t(`technologies.${item.itemType}`)
|
|
||||||
} else if (item.type === 'ship') {
|
|
||||||
return t(`ships.${item.itemType}`)
|
|
||||||
} else if (item.type === 'defense') {
|
|
||||||
return t(`defenses.${item.itemType}`)
|
|
||||||
}
|
|
||||||
return t('common.unknown')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取剩余时间(秒)
|
|
||||||
*/
|
|
||||||
const getRemainingTime = (item: BuildQueueItem): number => {
|
|
||||||
const now = Date.now()
|
|
||||||
return Math.max(0, Math.floor((item.endTime - now) / 1000))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取队列进度(百分比)
|
|
||||||
*/
|
|
||||||
const getQueueProgress = (item: BuildQueueItem): number => {
|
|
||||||
const now = Date.now()
|
|
||||||
const total = item.endTime - item.startTime
|
|
||||||
const elapsed = now - item.startTime
|
|
||||||
return Math.min(100, Math.max(0, (elapsed / total) * 100))
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
handleCancelBuild,
|
|
||||||
handleCancelResearch,
|
|
||||||
getItemName,
|
|
||||||
getRemainingTime,
|
|
||||||
getQueueProgress
|
|
||||||
}
|
|
||||||
}
|
|
||||||
562
src/composables/useTutorial.ts
Normal file
562
src/composables/useTutorial.ts
Normal file
@@ -0,0 +1,562 @@
|
|||||||
|
import { ref, computed, watch } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { useGameStore } from '@/stores/gameStore'
|
||||||
|
import type { TutorialStep, TutorialState } from '@/types/game'
|
||||||
|
import { BuildingType, TechnologyType } from '@/types/game'
|
||||||
|
|
||||||
|
// 桌面端引导步骤定义
|
||||||
|
export const desktopTutorialSteps: TutorialStep[] = [
|
||||||
|
// 第1步:欢迎和基础介绍
|
||||||
|
{
|
||||||
|
id: 'welcome',
|
||||||
|
title: 'tutorial.welcome.title',
|
||||||
|
content: 'tutorial.welcome.content',
|
||||||
|
placement: 'center',
|
||||||
|
route: '/',
|
||||||
|
action: 'none',
|
||||||
|
canSkip: true
|
||||||
|
},
|
||||||
|
// 第2步:资源栏介绍
|
||||||
|
{
|
||||||
|
id: 'resources_intro',
|
||||||
|
title: 'tutorial.resources.title',
|
||||||
|
content: 'tutorial.resources.content',
|
||||||
|
target: '.resource-bar',
|
||||||
|
placement: 'bottom',
|
||||||
|
route: '/',
|
||||||
|
action: 'none',
|
||||||
|
highlightPadding: 8
|
||||||
|
},
|
||||||
|
// 第3步:星球选择器介绍
|
||||||
|
{
|
||||||
|
id: 'planet_info',
|
||||||
|
title: 'tutorial.planet.title',
|
||||||
|
content: 'tutorial.planet.content',
|
||||||
|
target: '[data-tutorial="planet-selector"]',
|
||||||
|
placement: 'bottom',
|
||||||
|
route: '/',
|
||||||
|
action: 'none',
|
||||||
|
highlightPadding: 8
|
||||||
|
},
|
||||||
|
// 第4步:导航菜单介绍
|
||||||
|
{
|
||||||
|
id: 'navigation',
|
||||||
|
title: 'tutorial.navigation.title',
|
||||||
|
content: 'tutorial.navigation.content',
|
||||||
|
target: '[data-tutorial="navigation"]',
|
||||||
|
placement: 'right',
|
||||||
|
route: '/',
|
||||||
|
action: 'none',
|
||||||
|
highlightPadding: 12
|
||||||
|
},
|
||||||
|
// 第5步:前往建筑页面
|
||||||
|
{
|
||||||
|
id: 'goto_buildings',
|
||||||
|
title: 'tutorial.gotoBuildings.title',
|
||||||
|
content: 'tutorial.gotoBuildings.content',
|
||||||
|
target: '[data-nav-path="/buildings"]',
|
||||||
|
placement: 'right',
|
||||||
|
route: '/',
|
||||||
|
action: 'click',
|
||||||
|
highlightPadding: 8
|
||||||
|
},
|
||||||
|
// 第6步:建造太阳能电站(提供能源,是所有资源建筑的前置条件)
|
||||||
|
{
|
||||||
|
id: 'build_solar_plant',
|
||||||
|
title: 'tutorial.buildSolarPlant.title',
|
||||||
|
content: 'tutorial.buildSolarPlant.content',
|
||||||
|
target: `[data-building="${BuildingType.SolarPlant}"]`,
|
||||||
|
placement: 'top',
|
||||||
|
route: '/buildings',
|
||||||
|
action: 'build',
|
||||||
|
actionTarget: BuildingType.SolarPlant,
|
||||||
|
highlightPadding: 12
|
||||||
|
},
|
||||||
|
// 第7步:了解建造队列
|
||||||
|
{
|
||||||
|
id: 'wait_for_build',
|
||||||
|
title: 'tutorial.waitBuild.title',
|
||||||
|
content: 'tutorial.waitBuild.content',
|
||||||
|
target: '[data-tutorial="queue-button"]',
|
||||||
|
placement: 'bottom',
|
||||||
|
route: '/buildings',
|
||||||
|
action: 'none',
|
||||||
|
highlightPadding: 8
|
||||||
|
},
|
||||||
|
// 第8步:建造金属矿(有了太阳能电站后才能建造)
|
||||||
|
{
|
||||||
|
id: 'build_metal_mine',
|
||||||
|
title: 'tutorial.buildMetalMine.title',
|
||||||
|
content: 'tutorial.buildMetalMine.content',
|
||||||
|
target: `[data-building="${BuildingType.MetalMine}"]`,
|
||||||
|
placement: 'top',
|
||||||
|
route: '/buildings',
|
||||||
|
action: 'build',
|
||||||
|
actionTarget: BuildingType.MetalMine,
|
||||||
|
highlightPadding: 12
|
||||||
|
},
|
||||||
|
// 第9步:建造晶体矿
|
||||||
|
{
|
||||||
|
id: 'build_crystal_mine',
|
||||||
|
title: 'tutorial.buildCrystalMine.title',
|
||||||
|
content: 'tutorial.buildCrystalMine.content',
|
||||||
|
target: `[data-building="${BuildingType.CrystalMine}"]`,
|
||||||
|
placement: 'top',
|
||||||
|
route: '/buildings',
|
||||||
|
action: 'build',
|
||||||
|
actionTarget: BuildingType.CrystalMine,
|
||||||
|
highlightPadding: 12
|
||||||
|
},
|
||||||
|
// 第10步:建造重氢合成器
|
||||||
|
{
|
||||||
|
id: 'build_deuterium',
|
||||||
|
title: 'tutorial.buildDeuterium.title',
|
||||||
|
content: 'tutorial.buildDeuterium.content',
|
||||||
|
target: `[data-building="${BuildingType.DeuteriumSynthesizer}"]`,
|
||||||
|
placement: 'top',
|
||||||
|
route: '/buildings',
|
||||||
|
action: 'build',
|
||||||
|
actionTarget: BuildingType.DeuteriumSynthesizer,
|
||||||
|
highlightPadding: 12
|
||||||
|
},
|
||||||
|
// 第11步:升级资源矿到2级(为机器人工厂做准备)
|
||||||
|
{
|
||||||
|
id: 'upgrade_mines_intro',
|
||||||
|
title: 'tutorial.upgradeMines.title',
|
||||||
|
content: 'tutorial.upgradeMines.content',
|
||||||
|
placement: 'center',
|
||||||
|
route: '/buildings',
|
||||||
|
action: 'none'
|
||||||
|
},
|
||||||
|
// 第12步:建造机器人工厂(需要三种资源矿各2级)
|
||||||
|
{
|
||||||
|
id: 'build_robotics',
|
||||||
|
title: 'tutorial.buildRobotics.title',
|
||||||
|
content: 'tutorial.buildRobotics.content',
|
||||||
|
target: `[data-building="${BuildingType.RoboticsFactory}"]`,
|
||||||
|
placement: 'top',
|
||||||
|
route: '/buildings',
|
||||||
|
action: 'build',
|
||||||
|
actionTarget: BuildingType.RoboticsFactory,
|
||||||
|
highlightPadding: 12
|
||||||
|
},
|
||||||
|
// 第13步:继续升级资源矿到3级(为研究实验室做准备)
|
||||||
|
{
|
||||||
|
id: 'upgrade_mines_for_lab',
|
||||||
|
title: 'tutorial.upgradeMinesForLab.title',
|
||||||
|
content: 'tutorial.upgradeMinesForLab.content',
|
||||||
|
placement: 'center',
|
||||||
|
route: '/buildings',
|
||||||
|
action: 'none'
|
||||||
|
},
|
||||||
|
// 第14步:建造研究实验室(需要三种资源矿各3级)
|
||||||
|
{
|
||||||
|
id: 'build_research_lab',
|
||||||
|
title: 'tutorial.buildResearchLab.title',
|
||||||
|
content: 'tutorial.buildResearchLab.content',
|
||||||
|
target: `[data-building="${BuildingType.ResearchLab}"]`,
|
||||||
|
placement: 'top',
|
||||||
|
route: '/buildings',
|
||||||
|
action: 'build',
|
||||||
|
actionTarget: BuildingType.ResearchLab,
|
||||||
|
highlightPadding: 12
|
||||||
|
},
|
||||||
|
// 第15步:前往研究页面
|
||||||
|
{
|
||||||
|
id: 'goto_research',
|
||||||
|
title: 'tutorial.gotoResearch.title',
|
||||||
|
content: 'tutorial.gotoResearch.content',
|
||||||
|
target: '[data-nav-path="/research"]',
|
||||||
|
placement: 'right',
|
||||||
|
route: '/buildings',
|
||||||
|
action: 'click',
|
||||||
|
highlightPadding: 8
|
||||||
|
},
|
||||||
|
// 第16步:研究能量科技
|
||||||
|
{
|
||||||
|
id: 'research_energy',
|
||||||
|
title: 'tutorial.researchEnergy.title',
|
||||||
|
content: 'tutorial.researchEnergy.content',
|
||||||
|
target: `[data-tech="${TechnologyType.EnergyTechnology}"]`,
|
||||||
|
placement: 'top',
|
||||||
|
route: '/research',
|
||||||
|
action: 'research',
|
||||||
|
actionTarget: TechnologyType.EnergyTechnology,
|
||||||
|
highlightPadding: 12
|
||||||
|
},
|
||||||
|
// 第17步:介绍船坞(需要机器人工厂2级)
|
||||||
|
{
|
||||||
|
id: 'shipyard_intro',
|
||||||
|
title: 'tutorial.shipyardIntro.title',
|
||||||
|
content: 'tutorial.shipyardIntro.content',
|
||||||
|
placement: 'center',
|
||||||
|
route: '/research',
|
||||||
|
action: 'none'
|
||||||
|
},
|
||||||
|
// 第18步:返回建筑页面建造船坞
|
||||||
|
{
|
||||||
|
id: 'goto_buildings_for_shipyard',
|
||||||
|
title: 'tutorial.gotoBuildingsForShipyard.title',
|
||||||
|
content: 'tutorial.gotoBuildingsForShipyard.content',
|
||||||
|
target: '[data-nav-path="/buildings"]',
|
||||||
|
placement: 'right',
|
||||||
|
route: '/research',
|
||||||
|
action: 'click',
|
||||||
|
highlightPadding: 8
|
||||||
|
},
|
||||||
|
// 第19步:建造船坞
|
||||||
|
{
|
||||||
|
id: 'build_shipyard',
|
||||||
|
title: 'tutorial.buildShipyard.title',
|
||||||
|
content: 'tutorial.buildShipyard.content',
|
||||||
|
target: `[data-building="${BuildingType.Shipyard}"]`,
|
||||||
|
placement: 'top',
|
||||||
|
route: '/buildings',
|
||||||
|
action: 'build',
|
||||||
|
actionTarget: BuildingType.Shipyard,
|
||||||
|
highlightPadding: 12
|
||||||
|
},
|
||||||
|
// 第20步:舰队和探索介绍
|
||||||
|
{
|
||||||
|
id: 'fleet_intro',
|
||||||
|
title: 'tutorial.fleetIntro.title',
|
||||||
|
content: 'tutorial.fleetIntro.content',
|
||||||
|
placement: 'center',
|
||||||
|
route: '/buildings',
|
||||||
|
action: 'none'
|
||||||
|
},
|
||||||
|
// 第21步:银河系探索介绍
|
||||||
|
{
|
||||||
|
id: 'galaxy_intro',
|
||||||
|
title: 'tutorial.galaxyIntro.title',
|
||||||
|
content: 'tutorial.galaxyIntro.content',
|
||||||
|
target: '[data-nav-path="/galaxy"]',
|
||||||
|
placement: 'right',
|
||||||
|
route: '/buildings',
|
||||||
|
action: 'none',
|
||||||
|
highlightPadding: 8
|
||||||
|
},
|
||||||
|
// 第22步:引导完成
|
||||||
|
{
|
||||||
|
id: 'tutorial_complete',
|
||||||
|
title: 'tutorial.complete.title',
|
||||||
|
content: 'tutorial.complete.content',
|
||||||
|
placement: 'center',
|
||||||
|
route: '/buildings',
|
||||||
|
action: 'none'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// 移动端引导步骤定义
|
||||||
|
export const mobileTutorialSteps: TutorialStep[] = [
|
||||||
|
// 第1步:欢迎(移动端)
|
||||||
|
{
|
||||||
|
id: 'welcome_mobile',
|
||||||
|
title: 'tutorial.mobile.welcome.title',
|
||||||
|
content: 'tutorial.mobile.welcome.content',
|
||||||
|
placement: 'center',
|
||||||
|
route: '/',
|
||||||
|
action: 'none',
|
||||||
|
canSkip: true
|
||||||
|
},
|
||||||
|
// 第2步:顶部资源栏介绍
|
||||||
|
{
|
||||||
|
id: 'resources_intro_mobile',
|
||||||
|
title: 'tutorial.mobile.resources.title',
|
||||||
|
content: 'tutorial.mobile.resources.content',
|
||||||
|
target: '.resource-bar',
|
||||||
|
placement: 'bottom',
|
||||||
|
route: '/',
|
||||||
|
action: 'none',
|
||||||
|
highlightPadding: 8
|
||||||
|
},
|
||||||
|
// 第3步:汉堡菜单介绍 - 引导玩家手动点击打开菜单
|
||||||
|
{
|
||||||
|
id: 'menu_intro_mobile',
|
||||||
|
title: 'tutorial.mobile.menu.title',
|
||||||
|
content: 'tutorial.mobile.menu.content',
|
||||||
|
target: '[data-tutorial="mobile-menu"]',
|
||||||
|
placement: 'bottom',
|
||||||
|
route: '/',
|
||||||
|
action: 'none', // 让玩家手动点击汉堡菜单打开侧边栏
|
||||||
|
highlightPadding: 8
|
||||||
|
},
|
||||||
|
// 第4步:前往建筑页面 - 此时侧边栏已打开,让玩家手动点击
|
||||||
|
{
|
||||||
|
id: 'goto_buildings_mobile',
|
||||||
|
title: 'tutorial.mobile.gotoBuildings.title',
|
||||||
|
content: 'tutorial.mobile.gotoBuildings.content',
|
||||||
|
target: '[data-nav-path="/buildings"]',
|
||||||
|
placement: 'right', // 改为right,因为菜单在左侧展开
|
||||||
|
route: '/',
|
||||||
|
action: 'click', // 使用click,但不会自动触发,只是用来标识这是一个点击操作
|
||||||
|
highlightPadding: 8
|
||||||
|
},
|
||||||
|
// 第5步:建造太阳能电站
|
||||||
|
{
|
||||||
|
id: 'build_solar_plant_mobile',
|
||||||
|
title: 'tutorial.mobile.buildSolarPlant.title',
|
||||||
|
content: 'tutorial.mobile.buildSolarPlant.content',
|
||||||
|
target: `[data-building="${BuildingType.SolarPlant}"]`,
|
||||||
|
placement: 'bottom',
|
||||||
|
route: '/buildings',
|
||||||
|
action: 'build',
|
||||||
|
actionTarget: BuildingType.SolarPlant,
|
||||||
|
highlightPadding: 12
|
||||||
|
},
|
||||||
|
// 第6步:了解建造队列
|
||||||
|
{
|
||||||
|
id: 'wait_for_build_mobile',
|
||||||
|
title: 'tutorial.mobile.waitBuild.title',
|
||||||
|
content: 'tutorial.mobile.waitBuild.content',
|
||||||
|
target: '[data-tutorial="queue-button"]',
|
||||||
|
placement: 'bottom',
|
||||||
|
route: '/buildings',
|
||||||
|
action: 'none',
|
||||||
|
highlightPadding: 8
|
||||||
|
},
|
||||||
|
// 第7步:建造金属矿
|
||||||
|
{
|
||||||
|
id: 'build_metal_mine_mobile',
|
||||||
|
title: 'tutorial.mobile.buildMetalMine.title',
|
||||||
|
content: 'tutorial.mobile.buildMetalMine.content',
|
||||||
|
target: `[data-building="${BuildingType.MetalMine}"]`,
|
||||||
|
placement: 'bottom',
|
||||||
|
route: '/buildings',
|
||||||
|
action: 'build',
|
||||||
|
actionTarget: BuildingType.MetalMine,
|
||||||
|
highlightPadding: 12
|
||||||
|
},
|
||||||
|
// 第8步:完成教程
|
||||||
|
{
|
||||||
|
id: 'tutorial_complete_mobile',
|
||||||
|
title: 'tutorial.mobile.complete.title',
|
||||||
|
content: 'tutorial.mobile.complete.content',
|
||||||
|
placement: 'center',
|
||||||
|
route: '/buildings',
|
||||||
|
action: 'none'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// 检测是否为移动端
|
||||||
|
const isMobileDevice = () => {
|
||||||
|
return window.innerWidth < 768
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据设备类型获取教程步骤
|
||||||
|
export const getTutorialSteps = (): TutorialStep[] => {
|
||||||
|
return isMobileDevice() ? mobileTutorialSteps : desktopTutorialSteps
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出统一的 tutorialSteps(为了兼容性)
|
||||||
|
export const tutorialSteps = getTutorialSteps()
|
||||||
|
|
||||||
|
const tutorialState = ref<TutorialState>({
|
||||||
|
isActive: false,
|
||||||
|
currentStepIndex: 0,
|
||||||
|
completedSteps: [],
|
||||||
|
skipped: false
|
||||||
|
})
|
||||||
|
|
||||||
|
export function useTutorial() {
|
||||||
|
const router = useRouter()
|
||||||
|
const gameStore = useGameStore()
|
||||||
|
|
||||||
|
// 动态获取教程步骤
|
||||||
|
const currentTutorialSteps = computed(() => getTutorialSteps())
|
||||||
|
|
||||||
|
const currentStep = computed(() => {
|
||||||
|
if (!tutorialState.value.isActive || tutorialState.value.currentStepIndex >= currentTutorialSteps.value.length) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return currentTutorialSteps.value[tutorialState.value.currentStepIndex]
|
||||||
|
})
|
||||||
|
|
||||||
|
const progress = computed(() => {
|
||||||
|
return Math.round((tutorialState.value.currentStepIndex / currentTutorialSteps.value.length) * 100)
|
||||||
|
})
|
||||||
|
|
||||||
|
const isLastStep = computed(() => {
|
||||||
|
return tutorialState.value.currentStepIndex === currentTutorialSteps.value.length - 1
|
||||||
|
})
|
||||||
|
|
||||||
|
// 初始化引导
|
||||||
|
const startTutorial = () => {
|
||||||
|
const player = gameStore.player
|
||||||
|
if (!player.tutorialProgress || !player.tutorialProgress.tutorialCompleted) {
|
||||||
|
const now = Date.now()
|
||||||
|
tutorialState.value = {
|
||||||
|
isActive: true,
|
||||||
|
currentStepIndex: 0,
|
||||||
|
completedSteps: player.tutorialProgress?.completedStepIds || [],
|
||||||
|
skipped: false,
|
||||||
|
lastActiveTime: now
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有进度,恢复到上次的步骤
|
||||||
|
if (player.tutorialProgress?.currentStep) {
|
||||||
|
const stepIndex = currentTutorialSteps.value.findIndex((s: TutorialStep) => s.id === player.tutorialProgress?.currentStep)
|
||||||
|
if (stepIndex !== -1) {
|
||||||
|
tutorialState.value.currentStepIndex = stepIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳转到当前步骤的路由
|
||||||
|
if (currentStep.value?.route) {
|
||||||
|
router.push(currentStep.value.route)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下一步
|
||||||
|
const nextStep = () => {
|
||||||
|
if (!currentStep.value) return
|
||||||
|
|
||||||
|
// 标记当前步骤为已完成
|
||||||
|
if (!tutorialState.value.completedSteps.includes(currentStep.value.id)) {
|
||||||
|
tutorialState.value.completedSteps.push(currentStep.value.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存进度到store
|
||||||
|
saveProgress()
|
||||||
|
|
||||||
|
// 移动到下一步
|
||||||
|
if (tutorialState.value.currentStepIndex < currentTutorialSteps.value.length - 1) {
|
||||||
|
tutorialState.value.currentStepIndex++
|
||||||
|
|
||||||
|
// 跳转到新步骤的路由
|
||||||
|
if (currentStep.value?.route) {
|
||||||
|
router.push(currentStep.value.route)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 引导完成
|
||||||
|
completeTutorial()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上一步
|
||||||
|
const previousStep = () => {
|
||||||
|
if (tutorialState.value.currentStepIndex > 0) {
|
||||||
|
tutorialState.value.currentStepIndex--
|
||||||
|
|
||||||
|
// 跳转到新步骤的路由
|
||||||
|
if (currentStep.value?.route) {
|
||||||
|
router.push(currentStep.value.route)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳过引导
|
||||||
|
const skipTutorial = () => {
|
||||||
|
tutorialState.value.isActive = false
|
||||||
|
tutorialState.value.skipped = true
|
||||||
|
|
||||||
|
// 保存跳过状态(跳过也视为已完成,避免刷新后重新弹出)
|
||||||
|
if (!gameStore.player.tutorialProgress) {
|
||||||
|
gameStore.player.tutorialProgress = {
|
||||||
|
tutorialCompleted: true,
|
||||||
|
completedStepIds: tutorialState.value.completedSteps,
|
||||||
|
currentStep: null,
|
||||||
|
skippedAt: Date.now()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
gameStore.player.tutorialProgress.tutorialCompleted = true
|
||||||
|
gameStore.player.tutorialProgress.skippedAt = Date.now()
|
||||||
|
gameStore.player.tutorialProgress.currentStep = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 完成引导
|
||||||
|
const completeTutorial = () => {
|
||||||
|
tutorialState.value.isActive = false
|
||||||
|
|
||||||
|
// 保存完成状态
|
||||||
|
gameStore.player.tutorialProgress = {
|
||||||
|
tutorialCompleted: true,
|
||||||
|
completedStepIds: tutorialState.value.completedSteps,
|
||||||
|
currentStep: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存进度
|
||||||
|
const saveProgress = () => {
|
||||||
|
if (!gameStore.player.tutorialProgress) {
|
||||||
|
gameStore.player.tutorialProgress = {
|
||||||
|
tutorialCompleted: false,
|
||||||
|
completedStepIds: [],
|
||||||
|
currentStep: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gameStore.player.tutorialProgress.completedStepIds = [...tutorialState.value.completedSteps]
|
||||||
|
gameStore.player.tutorialProgress.currentStep = currentStep.value?.id || null
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查步骤完成条件
|
||||||
|
const checkStepCompletion = (stepId: string): boolean => {
|
||||||
|
const step = currentTutorialSteps.value.find((s: TutorialStep) => s.id === stepId)
|
||||||
|
if (!step) return false
|
||||||
|
|
||||||
|
const planet = gameStore.currentPlanet
|
||||||
|
if (!planet) return false
|
||||||
|
|
||||||
|
switch (step.action) {
|
||||||
|
case 'build':
|
||||||
|
if (step.actionTarget) {
|
||||||
|
// 简单检查队列中是否有该建筑
|
||||||
|
const inQueue = planet.buildQueue.some(
|
||||||
|
item => item.itemType === step.actionTarget && (item.type === 'building' || item.type === 'demolish')
|
||||||
|
)
|
||||||
|
return inQueue
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
|
||||||
|
case 'research':
|
||||||
|
if (step.actionTarget) {
|
||||||
|
// 简单检查队列中是否有该科技
|
||||||
|
const inQueue = planet.buildQueue.some(item => item.itemType === step.actionTarget && item.type === 'technology')
|
||||||
|
return inQueue
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
|
||||||
|
case 'click':
|
||||||
|
case 'none':
|
||||||
|
default:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不再自动推进,完全由玩家手动点击"下一步"按钮控制
|
||||||
|
|
||||||
|
// 监听路由变化,自动推进需要导航的教程步骤
|
||||||
|
watch(
|
||||||
|
() => router.currentRoute.value.path,
|
||||||
|
newPath => {
|
||||||
|
if (tutorialState.value.isActive && currentStep.value) {
|
||||||
|
// 如果当前步骤需要导航到特定页面,且已经到达该页面,自动推进
|
||||||
|
if (currentStep.value.action === 'none' && currentStep.value.target && currentStep.value.target.includes('data-nav-path')) {
|
||||||
|
// 提取目标路径
|
||||||
|
const match = currentStep.value.target.match(/data-nav-path="([^"]+)"/)
|
||||||
|
if (match && match[1] === newPath) {
|
||||||
|
setTimeout(() => {
|
||||||
|
nextStep()
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
tutorialState,
|
||||||
|
currentStep,
|
||||||
|
progress,
|
||||||
|
isLastStep,
|
||||||
|
startTutorial,
|
||||||
|
nextStep,
|
||||||
|
previousStep,
|
||||||
|
skipTutorial,
|
||||||
|
completeTutorial,
|
||||||
|
checkStepCompletion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -123,13 +123,28 @@ export const BUILDINGS: Record<BuildingType, BuildingConfig> = {
|
|||||||
baseTime: 30, // 减少建造时间:60→30秒
|
baseTime: 30, // 减少建造时间:60→30秒
|
||||||
costMultiplier: 2,
|
costMultiplier: 2,
|
||||||
spaceUsage: 5,
|
spaceUsage: 5,
|
||||||
fleetStorageBonus: 1000, // 每级增加100舰队仓储
|
fleetStorageBonus: 1000, // 每级增加1000舰队仓储
|
||||||
requirements: { [BuildingType.RoboticsFactory]: 2 },
|
requirements: { [BuildingType.RoboticsFactory]: 2 },
|
||||||
levelRequirements: {
|
levelRequirements: {
|
||||||
8: { [BuildingType.RoboticsFactory]: 5, [BuildingType.ResearchLab]: 5 },
|
8: { [BuildingType.RoboticsFactory]: 5, [BuildingType.ResearchLab]: 5 },
|
||||||
12: { [BuildingType.RoboticsFactory]: 8, [BuildingType.ResearchLab]: 8, [BuildingType.NaniteFactory]: 2 }
|
12: { [BuildingType.RoboticsFactory]: 8, [BuildingType.ResearchLab]: 8, [BuildingType.NaniteFactory]: 2 }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
[BuildingType.Hangar]: {
|
||||||
|
id: BuildingType.Hangar,
|
||||||
|
name: '机库',
|
||||||
|
description: '专门用于扩展舰队存储容量,支持星球专业化发展',
|
||||||
|
baseCost: { metal: 200, crystal: 100, deuterium: 50, darkMatter: 0, energy: 0 },
|
||||||
|
baseTime: 20,
|
||||||
|
costMultiplier: 1.8,
|
||||||
|
spaceUsage: 3,
|
||||||
|
fleetStorageBonus: 1500, // 每级增加1500舰队仓储,比船坞更高
|
||||||
|
requirements: { [BuildingType.RoboticsFactory]: 1 }, // 只需要1级机器人工厂
|
||||||
|
levelRequirements: {
|
||||||
|
10: { [BuildingType.RoboticsFactory]: 3 },
|
||||||
|
20: { [BuildingType.RoboticsFactory]: 5 }
|
||||||
|
}
|
||||||
|
},
|
||||||
[BuildingType.ResearchLab]: {
|
[BuildingType.ResearchLab]: {
|
||||||
id: BuildingType.ResearchLab,
|
id: BuildingType.ResearchLab,
|
||||||
name: '研究实验室',
|
name: '研究实验室',
|
||||||
@@ -251,7 +266,7 @@ export const BUILDINGS: Record<BuildingType, BuildingConfig> = {
|
|||||||
[BuildingType.Terraformer]: {
|
[BuildingType.Terraformer]: {
|
||||||
id: BuildingType.Terraformer,
|
id: BuildingType.Terraformer,
|
||||||
name: '地形改造器',
|
name: '地形改造器',
|
||||||
description: '改造行星地形,每级增加5个可用空间',
|
description: '改造行星地形,每级增加30个可用空间',
|
||||||
baseCost: { metal: 0, crystal: 50000, deuterium: 100000, darkMatter: 0, energy: 0 },
|
baseCost: { metal: 0, crystal: 50000, deuterium: 100000, darkMatter: 0, energy: 0 },
|
||||||
baseTime: 60,
|
baseTime: 60,
|
||||||
costMultiplier: 2,
|
costMultiplier: 2,
|
||||||
@@ -433,7 +448,7 @@ export const TECHNOLOGIES: Record<TechnologyType, TechnologyConfig> = {
|
|||||||
baseCost: { metal: 0, crystal: 400, deuterium: 600, darkMatter: 0, energy: 0 },
|
baseCost: { metal: 0, crystal: 400, deuterium: 600, darkMatter: 0, energy: 0 },
|
||||||
baseTime: 60,
|
baseTime: 60,
|
||||||
costMultiplier: 2,
|
costMultiplier: 2,
|
||||||
fleetStorageBonus: 500, // 每级全局增加50舰队仓储
|
fleetStorageBonus: 500, // 每级全局增加500舰队仓储
|
||||||
maxLevel: 10, // 最多10级(最多11个研究队列)
|
maxLevel: 10, // 最多10级(最多11个研究队列)
|
||||||
requirements: { [BuildingType.ResearchLab]: 1 },
|
requirements: { [BuildingType.ResearchLab]: 1 },
|
||||||
levelRequirements: {
|
levelRequirements: {
|
||||||
@@ -588,7 +603,7 @@ export const TECHNOLOGIES: Record<TechnologyType, TechnologyConfig> = {
|
|||||||
[TechnologyType.TerraformingTechnology]: {
|
[TechnologyType.TerraformingTechnology]: {
|
||||||
id: TechnologyType.TerraformingTechnology,
|
id: TechnologyType.TerraformingTechnology,
|
||||||
name: '地形改造技术',
|
name: '地形改造技术',
|
||||||
description: '研究行星地形改造技术,每级为所有行星增加5个可用空间',
|
description: '研究行星地形改造技术,每级为所有行星增加30个可用空间',
|
||||||
baseCost: { metal: 0, crystal: 20000, deuterium: 40000, darkMatter: 0, energy: 0 },
|
baseCost: { metal: 0, crystal: 20000, deuterium: 40000, darkMatter: 0, energy: 0 },
|
||||||
baseTime: 90,
|
baseTime: 90,
|
||||||
costMultiplier: 2,
|
costMultiplier: 2,
|
||||||
@@ -674,13 +689,13 @@ export const SHIPS: Record<ShipType, ShipConfig> = {
|
|||||||
[ShipType.Battleship]: {
|
[ShipType.Battleship]: {
|
||||||
id: ShipType.Battleship,
|
id: ShipType.Battleship,
|
||||||
name: '战列舰',
|
name: '战列舰',
|
||||||
description: '重型战舰',
|
description: '重型战舰,主力作战单位',
|
||||||
cost: { metal: 45000, crystal: 15000, deuterium: 0, darkMatter: 0, energy: 0 },
|
cost: { metal: 45000, crystal: 15000, deuterium: 0, darkMatter: 0, energy: 0 },
|
||||||
buildTime: 90,
|
buildTime: 90,
|
||||||
cargoCapacity: 1500,
|
cargoCapacity: 1500,
|
||||||
attack: 1000,
|
attack: 1200,
|
||||||
shield: 200,
|
shield: 300,
|
||||||
armor: 6000,
|
armor: 10000,
|
||||||
speed: 10000,
|
speed: 10000,
|
||||||
fuelConsumption: 500,
|
fuelConsumption: 500,
|
||||||
storageUsage: 25,
|
storageUsage: 25,
|
||||||
@@ -728,13 +743,13 @@ export const SHIPS: Record<ShipType, ShipConfig> = {
|
|||||||
[ShipType.Destroyer]: {
|
[ShipType.Destroyer]: {
|
||||||
id: ShipType.Destroyer,
|
id: ShipType.Destroyer,
|
||||||
name: '驱逐舰',
|
name: '驱逐舰',
|
||||||
description: '擅长摧毁大型舰船的猎杀者',
|
description: '专业反大型舰船战舰,高火力低防护',
|
||||||
cost: { metal: 60000, crystal: 50000, deuterium: 15000, darkMatter: 0, energy: 0 },
|
cost: { metal: 60000, crystal: 50000, deuterium: 15000, darkMatter: 0, energy: 0 },
|
||||||
buildTime: 120,
|
buildTime: 120,
|
||||||
cargoCapacity: 2000,
|
cargoCapacity: 2000,
|
||||||
attack: 2000,
|
attack: 2500,
|
||||||
shield: 500,
|
shield: 250,
|
||||||
armor: 11000,
|
armor: 8000,
|
||||||
speed: 5000,
|
speed: 5000,
|
||||||
fuelConsumption: 1000,
|
fuelConsumption: 1000,
|
||||||
storageUsage: 40,
|
storageUsage: 40,
|
||||||
@@ -867,7 +882,7 @@ export const SHIPS: Record<ShipType, ShipConfig> = {
|
|||||||
fuelConsumption: 1,
|
fuelConsumption: 1,
|
||||||
storageUsage: 100,
|
storageUsage: 100,
|
||||||
requirements: {
|
requirements: {
|
||||||
[BuildingType.PlanetDestroyerFactory]: 10,
|
[BuildingType.PlanetDestroyerFactory]: 3,
|
||||||
[TechnologyType.PlanetDestructionTech]: 7,
|
[TechnologyType.PlanetDestructionTech]: 7,
|
||||||
[TechnologyType.HyperspaceDrive]: 7
|
[TechnologyType.HyperspaceDrive]: 7
|
||||||
}
|
}
|
||||||
@@ -1085,15 +1100,15 @@ export const MOON_CONFIG = {
|
|||||||
baseChance: 1, // 基础1%概率
|
baseChance: 1, // 基础1%概率
|
||||||
maxChance: 20, // 最大20%概率
|
maxChance: 20, // 最大20%概率
|
||||||
chancePerDebris: 100000, // 每10万资源增加1%概率
|
chancePerDebris: 100000, // 每10万资源增加1%概率
|
||||||
baseSize: 60, // 月球基础空间
|
baseSize: 100, // 月球基础空间
|
||||||
lunarBaseSpaceBonus: 5 // 每级月球基地增加的空间
|
lunarBaseSpaceBonus: 30 // 每级月球基地增加的空间
|
||||||
}
|
}
|
||||||
|
|
||||||
// 行星配置
|
// 行星配置
|
||||||
export const PLANET_CONFIG = {
|
export const PLANET_CONFIG = {
|
||||||
baseSize: 200, // 行星基础空间
|
baseSize: 300, // 行星基础空间
|
||||||
terraformerSpaceBonus: 5, // 每级地形改造器增加的空间
|
terraformerSpaceBonus: 30, // 每级地形改造器增加的空间
|
||||||
terraformingTechSpaceBonus: 3 // 每级地形改造技术增加的空间
|
terraformingTechSpaceBonus: 30 // 每级地形改造技术增加的空间
|
||||||
}
|
}
|
||||||
|
|
||||||
// 舰队仓储配置
|
// 舰队仓储配置
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export default {
|
|||||||
close: 'Schließen',
|
close: 'Schließen',
|
||||||
back: 'Zurück',
|
back: 'Zurück',
|
||||||
next: 'Weiter',
|
next: 'Weiter',
|
||||||
|
gotIt: '',
|
||||||
previous: 'Vorherige',
|
previous: 'Vorherige',
|
||||||
submit: 'Absenden',
|
submit: 'Absenden',
|
||||||
reset: 'Zurücksetzen',
|
reset: 'Zurücksetzen',
|
||||||
@@ -33,13 +34,19 @@ export default {
|
|||||||
viewRequirements: 'Anforderungen anzeigen',
|
viewRequirements: 'Anforderungen anzeigen',
|
||||||
requirementsNotMet: 'Anforderungen nicht erfüllt',
|
requirementsNotMet: 'Anforderungen nicht erfüllt',
|
||||||
current: 'Aktuell',
|
current: 'Aktuell',
|
||||||
level: 'Stufe'
|
level: 'Stufe',
|
||||||
|
gmModeActivated: 'GM-Modus aktiviert! Überprüfen Sie das Navigationsmenü.'
|
||||||
},
|
},
|
||||||
errors: {
|
errors: {
|
||||||
requirementsNotMet: 'Anforderungen nicht erfüllt',
|
requirementsNotMet: 'Anforderungen nicht erfüllt',
|
||||||
insufficientResources: 'Unzureichende Ressourcen',
|
insufficientResources: 'Unzureichende Ressourcen',
|
||||||
insufficientFleetStorage: 'Unzureichender Flottenspeicher',
|
insufficientFleetStorage: 'Unzureichender Flottenspeicher',
|
||||||
shieldDomeLimit: 'Schildkuppel-Limit erreicht',
|
shieldDomeLimit: 'Schildkuppel-Limit erreicht',
|
||||||
|
missileSiloLimit: 'Raketensilokapazität überschritten',
|
||||||
|
insufficientMissiles: 'Unzureichende Interkontinentalraketen',
|
||||||
|
invalidMissileCount: 'Ungültige Raketenanzahl',
|
||||||
|
targetOutOfRange: 'Ziel außer Reichweite',
|
||||||
|
cannotAttackOwnPlanet: 'Eigenen Planeten kann nicht angegriffen werden',
|
||||||
fleetMissionsFull: 'Flottenmissionsplätze voll',
|
fleetMissionsFull: 'Flottenmissionsplätze voll',
|
||||||
insufficientFleet: 'Unzureichende Flotte',
|
insufficientFleet: 'Unzureichende Flotte',
|
||||||
insufficientFuel: 'Unzureichender Treibstoff',
|
insufficientFuel: 'Unzureichender Treibstoff',
|
||||||
@@ -119,6 +126,7 @@ export default {
|
|||||||
roboticsFactory: 'Roboterfabrik',
|
roboticsFactory: 'Roboterfabrik',
|
||||||
naniteFactory: 'Nanitenfabrik',
|
naniteFactory: 'Nanitenfabrik',
|
||||||
shipyard: 'Raumschiffwerft',
|
shipyard: 'Raumschiffwerft',
|
||||||
|
hangar: 'Hangar',
|
||||||
researchLab: 'Forschungslabor',
|
researchLab: 'Forschungslabor',
|
||||||
metalStorage: 'Metallspeicher',
|
metalStorage: 'Metallspeicher',
|
||||||
crystalStorage: 'Kristallspeicher',
|
crystalStorage: 'Kristallspeicher',
|
||||||
@@ -159,6 +167,7 @@ export default {
|
|||||||
roboticsFactory: 'Beschleunigt Baugeschwindigkeit',
|
roboticsFactory: 'Beschleunigt Baugeschwindigkeit',
|
||||||
naniteFactory: 'Erhöht Bauauftragskapazität, +1 pro Stufe (max 10 Stufen)',
|
naniteFactory: 'Erhöht Bauauftragskapazität, +1 pro Stufe (max 10 Stufen)',
|
||||||
shipyard: 'Baut Schiffe',
|
shipyard: 'Baut Schiffe',
|
||||||
|
hangar: 'Spezialisierte Einrichtung zur Erweiterung der Flottenspeicherkapazität, unterstützt Planetenspezialisierung',
|
||||||
researchLab: 'Erforscht Technologien',
|
researchLab: 'Erforscht Technologien',
|
||||||
metalStorage: 'Erhöht Metallspeicherkapazität',
|
metalStorage: 'Erhöht Metallspeicherkapazität',
|
||||||
crystalStorage: 'Erhöht Kristallspeicherkapazität',
|
crystalStorage: 'Erhöht Kristallspeicherkapazität',
|
||||||
@@ -166,8 +175,8 @@ export default {
|
|||||||
darkMatterCollector: 'Sammelt seltene Dunkle-Materie-Ressourcen',
|
darkMatterCollector: 'Sammelt seltene Dunkle-Materie-Ressourcen',
|
||||||
darkMatterTank: 'Erhöht Dunkle-Materie-Speicherkapazität',
|
darkMatterTank: 'Erhöht Dunkle-Materie-Speicherkapazität',
|
||||||
missileSilo: 'Lagert und startet Raketen, 10 Raketen pro Stufe',
|
missileSilo: 'Lagert und startet Raketen, 10 Raketen pro Stufe',
|
||||||
terraformer: 'Terraformt Planetenoberfläche, erhöht verfügbaren Platz um 5 pro Stufe',
|
terraformer: 'Terraformt Planetenoberfläche, erhöht verfügbaren Platz um 30 pro Stufe',
|
||||||
lunarBase: 'Erhöht verfügbaren Platz auf dem Mond, +5 Platz pro Stufe',
|
lunarBase: 'Erhöht verfügbaren Platz auf dem Mond, +30 Platz pro Stufe',
|
||||||
sensorPhalanx: 'Erkennt Flottenaktivitäten in umliegenden Systemen',
|
sensorPhalanx: 'Erkennt Flottenaktivitäten in umliegenden Systemen',
|
||||||
jumpGate: 'Überträgt Flotten sofort zu anderen Monden',
|
jumpGate: 'Überträgt Flotten sofort zu anderen Monden',
|
||||||
planetDestroyerFactory: 'Konstruiert ultimative Waffen zur Zerstörung von Planeten'
|
planetDestroyerFactory: 'Konstruiert ultimative Waffen zur Zerstörung von Planeten'
|
||||||
@@ -193,10 +202,10 @@ export default {
|
|||||||
lightFighter: 'Grundlegende Kampfeinheit',
|
lightFighter: 'Grundlegende Kampfeinheit',
|
||||||
heavyFighter: 'Schwer gepanzerter Jäger',
|
heavyFighter: 'Schwer gepanzerter Jäger',
|
||||||
cruiser: 'Mittleres Kriegsschiff, ausgewogene Offensive und Defensive',
|
cruiser: 'Mittleres Kriegsschiff, ausgewogene Offensive und Defensive',
|
||||||
battleship: 'Mächtiges Kriegsschiff',
|
battleship: 'Schweres Hauptkriegsschiff mit starker Feuerkraft und hoher Verteidigung',
|
||||||
battlecruiser: 'Schnelles mächtiges Kriegsschiff, hervorragend gegen Schlachtschiffe',
|
battlecruiser: 'Schnelles mächtiges Kriegsschiff, hervorragend gegen Schlachtschiffe',
|
||||||
bomber: 'Spezialisiertes Schiff zum Angriff auf Verteidigungsanlagen',
|
bomber: 'Spezialisiertes Schiff zum Angriff auf Verteidigungsanlagen',
|
||||||
destroyer: 'Jäger spezialisiert auf Zerstörung großer Schiffe',
|
destroyer: 'Spezialisiertes Anti-Großschiff mit hoher Feuerkraft aber geringer Verteidigung',
|
||||||
smallCargo: 'Transportiert kleine Mengen Ressourcen',
|
smallCargo: 'Transportiert kleine Mengen Ressourcen',
|
||||||
largeCargo: 'Transportiert große Mengen Ressourcen',
|
largeCargo: 'Transportiert große Mengen Ressourcen',
|
||||||
colonyShip: 'Zur Kolonisierung neuer Planeten',
|
colonyShip: 'Zur Kolonisierung neuer Planeten',
|
||||||
@@ -283,7 +292,7 @@ export default {
|
|||||||
impulseDrive: 'Mittlere Antriebstechnologie',
|
impulseDrive: 'Mittlere Antriebstechnologie',
|
||||||
hyperspaceDrive: 'Fortgeschrittene Antriebstechnologie',
|
hyperspaceDrive: 'Fortgeschrittene Antriebstechnologie',
|
||||||
darkMatterTechnology: 'Forschung zu Eigenschaften und Anwendungen von Dunkler Materie',
|
darkMatterTechnology: 'Forschung zu Eigenschaften und Anwendungen von Dunkler Materie',
|
||||||
terraformingTechnology: 'Forschung zur Planeten-Terraforming-Technologie, erhöht verfügbaren Platz aller Planeten um 3 pro Stufe',
|
terraformingTechnology: 'Forschung zur Planeten-Terraforming-Technologie, erhöht verfügbaren Platz aller Planeten um 30 pro Stufe',
|
||||||
planetDestructionTech: 'Schreckliche Technologie zur Zerstörung ganzer Planeten'
|
planetDestructionTech: 'Schreckliche Technologie zur Zerstörung ganzer Planeten'
|
||||||
},
|
},
|
||||||
officers: {
|
officers: {
|
||||||
@@ -306,16 +315,20 @@ export default {
|
|||||||
darkMatterSpecialist: 'Verbessert Dunkle-Materie-Sammlungseffizienz'
|
darkMatterSpecialist: 'Verbessert Dunkle-Materie-Sammlungseffizienz'
|
||||||
},
|
},
|
||||||
queue: {
|
queue: {
|
||||||
|
title: 'Bauauftrag',
|
||||||
|
empty: 'Keine aktiven Aufgaben',
|
||||||
buildQueue: 'Bauauftrag',
|
buildQueue: 'Bauauftrag',
|
||||||
researchQueue: 'Forschungsauftrag',
|
researchQueue: 'Forschungsauftrag',
|
||||||
building: 'Im Bau',
|
building: 'Im Bau',
|
||||||
researching: 'In Forschung',
|
researching: 'In Forschung',
|
||||||
|
demolishing: 'Wird abgerissen',
|
||||||
remaining: 'Verbleibend',
|
remaining: 'Verbleibend',
|
||||||
cancel: 'Abbrechen',
|
cancel: 'Abbrechen',
|
||||||
cancelBuild: 'Bau abbrechen',
|
cancelBuild: 'Bau abbrechen',
|
||||||
cancelResearch: 'Forschung abbrechen',
|
cancelResearch: 'Forschung abbrechen',
|
||||||
confirmCancel: 'Möchten Sie wirklich abbrechen? 50% der Ressourcen werden zurückerstattet.',
|
confirmCancel: 'Möchten Sie wirklich abbrechen? 50% der Ressourcen werden zurückerstattet.',
|
||||||
level: 'Stufe',
|
level: 'Stufe',
|
||||||
|
gmModeActivated: '',
|
||||||
upgradeToLevel: 'Auf Stufe aufrüsten'
|
upgradeToLevel: 'Auf Stufe aufrüsten'
|
||||||
},
|
},
|
||||||
overview: {
|
overview: {
|
||||||
@@ -336,6 +349,7 @@ export default {
|
|||||||
usedSpace: 'Verwendeter Platz',
|
usedSpace: 'Verwendeter Platz',
|
||||||
spaceUsage: 'Platzbedarf',
|
spaceUsage: 'Platzbedarf',
|
||||||
level: 'Stufe',
|
level: 'Stufe',
|
||||||
|
gmModeActivated: '',
|
||||||
upgradeCost: 'Ausbaukosten',
|
upgradeCost: 'Ausbaukosten',
|
||||||
buildTime: 'Bauzeit',
|
buildTime: 'Bauzeit',
|
||||||
upgrade: 'Ausbauen',
|
upgrade: 'Ausbauen',
|
||||||
@@ -361,6 +375,7 @@ export default {
|
|||||||
},
|
},
|
||||||
shipyard: {
|
shipyard: {
|
||||||
attack: 'Angriff',
|
attack: 'Angriff',
|
||||||
|
missileAttack: 'Raketenangriff',
|
||||||
shield: 'Schild',
|
shield: 'Schild',
|
||||||
armor: 'Panzerung',
|
armor: 'Panzerung',
|
||||||
speed: 'Geschwindigkeit',
|
speed: 'Geschwindigkeit',
|
||||||
@@ -378,6 +393,7 @@ export default {
|
|||||||
title: 'Raumschiffwerft',
|
title: 'Raumschiffwerft',
|
||||||
fleetStorage: 'Flottenspeicher',
|
fleetStorage: 'Flottenspeicher',
|
||||||
attack: 'Angriff',
|
attack: 'Angriff',
|
||||||
|
missileAttack: 'Raketenangriff',
|
||||||
shield: 'Schild',
|
shield: 'Schild',
|
||||||
speed: 'Geschwindigkeit',
|
speed: 'Geschwindigkeit',
|
||||||
cargoCapacity: 'Ladekapazität',
|
cargoCapacity: 'Ladekapazität',
|
||||||
@@ -392,6 +408,7 @@ export default {
|
|||||||
},
|
},
|
||||||
defense: {
|
defense: {
|
||||||
attack: 'Angriff',
|
attack: 'Angriff',
|
||||||
|
missileAttack: 'Raketenangriff',
|
||||||
shield: 'Schild',
|
shield: 'Schild',
|
||||||
armor: 'Panzerung',
|
armor: 'Panzerung',
|
||||||
buildCost: 'Baukosten',
|
buildCost: 'Baukosten',
|
||||||
@@ -405,6 +422,7 @@ export default {
|
|||||||
defenseView: {
|
defenseView: {
|
||||||
title: 'Verteidigung',
|
title: 'Verteidigung',
|
||||||
attack: 'Angriff',
|
attack: 'Angriff',
|
||||||
|
missileAttack: 'Raketenangriff',
|
||||||
shield: 'Schild',
|
shield: 'Schild',
|
||||||
armor: 'Panzerung',
|
armor: 'Panzerung',
|
||||||
buildTime: 'Bauzeit',
|
buildTime: 'Bauzeit',
|
||||||
@@ -414,6 +432,7 @@ export default {
|
|||||||
totalCost: 'Gesamtkosten',
|
totalCost: 'Gesamtkosten',
|
||||||
build: 'Bauen',
|
build: 'Bauen',
|
||||||
shieldDomeBuilt: 'Schildkuppel bereits gebaut',
|
shieldDomeBuilt: 'Schildkuppel bereits gebaut',
|
||||||
|
missileCapacity: 'Raketenkapazität',
|
||||||
inputError: 'Eingabefehler',
|
inputError: 'Eingabefehler',
|
||||||
inputErrorMessage: 'Bitte Baumenge eingeben!',
|
inputErrorMessage: 'Bitte Baumenge eingeben!',
|
||||||
buildFailed: 'Bau fehlgeschlagen',
|
buildFailed: 'Bau fehlgeschlagen',
|
||||||
@@ -427,6 +446,7 @@ export default {
|
|||||||
flightMissions: 'Flugmissionen',
|
flightMissions: 'Flugmissionen',
|
||||||
currentPlanetFleet: 'Flotte auf diesem Planeten',
|
currentPlanetFleet: 'Flotte auf diesem Planeten',
|
||||||
attack: 'Angriff',
|
attack: 'Angriff',
|
||||||
|
missileAttack: 'Raketenangriff',
|
||||||
shield: 'Schild',
|
shield: 'Schild',
|
||||||
armor: 'Panzerung',
|
armor: 'Panzerung',
|
||||||
speed: 'Geschwindigkeit',
|
speed: 'Geschwindigkeit',
|
||||||
@@ -461,6 +481,11 @@ export default {
|
|||||||
arrivalTime: 'Ankunftszeit',
|
arrivalTime: 'Ankunftszeit',
|
||||||
returnTime: 'Rückkehrzeit',
|
returnTime: 'Rückkehrzeit',
|
||||||
recallFleet: 'Flotte zurückrufen',
|
recallFleet: 'Flotte zurückrufen',
|
||||||
|
abortMission: '',
|
||||||
|
abortMissionTitle: '',
|
||||||
|
abortMissionWarning: '',
|
||||||
|
abortMissionSuccess: '',
|
||||||
|
abortMissionSuccessMessage: '',
|
||||||
sendFailed: 'Senden fehlgeschlagen',
|
sendFailed: 'Senden fehlgeschlagen',
|
||||||
sendFailedMessage: 'Bitte überprüfen Sie Flottenanzahl, Treibstoffverfügbarkeit oder Ladekapazitätsgrenzen.',
|
sendFailedMessage: 'Bitte überprüfen Sie Flottenanzahl, Treibstoffverfügbarkeit oder Ladekapazitätsgrenzen.',
|
||||||
recallFailed: 'Zurückrufen fehlgeschlagen',
|
recallFailed: 'Zurückrufen fehlgeschlagen',
|
||||||
@@ -521,27 +546,38 @@ export default {
|
|||||||
selectSystem: 'System auswählen',
|
selectSystem: 'System auswählen',
|
||||||
view: 'Anzeigen',
|
view: 'Anzeigen',
|
||||||
myPlanet: 'Mein Planet',
|
myPlanet: 'Mein Planet',
|
||||||
myPlanets: 'Meine Planeten',
|
myPlanets: 'Meine Systeme ansehen',
|
||||||
npcPlanets: 'NPC-Planeten',
|
npcPlanets: 'NPC-Planeten',
|
||||||
selectPlanetToView: 'Planet zum Anzeigen auswählen',
|
selectPlanetToView: 'Planet auswählen, um sein System anzuzeigen',
|
||||||
totalPositions: 'Insgesamt 10 Planetenpositionen',
|
totalPositions: 'Insgesamt 10 Planetenpositionen',
|
||||||
mine: 'Mein',
|
mine: 'Mein',
|
||||||
hostile: 'Feindlich',
|
hostile: 'Feindlich',
|
||||||
emptySlot: 'Leer - Kolonisierbar',
|
emptySlot: 'Leer - Kolonisierbar',
|
||||||
scout: 'Spähen',
|
scout: 'Spähen',
|
||||||
attack: 'Angriff',
|
attack: 'Angriff',
|
||||||
|
missileAttack: 'Raketenangriff',
|
||||||
colonize: 'Kolonisieren',
|
colonize: 'Kolonisieren',
|
||||||
switch: 'Wechseln',
|
switch: 'Wechseln',
|
||||||
recycle: 'Recyceln',
|
recycle: 'Recyceln',
|
||||||
debrisField: 'Trümmerfeld',
|
debrisField: 'Trümmerfeld',
|
||||||
scoutPlanetTitle: 'Planet ausspionieren',
|
scoutPlanetTitle: 'Planet ausspionieren',
|
||||||
attackPlanetTitle: 'Planet angreifen',
|
attackPlanetTitle: 'Planet angreifen',
|
||||||
|
missileAttackTitle: 'Raketenangriff',
|
||||||
colonizePlanetTitle: 'Planet kolonisieren',
|
colonizePlanetTitle: 'Planet kolonisieren',
|
||||||
recyclePlanetTitle: 'Trümmer recyceln',
|
recyclePlanetTitle: 'Trümmer recyceln',
|
||||||
scoutPlanetMessage:
|
scoutPlanetMessage:
|
||||||
'Möchten Sie wirklich Spionagesonden senden, um Planet [{coordinates}] auszuspionieren?\n\nBitte gehen Sie zur Flottenseite, um Schiffe auszuwählen und zu senden.',
|
'Möchten Sie wirklich Spionagesonden senden, um Planet [{coordinates}] auszuspionieren?\n\nBitte gehen Sie zur Flottenseite, um Schiffe auszuwählen und zu senden.',
|
||||||
attackPlanetMessage:
|
attackPlanetMessage:
|
||||||
'Möchten Sie wirklich Planet [{coordinates}] angreifen?\n\nBitte gehen Sie zur Flottenseite, um Schiffe auszuwählen und zu senden.',
|
'Möchten Sie wirklich Planet [{coordinates}] angreifen?\n\nBitte gehen Sie zur Flottenseite, um Schiffe auszuwählen und zu senden.',
|
||||||
|
missileAttackMessage: 'Interkontinentalraketen starten, um Planet [{coordinates}] anzugreifen',
|
||||||
|
missileCount: 'Raketenanzahl',
|
||||||
|
availableMissiles: 'Verfügbare Raketen',
|
||||||
|
missileRange: 'Raketenreichweite',
|
||||||
|
systems: 'Systeme',
|
||||||
|
distance: 'Entfernung',
|
||||||
|
flightTime: 'Flugzeit',
|
||||||
|
launchMissile: 'Starten',
|
||||||
|
cancel: 'Abbrechen',
|
||||||
colonizePlanetMessage:
|
colonizePlanetMessage:
|
||||||
'Möchten Sie wirklich Position [{coordinates}] kolonisieren?\n\nBitte gehen Sie zur Flottenseite, um ein Kolonieschiff zu senden.',
|
'Möchten Sie wirklich Position [{coordinates}] kolonisieren?\n\nBitte gehen Sie zur Flottenseite, um ein Kolonieschiff zu senden.',
|
||||||
recyclePlanetMessage:
|
recyclePlanetMessage:
|
||||||
@@ -557,11 +593,13 @@ export default {
|
|||||||
battles: 'Kämpfe',
|
battles: 'Kämpfe',
|
||||||
spy: 'Spionage',
|
spy: 'Spionage',
|
||||||
npc: 'NPC',
|
npc: 'NPC',
|
||||||
|
diplomacy: '',
|
||||||
spied: 'Ausspioniert',
|
spied: 'Ausspioniert',
|
||||||
battleReports: 'Kampfberichte',
|
battleReports: 'Kampfberichte',
|
||||||
spyReports: 'Spionageberichte',
|
spyReports: 'Spionageberichte',
|
||||||
noBattleReports: 'Keine Kampfberichte',
|
noBattleReports: 'Keine Kampfberichte',
|
||||||
noSpyReports: 'Keine Spionageberichte',
|
noSpyReports: 'Keine Spionageberichte',
|
||||||
|
noDiplomaticReports: '',
|
||||||
noSpiedNotifications: 'Keine Ausspionierungs-Benachrichtigungen',
|
noSpiedNotifications: 'Keine Ausspionierungs-Benachrichtigungen',
|
||||||
battleReport: 'Kampfbericht',
|
battleReport: 'Kampfbericht',
|
||||||
spyReport: 'Spionagebericht',
|
spyReport: 'Spionagebericht',
|
||||||
@@ -616,7 +654,38 @@ export default {
|
|||||||
hostile: 'Sie sind feindlich und nehmen keine Geschenke an',
|
hostile: 'Sie sind feindlich und nehmen keine Geschenke an',
|
||||||
neutral_distrust: 'Sie vertrauen Ihnen nicht',
|
neutral_distrust: 'Sie vertrauen Ihnen nicht',
|
||||||
polite_decline: 'Sie lehnten höflich ab'
|
polite_decline: 'Sie lehnten höflich ab'
|
||||||
}
|
},
|
||||||
|
// Spied notification dialog
|
||||||
|
spiedNotificationDetails: '',
|
||||||
|
spyDetected: '',
|
||||||
|
detectionResult: '',
|
||||||
|
detectionSuccess: '',
|
||||||
|
spiedNotificationMessage: '',
|
||||||
|
spiedNotificationTip: '',
|
||||||
|
viewInGalaxy: '',
|
||||||
|
// Mission report dialog
|
||||||
|
missionReportDetails: '',
|
||||||
|
missionSuccess: '',
|
||||||
|
missionFailed: '',
|
||||||
|
origin: '',
|
||||||
|
destination: '',
|
||||||
|
missionDetails: '',
|
||||||
|
transportedResources: '',
|
||||||
|
recycledResources: '',
|
||||||
|
remainingDebris: '',
|
||||||
|
newPlanet: '',
|
||||||
|
// NPC activity dialog
|
||||||
|
npcActivityDetails: '',
|
||||||
|
activityType: {
|
||||||
|
recycle: ''
|
||||||
|
},
|
||||||
|
activityLocation: '',
|
||||||
|
position: '',
|
||||||
|
nearPlanet: '',
|
||||||
|
activityDescription: '',
|
||||||
|
npcActivityMessage: '',
|
||||||
|
arrivalTime: '',
|
||||||
|
npcActivityTip: ''
|
||||||
},
|
},
|
||||||
missionReports: {
|
missionReports: {
|
||||||
transportSuccess: 'Transportmission erfolgreich abgeschlossen',
|
transportSuccess: 'Transportmission erfolgreich abgeschlossen',
|
||||||
@@ -699,10 +768,24 @@ export default {
|
|||||||
gamePaused: 'Spiel pausiert',
|
gamePaused: 'Spiel pausiert',
|
||||||
gameResumed: 'Spiel fortgesetzt',
|
gameResumed: 'Spiel fortgesetzt',
|
||||||
playerName: 'Spielername',
|
playerName: 'Spielername',
|
||||||
gameSpeed: 'Spielgeschwindigkeit',
|
gameSpeed: 'Ressourcenproduktionsgeschwindigkeit',
|
||||||
gameSpeedDesc: 'Aktueller Spielgeschwindigkeitsmultiplikator',
|
gameSpeedDesc: 'Aktueller Ressourcenproduktionsgeschwindigkeitsmultiplikator',
|
||||||
|
speedChanged: 'Ressourcenproduktionsgeschwindigkeit auf {speed}x geändert',
|
||||||
|
speedReset: 'Ressourcenproduktionsgeschwindigkeit auf 1x zurückgesetzt',
|
||||||
|
reset: 'Zurücksetzen',
|
||||||
about: 'Über',
|
about: 'Über',
|
||||||
version: 'Version',
|
version: 'Version',
|
||||||
|
latestVersion: 'Neueste Version',
|
||||||
|
checkUpdate: 'Update prüfen',
|
||||||
|
checking: 'Prüfen...',
|
||||||
|
newVersionAvailable: 'Neue Version {version} verfügbar',
|
||||||
|
upToDate: 'Bereits auf dem neuesten Stand',
|
||||||
|
checkUpdateCooldown: 'Bitte versuchen Sie es später erneut (5 Minuten Abklingzeit)',
|
||||||
|
checkUpdateFailed: 'Update-Prüfung fehlgeschlagen, bitte überprüfen Sie Ihre Netzwerkverbindung',
|
||||||
|
viewUpdate: 'Update ansehen',
|
||||||
|
updateAvailable: 'Eine neue Version ist verfügbar. Klicken Sie, um die Versionshinweise anzuzeigen.',
|
||||||
|
download: 'Herunterladen',
|
||||||
|
goToDownload: 'Zum Download',
|
||||||
buildDate: 'Build-Datum',
|
buildDate: 'Build-Datum',
|
||||||
community: 'Community',
|
community: 'Community',
|
||||||
github: 'GitHub-Repository',
|
github: 'GitHub-Repository',
|
||||||
@@ -721,6 +804,8 @@ export default {
|
|||||||
officers: 'Offiziere',
|
officers: 'Offiziere',
|
||||||
modifyResources: 'Ressourcen ändern',
|
modifyResources: 'Ressourcen ändern',
|
||||||
resourcesDesc: 'Planetenressourcen schnell ändern',
|
resourcesDesc: 'Planetenressourcen schnell ändern',
|
||||||
|
maxAllResources: '',
|
||||||
|
maxAllResourcesSuccess: '',
|
||||||
modifyBuildings: 'Gebäude ändern',
|
modifyBuildings: 'Gebäude ändern',
|
||||||
buildingsDesc: 'Gebäudelevel schnell festlegen',
|
buildingsDesc: 'Gebäudelevel schnell festlegen',
|
||||||
modifyResearch: 'Forschung ändern',
|
modifyResearch: 'Forschung ändern',
|
||||||
@@ -741,16 +826,31 @@ export default {
|
|||||||
testSpy: 'Spionage testen',
|
testSpy: 'Spionage testen',
|
||||||
testAttack: 'Angriff testen',
|
testAttack: 'Angriff testen',
|
||||||
testSpyAndAttack: 'Spionage & Angriff testen',
|
testSpyAndAttack: 'Spionage & Angriff testen',
|
||||||
|
testSpyMessage: 'Klicken Sie auf Bestätigen, um die Spionagemission zu beschleunigen',
|
||||||
|
testAttackMessage: 'Klicken Sie auf Bestätigen, um die Angriffsmission zu beschleunigen',
|
||||||
|
testSpyAndAttackMessage: 'Klicken Sie auf Bestätigen, um die Missionen zu beschleunigen',
|
||||||
initializeFleet: 'NPC-Flotte initialisieren',
|
initializeFleet: 'NPC-Flotte initialisieren',
|
||||||
accelerateMissions: 'Alle Missionen beschleunigen (5s)',
|
accelerateMissions: 'Alle Missionen beschleunigen (5s)',
|
||||||
selectNPCFirst: 'Bitte wählen Sie zuerst einen NPC',
|
selectNPCFirst: 'Bitte wählen Sie zuerst einen NPC',
|
||||||
npcNoProbes: 'NPC hat keine Spionagesonden',
|
npcNoProbes: 'NPC hat keine Spionagesonden',
|
||||||
npcNoSpyReport: 'NPC muss zuerst spionieren',
|
npcNoSpyReport: 'NPC muss zuerst spionieren',
|
||||||
npcMissionFailed: 'Mission konnte nicht erstellt werden',
|
npcMissionFailed: 'Mission konnte nicht erstellt werden',
|
||||||
|
npcNoPlanets: 'NPC hat keine Planeten',
|
||||||
|
npcWillSpyIn5s: '{npcName} wird in 5 Sekunden spionieren',
|
||||||
|
npcWillAttackIn5s: '{npcName} wird in 5 Sekunden angreifen',
|
||||||
|
npcWillSpyAndAttack: '{npcName} wird in 5s spionieren und in 10s angreifen',
|
||||||
|
acceleratedMissions: '{count} Missionen auf 5 Sekunden beschleunigt',
|
||||||
|
npcFleetInitialized: '{npcName} Flotte initialisiert',
|
||||||
|
npcFleetDetails:
|
||||||
|
'100 Spionagesonden\n500 Leichte Jäger\n300 Schwere Jäger\n200 Kreuzer\n100 Schlachtschiffe\n50 Bomber\n30 Zerstörer\n20 Schlachtkreuzer',
|
||||||
dangerZone: 'Gefahrenzone',
|
dangerZone: 'Gefahrenzone',
|
||||||
dangerZoneDesc: 'Die folgenden Vorgänge sind irreversibel',
|
dangerZoneDesc: 'Die folgenden Vorgänge sind irreversibel',
|
||||||
resetGame: 'Spiel zurücksetzen',
|
resetGame: 'Spiel zurücksetzen',
|
||||||
resetGameConfirm: 'Möchten Sie das Spiel wirklich zurücksetzen? Alle Daten werden gelöscht!'
|
resetGameConfirm: 'Möchten Sie das Spiel wirklich zurücksetzen? Alle Daten werden gelöscht!',
|
||||||
|
completeAllQueues: '',
|
||||||
|
completeAllQueuesDesc: '',
|
||||||
|
completeQueues: '',
|
||||||
|
completeQueuesSuccess: ''
|
||||||
},
|
},
|
||||||
alerts: {
|
alerts: {
|
||||||
npcSpyIncoming: 'NPC-Spionagesonde nähert sich',
|
npcSpyIncoming: 'NPC-Spionagesonde nähert sich',
|
||||||
@@ -780,6 +880,10 @@ export default {
|
|||||||
recentEvents: 'Aktuelle Ereignisse',
|
recentEvents: 'Aktuelle Ereignisse',
|
||||||
recentEventsDescription: 'Protokoll der jüngsten diplomatischen Aktivitäten',
|
recentEventsDescription: 'Protokoll der jüngsten diplomatischen Aktivitäten',
|
||||||
ago: 'vor',
|
ago: 'vor',
|
||||||
|
notifications: '',
|
||||||
|
markAllRead: '',
|
||||||
|
noReports: '',
|
||||||
|
viewAll: '',
|
||||||
status: {
|
status: {
|
||||||
friendly: 'Freundlich',
|
friendly: 'Freundlich',
|
||||||
neutral: 'Neutral',
|
neutral: 'Neutral',
|
||||||
@@ -795,19 +899,96 @@ export default {
|
|||||||
viewPlanets: 'Planeten ansehen'
|
viewPlanets: 'Planeten ansehen'
|
||||||
},
|
},
|
||||||
lastEvent: 'Letztes Ereignis',
|
lastEvent: 'Letztes Ereignis',
|
||||||
|
reportDetails: '',
|
||||||
|
eventDescription: '',
|
||||||
|
reputationChange: '',
|
||||||
|
before: '',
|
||||||
|
after: '',
|
||||||
|
statusChange: '',
|
||||||
|
viewDiplomacy: '',
|
||||||
events: {
|
events: {
|
||||||
gift: 'Geschenk gesendet',
|
gift: 'Geschenk gesendet',
|
||||||
attack: 'Angriff',
|
attack: 'Angriff',
|
||||||
|
missileAttack: 'Raketenangriff',
|
||||||
allyAttacked: 'Verbündeter angegriffen',
|
allyAttacked: 'Verbündeter angegriffen',
|
||||||
spy: 'Spionage',
|
spy: 'Spionage',
|
||||||
stealDebris: 'Trümmer gestohlen'
|
stealDebris: 'Trümmer gestohlen'
|
||||||
|
},
|
||||||
|
reports: {
|
||||||
|
giftedResources: '{metal}M {crystal}K {deuterium}D geschenkt',
|
||||||
|
receivedGiftFromPlayer: 'Geschenk von Spieler erhalten',
|
||||||
|
giftedToNpc: 'Sie haben {npcName} Ressourcen geschenkt. Ansehen +{reputation}',
|
||||||
|
rejectedPlayerGift: 'Geschenk des Spielers abgelehnt',
|
||||||
|
npcRejectedGift: '{npcName} hat Ihr Geschenk abgelehnt. Ansehen {reputation}',
|
||||||
|
attackedNpc: '{npcName} angegriffen',
|
||||||
|
wasAttackedByPlayer: 'Wurde von Spieler angegriffen',
|
||||||
|
youAttackedNpc: 'Sie haben {npcName} angegriffen',
|
||||||
|
playerAttackedAlly: 'Spieler hat Verbündeten {allyName} angegriffen',
|
||||||
|
allyDispleased: '{allyName} ist unzufrieden, dass Sie ihren Verbündeten {targetName} angegriffen haben',
|
||||||
|
wasSpiedByPlayer: 'Wurde von Spieler ausspioniert (entdeckt: {detected})',
|
||||||
|
spyDetected: 'Ihre Spionage wurde von {npcName} entdeckt',
|
||||||
|
stoleDebrisFromTerritory: 'Trümmer aus {npcName}s Territorium gestohlen',
|
||||||
|
playerStoleDebris: 'Spieler hat Trümmer aus Territorium gestohlen',
|
||||||
|
recycledDebrisNearNpc: 'Sie haben Trümmer in der Nähe von {npcName}s Planeten recycelt. Sie sind unzufrieden.',
|
||||||
|
giftedResourcesToPlayer: 'Ressourcen an Spieler geschenkt',
|
||||||
|
receivedGiftFromNpc: 'Geschenk von {npcName} erhalten',
|
||||||
|
acceptedGiftFromNpc: 'Sie haben ein Geschenk von {npcName} angenommen: {metal}M {crystal}K {deuterium}D',
|
||||||
|
playerRejectedGift: 'Spieler hat Geschenk abgelehnt',
|
||||||
|
rejectedGiftFromNpc: 'Sie haben ein Geschenk von {npcName} abgelehnt. Ansehen {reputation}',
|
||||||
|
destroyedNpcPlanet: '{npcName}s {planetName} zerstört',
|
||||||
|
playerDestroyedPlanet: 'Spieler hat {planetName} zerstört',
|
||||||
|
youDestroyedNpcPlanet: 'Sie haben {npcName}s {planetName} zerstört. Ansehen {reputation}',
|
||||||
|
playerDestroyedAllyPlanet: 'Spieler hat Verbündeten {allyName}s {planetName} zerstört',
|
||||||
|
allyOutraged: '{allyName} ist empört, dass Sie den Planeten {planetName} ihres Verbündeten {targetName} zerstört haben',
|
||||||
|
npcEliminated: 'NPC {npcName} wurde vollständig eliminiert',
|
||||||
|
npcEliminatedMessage: 'Sie haben alle Planeten von {npcName} zerstört! Diese Fraktion wurde vollständig ausgelöscht.'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pagination: {
|
pagination: {
|
||||||
previous: 'Vorherige',
|
previous: 'Vorherige',
|
||||||
next: 'Nächste',
|
next: 'Nächste',
|
||||||
|
gotIt: '',
|
||||||
first: 'Erste',
|
first: 'Erste',
|
||||||
last: 'Letzte',
|
last: 'Letzte',
|
||||||
page: 'Seite {page}'
|
page: 'Seite {page}'
|
||||||
|
},
|
||||||
|
notFound: {
|
||||||
|
title: 'Seite nicht gefunden',
|
||||||
|
description: 'Entschuldigung, die gesuchte Seite existiert nicht',
|
||||||
|
goHome: 'Zur Startseite'
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
days: 'Tage',
|
||||||
|
hours: 'Stunden',
|
||||||
|
minutes: 'Minuten',
|
||||||
|
seconds: 'Sekunden'
|
||||||
|
},
|
||||||
|
tutorial: {
|
||||||
|
welcome: {
|
||||||
|
title: 'Willkommen bei OGame',
|
||||||
|
content: 'Willkommen, Kommandant! Beginnen wir mit den Grundlagen und bauen Sie Ihr Weltraum-Imperium auf.'
|
||||||
|
},
|
||||||
|
buildSolarPlant: {
|
||||||
|
title: 'Solarkraftwerk bauen',
|
||||||
|
content:
|
||||||
|
'Bauen Sie zuerst ein Solarkraftwerk! Es liefert Energie für Ihren Planeten. Ohne Energie können andere Ressourcengebäude nicht funktionieren. Dies ist der wichtigste erste Schritt.'
|
||||||
|
},
|
||||||
|
waitBuild: {
|
||||||
|
title: 'Bauauftrag',
|
||||||
|
content:
|
||||||
|
'Ihr Gebäude befindet sich jetzt in der Bauauftragsliste. Klicken Sie auf das Warteschlangensymbol oben rechts, um alle laufenden Bau- und Forschungsaufträge anzuzeigen. Gebäude brauchen Zeit zum Fertigstellen, aber Sie können während des Wartens weitermachen.'
|
||||||
|
},
|
||||||
|
mobile: {
|
||||||
|
welcome: {
|
||||||
|
title: 'Willkommen bei OGame (Mobil)',
|
||||||
|
content:
|
||||||
|
'Willkommen, Kommandant! Dies ist ein optimiertes Tutorial für Touchscreens. Wir werden schnell die Kernfunktionen durchgehen, damit Sie mit dem Aufbau Ihres Imperiums beginnen können.'
|
||||||
|
},
|
||||||
|
waitBuild: {
|
||||||
|
title: 'Bauauftrag',
|
||||||
|
content:
|
||||||
|
'Klicken Sie auf das Warteschlangensymbol oben rechts, um den Baufortschritt anzuzeigen. Sie können weiter andere Seiten durchsuchen - der Bau läuft im Hintergrund.'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,13 +33,19 @@ export default {
|
|||||||
viewRequirements: 'View Requirements',
|
viewRequirements: 'View Requirements',
|
||||||
requirementsNotMet: 'Requirements Not Met',
|
requirementsNotMet: 'Requirements Not Met',
|
||||||
current: 'Current',
|
current: 'Current',
|
||||||
level: 'Level'
|
level: 'Level',
|
||||||
|
gmModeActivated: 'GM Mode Activated! Check the navigation menu.'
|
||||||
},
|
},
|
||||||
errors: {
|
errors: {
|
||||||
requirementsNotMet: 'Requirements not met',
|
requirementsNotMet: 'Requirements not met',
|
||||||
insufficientResources: 'Insufficient resources',
|
insufficientResources: 'Insufficient resources',
|
||||||
insufficientFleetStorage: 'Insufficient fleet storage',
|
insufficientFleetStorage: 'Insufficient fleet storage',
|
||||||
shieldDomeLimit: 'Shield dome limit reached',
|
shieldDomeLimit: 'Shield dome limit reached',
|
||||||
|
missileSiloLimit: 'Missile silo capacity exceeded',
|
||||||
|
insufficientMissiles: 'Insufficient interplanetary missiles',
|
||||||
|
invalidMissileCount: 'Invalid missile count',
|
||||||
|
targetOutOfRange: 'Target out of range',
|
||||||
|
cannotAttackOwnPlanet: 'Cannot attack your own planet',
|
||||||
fleetMissionsFull: 'Fleet mission slots full',
|
fleetMissionsFull: 'Fleet mission slots full',
|
||||||
insufficientFleet: 'Insufficient fleet',
|
insufficientFleet: 'Insufficient fleet',
|
||||||
insufficientFuel: 'Insufficient fuel',
|
insufficientFuel: 'Insufficient fuel',
|
||||||
@@ -119,6 +125,7 @@ export default {
|
|||||||
roboticsFactory: 'Robotics Factory',
|
roboticsFactory: 'Robotics Factory',
|
||||||
naniteFactory: 'Nanite Factory',
|
naniteFactory: 'Nanite Factory',
|
||||||
shipyard: 'Shipyard',
|
shipyard: 'Shipyard',
|
||||||
|
hangar: 'Hangar',
|
||||||
researchLab: 'Research Lab',
|
researchLab: 'Research Lab',
|
||||||
metalStorage: 'Metal Storage',
|
metalStorage: 'Metal Storage',
|
||||||
crystalStorage: 'Crystal Storage',
|
crystalStorage: 'Crystal Storage',
|
||||||
@@ -157,6 +164,7 @@ export default {
|
|||||||
roboticsFactory: 'Accelerates construction speed',
|
roboticsFactory: 'Accelerates construction speed',
|
||||||
naniteFactory: 'Increases build queue capacity, +1 per level (max 10 levels)',
|
naniteFactory: 'Increases build queue capacity, +1 per level (max 10 levels)',
|
||||||
shipyard: 'Constructs ships',
|
shipyard: 'Constructs ships',
|
||||||
|
hangar: 'Specialized facility for expanding fleet storage capacity, supports planetary specialization',
|
||||||
researchLab: 'Researches technologies',
|
researchLab: 'Researches technologies',
|
||||||
metalStorage: 'Increases metal storage capacity',
|
metalStorage: 'Increases metal storage capacity',
|
||||||
crystalStorage: 'Increases crystal storage capacity',
|
crystalStorage: 'Increases crystal storage capacity',
|
||||||
@@ -164,8 +172,8 @@ export default {
|
|||||||
darkMatterCollector: 'Collects rare dark matter resources',
|
darkMatterCollector: 'Collects rare dark matter resources',
|
||||||
darkMatterTank: 'Increases dark matter storage capacity',
|
darkMatterTank: 'Increases dark matter storage capacity',
|
||||||
missileSilo: 'Stores and launches missiles, 10 missiles per level',
|
missileSilo: 'Stores and launches missiles, 10 missiles per level',
|
||||||
terraformer: 'Terraforms planet surface, adds 5 available space per level',
|
terraformer: 'Terraforms planet surface, adds 30 available space per level',
|
||||||
lunarBase: 'Increases available space on the moon, +5 space per level',
|
lunarBase: 'Increases available space on the moon, +30 space per level',
|
||||||
sensorPhalanx: 'Detects fleet activities in surrounding systems',
|
sensorPhalanx: 'Detects fleet activities in surrounding systems',
|
||||||
jumpGate: 'Instantly transfers fleets to other moons',
|
jumpGate: 'Instantly transfers fleets to other moons',
|
||||||
planetDestroyerFactory: 'Constructs ultimate weapons capable of destroying planets'
|
planetDestroyerFactory: 'Constructs ultimate weapons capable of destroying planets'
|
||||||
@@ -191,10 +199,10 @@ export default {
|
|||||||
lightFighter: 'Basic combat unit',
|
lightFighter: 'Basic combat unit',
|
||||||
heavyFighter: 'Heavily armored fighter',
|
heavyFighter: 'Heavily armored fighter',
|
||||||
cruiser: 'Medium warship, balanced offense and defense',
|
cruiser: 'Medium warship, balanced offense and defense',
|
||||||
battleship: 'Powerful warship',
|
battleship: 'Main heavy warship with powerful firepower and strong defense',
|
||||||
battlecruiser: 'Fast powerful warship, excels at attacking battleships',
|
battlecruiser: 'Fast powerful warship, excels at attacking battleships',
|
||||||
bomber: 'Specialized ship for attacking defense structures',
|
bomber: 'Specialized ship for attacking defense structures',
|
||||||
destroyer: 'Hunter specialized in destroying large ships',
|
destroyer: 'Specialized anti-capital ship with high firepower but low defense',
|
||||||
smallCargo: 'Transports small amounts of resources',
|
smallCargo: 'Transports small amounts of resources',
|
||||||
largeCargo: 'Transports large amounts of resources',
|
largeCargo: 'Transports large amounts of resources',
|
||||||
colonyShip: 'Used to colonize new planets',
|
colonyShip: 'Used to colonize new planets',
|
||||||
@@ -283,7 +291,7 @@ export default {
|
|||||||
impulseDrive: 'Intermediate propulsion technology',
|
impulseDrive: 'Intermediate propulsion technology',
|
||||||
hyperspaceDrive: 'Advanced propulsion technology',
|
hyperspaceDrive: 'Advanced propulsion technology',
|
||||||
darkMatterTechnology: 'Research into dark matter properties and applications',
|
darkMatterTechnology: 'Research into dark matter properties and applications',
|
||||||
terraformingTechnology: 'Research planet terraforming technology, adds 3 available space to all planets per level',
|
terraformingTechnology: 'Research planet terraforming technology, adds 30 available space to all planets per level',
|
||||||
planetDestructionTech: 'Terrifying technology for destroying entire planets'
|
planetDestructionTech: 'Terrifying technology for destroying entire planets'
|
||||||
},
|
},
|
||||||
officers: {
|
officers: {
|
||||||
@@ -306,6 +314,8 @@ export default {
|
|||||||
darkMatterSpecialist: 'Improves dark matter collection efficiency'
|
darkMatterSpecialist: 'Improves dark matter collection efficiency'
|
||||||
},
|
},
|
||||||
queue: {
|
queue: {
|
||||||
|
title: 'Build Queue',
|
||||||
|
empty: 'No active tasks',
|
||||||
buildQueueBonus: 'Build Queue',
|
buildQueueBonus: 'Build Queue',
|
||||||
spaceBonus: 'Space Bonus',
|
spaceBonus: 'Space Bonus',
|
||||||
buildSpeedBonus: 'Build Speed Bonus',
|
buildSpeedBonus: 'Build Speed Bonus',
|
||||||
@@ -313,6 +323,7 @@ export default {
|
|||||||
researchQueueBonus: 'Research Queue',
|
researchQueueBonus: 'Research Queue',
|
||||||
building: 'Building',
|
building: 'Building',
|
||||||
researching: 'Researching',
|
researching: 'Researching',
|
||||||
|
demolishing: 'Demolishing',
|
||||||
remaining: 'Remaining',
|
remaining: 'Remaining',
|
||||||
cancel: 'Cancel',
|
cancel: 'Cancel',
|
||||||
cancelBuild: 'Cancel Build',
|
cancelBuild: 'Cancel Build',
|
||||||
@@ -364,6 +375,7 @@ export default {
|
|||||||
},
|
},
|
||||||
shipyard: {
|
shipyard: {
|
||||||
attack: 'Attack',
|
attack: 'Attack',
|
||||||
|
missileAttack: 'Missile Attack',
|
||||||
shield: 'Shield',
|
shield: 'Shield',
|
||||||
armor: 'Armor',
|
armor: 'Armor',
|
||||||
speed: 'Speed',
|
speed: 'Speed',
|
||||||
@@ -381,6 +393,7 @@ export default {
|
|||||||
title: 'Shipyard',
|
title: 'Shipyard',
|
||||||
fleetStorage: 'Fleet Storage',
|
fleetStorage: 'Fleet Storage',
|
||||||
attack: 'Attack',
|
attack: 'Attack',
|
||||||
|
missileAttack: 'Missile Attack',
|
||||||
shield: 'Shield',
|
shield: 'Shield',
|
||||||
speed: 'Speed',
|
speed: 'Speed',
|
||||||
cargoCapacity: 'Cargo Capacity',
|
cargoCapacity: 'Cargo Capacity',
|
||||||
@@ -395,6 +408,7 @@ export default {
|
|||||||
},
|
},
|
||||||
defense: {
|
defense: {
|
||||||
attack: 'Attack',
|
attack: 'Attack',
|
||||||
|
missileAttack: 'Missile Attack',
|
||||||
shield: 'Shield',
|
shield: 'Shield',
|
||||||
armor: 'Armor',
|
armor: 'Armor',
|
||||||
buildCost: 'Build Cost',
|
buildCost: 'Build Cost',
|
||||||
@@ -408,6 +422,7 @@ export default {
|
|||||||
defenseView: {
|
defenseView: {
|
||||||
title: 'Defense',
|
title: 'Defense',
|
||||||
attack: 'Attack',
|
attack: 'Attack',
|
||||||
|
missileAttack: 'Missile Attack',
|
||||||
shield: 'Shield',
|
shield: 'Shield',
|
||||||
armor: 'Armor',
|
armor: 'Armor',
|
||||||
buildTime: 'Build Time',
|
buildTime: 'Build Time',
|
||||||
@@ -417,6 +432,7 @@ export default {
|
|||||||
totalCost: 'Total Cost',
|
totalCost: 'Total Cost',
|
||||||
build: 'Build',
|
build: 'Build',
|
||||||
shieldDomeBuilt: 'Shield dome already built',
|
shieldDomeBuilt: 'Shield dome already built',
|
||||||
|
missileCapacity: 'Missile Capacity',
|
||||||
inputError: 'Input Error',
|
inputError: 'Input Error',
|
||||||
inputErrorMessage: 'Please enter build quantity!',
|
inputErrorMessage: 'Please enter build quantity!',
|
||||||
buildFailed: 'Build Failed',
|
buildFailed: 'Build Failed',
|
||||||
@@ -429,6 +445,7 @@ export default {
|
|||||||
flightMissions: 'Flight Missions',
|
flightMissions: 'Flight Missions',
|
||||||
currentPlanetFleet: 'Current Planet Fleet',
|
currentPlanetFleet: 'Current Planet Fleet',
|
||||||
attack: 'Attack',
|
attack: 'Attack',
|
||||||
|
missileAttack: 'Missile Attack',
|
||||||
shield: 'Shield',
|
shield: 'Shield',
|
||||||
armor: 'Armor',
|
armor: 'Armor',
|
||||||
speed: 'Speed',
|
speed: 'Speed',
|
||||||
@@ -463,6 +480,12 @@ export default {
|
|||||||
arrivalTime: 'Arrival Time',
|
arrivalTime: 'Arrival Time',
|
||||||
returnTime: 'Return Time',
|
returnTime: 'Return Time',
|
||||||
recallFleet: 'Recall Fleet',
|
recallFleet: 'Recall Fleet',
|
||||||
|
abortMission: 'Abort Mission',
|
||||||
|
abortMissionTitle: 'Confirm Abort Mission',
|
||||||
|
abortMissionWarning:
|
||||||
|
'WARNING: Aborting this mission will permanently lose {ships} ships and {resources} resources!\n\nThis action is irreversible and the fleet and resources will not return.',
|
||||||
|
abortMissionSuccess: 'Mission Aborted',
|
||||||
|
abortMissionSuccessMessage: 'Mission has been aborted, fleet and resources are lost.',
|
||||||
sendFailed: 'Send Failed',
|
sendFailed: 'Send Failed',
|
||||||
sendFailedMessage: 'Please check fleet count, fuel availability, or cargo capacity limits.',
|
sendFailedMessage: 'Please check fleet count, fuel availability, or cargo capacity limits.',
|
||||||
recallFailed: 'Recall Failed',
|
recallFailed: 'Recall Failed',
|
||||||
@@ -525,26 +548,37 @@ export default {
|
|||||||
selectSystem: 'Select System',
|
selectSystem: 'Select System',
|
||||||
view: 'View',
|
view: 'View',
|
||||||
myPlanet: 'My Planet',
|
myPlanet: 'My Planet',
|
||||||
myPlanets: 'My Planets',
|
myPlanets: 'View My Systems',
|
||||||
npcPlanets: 'NPC Planets',
|
npcPlanets: 'NPC Planets',
|
||||||
selectPlanetToView: 'Select planet to view',
|
selectPlanetToView: 'Select planet to view its system',
|
||||||
totalPositions: '10 planet positions total',
|
totalPositions: '10 planet positions total',
|
||||||
mine: 'Mine',
|
mine: 'Mine',
|
||||||
hostile: 'Hostile',
|
hostile: 'Hostile',
|
||||||
emptySlot: 'Empty - Colonizable',
|
emptySlot: 'Empty - Colonizable',
|
||||||
scout: 'Scout',
|
scout: 'Scout',
|
||||||
attack: 'Attack',
|
attack: 'Attack',
|
||||||
|
missileAttack: 'Missile Attack',
|
||||||
colonize: 'Colonize',
|
colonize: 'Colonize',
|
||||||
switch: 'Switch',
|
switch: 'Switch',
|
||||||
recycle: 'Recycle',
|
recycle: 'Recycle',
|
||||||
debrisField: 'Debris Field',
|
debrisField: 'Debris Field',
|
||||||
scoutPlanetTitle: 'Scout Planet',
|
scoutPlanetTitle: 'Scout Planet',
|
||||||
attackPlanetTitle: 'Attack Planet',
|
attackPlanetTitle: 'Attack Planet',
|
||||||
|
missileAttackTitle: 'Missile Attack',
|
||||||
colonizePlanetTitle: 'Colonize Planet',
|
colonizePlanetTitle: 'Colonize Planet',
|
||||||
recyclePlanetTitle: 'Recycle Debris',
|
recyclePlanetTitle: 'Recycle Debris',
|
||||||
scoutPlanetMessage:
|
scoutPlanetMessage:
|
||||||
'Are you sure you want to send espionage probes to scout planet [{coordinates}]?\n\nPlease go to the fleet page to select ships and send.',
|
'Are you sure you want to send espionage probes to scout planet [{coordinates}]?\n\nPlease go to the fleet page to select ships and send.',
|
||||||
attackPlanetMessage: 'Are you sure you want to attack planet [{coordinates}]?\n\nPlease go to the fleet page to select ships and send.',
|
attackPlanetMessage: 'Are you sure you want to attack planet [{coordinates}]?\n\nPlease go to the fleet page to select ships and send.',
|
||||||
|
missileAttackMessage: 'Launch interplanetary missiles to attack planet [{coordinates}]',
|
||||||
|
missileCount: 'Missile Count',
|
||||||
|
availableMissiles: 'Available Missiles',
|
||||||
|
missileRange: 'Missile Range',
|
||||||
|
systems: 'systems',
|
||||||
|
distance: 'Distance',
|
||||||
|
flightTime: 'Flight Time',
|
||||||
|
launchMissile: 'Launch',
|
||||||
|
cancel: 'Cancel',
|
||||||
colonizePlanetMessage:
|
colonizePlanetMessage:
|
||||||
'Are you sure you want to colonize position [{coordinates}]?\n\nPlease go to the fleet page to send a colony ship.',
|
'Are you sure you want to colonize position [{coordinates}]?\n\nPlease go to the fleet page to send a colony ship.',
|
||||||
recyclePlanetMessage:
|
recyclePlanetMessage:
|
||||||
@@ -560,10 +594,12 @@ export default {
|
|||||||
battles: 'Battles',
|
battles: 'Battles',
|
||||||
spy: 'Spy',
|
spy: 'Spy',
|
||||||
npc: 'NPC',
|
npc: 'NPC',
|
||||||
|
diplomacy: 'Diplomacy',
|
||||||
battleReports: 'Battle Reports',
|
battleReports: 'Battle Reports',
|
||||||
spyReports: 'Spy Reports',
|
spyReports: 'Spy Reports',
|
||||||
noBattleReports: 'No battle reports',
|
noBattleReports: 'No battle reports',
|
||||||
noSpyReports: 'No spy reports',
|
noSpyReports: 'No spy reports',
|
||||||
|
noDiplomaticReports: 'No diplomatic reports',
|
||||||
battleReport: 'Battle Report',
|
battleReport: 'Battle Report',
|
||||||
spyReport: 'Spy Report',
|
spyReport: 'Spy Report',
|
||||||
victory: 'Victory',
|
victory: 'Victory',
|
||||||
@@ -611,7 +647,38 @@ export default {
|
|||||||
hostile: 'They are hostile towards you and do not accept gifts',
|
hostile: 'They are hostile towards you and do not accept gifts',
|
||||||
neutral_distrust: 'They lack trust in you',
|
neutral_distrust: 'They lack trust in you',
|
||||||
polite_decline: 'They politely declined'
|
polite_decline: 'They politely declined'
|
||||||
}
|
},
|
||||||
|
// Spied notification dialog
|
||||||
|
spiedNotificationDetails: 'Spied Notification Details',
|
||||||
|
spyDetected: 'Spy Detected',
|
||||||
|
detectionResult: 'Detection Result',
|
||||||
|
detectionSuccess: 'Your spy probe was detected!',
|
||||||
|
spiedNotificationMessage: '{npc} attempted to spy on your planet {planet}',
|
||||||
|
spiedNotificationTip: 'Consider increasing your defense or counter-attacking if this NPC is hostile',
|
||||||
|
viewInGalaxy: 'View in Galaxy',
|
||||||
|
// Mission report dialog
|
||||||
|
missionReportDetails: 'Mission Report Details',
|
||||||
|
missionSuccess: 'Success',
|
||||||
|
missionFailed: 'Failed',
|
||||||
|
origin: 'Origin',
|
||||||
|
destination: 'Destination',
|
||||||
|
missionDetails: 'Mission Details',
|
||||||
|
transportedResources: 'Transported Resources',
|
||||||
|
recycledResources: 'Recycled Resources',
|
||||||
|
remainingDebris: 'Remaining Debris',
|
||||||
|
newPlanet: 'New Planet',
|
||||||
|
// NPC activity dialog
|
||||||
|
npcActivityDetails: 'NPC Activity Details',
|
||||||
|
activityType: {
|
||||||
|
recycle: 'Recycling Debris'
|
||||||
|
},
|
||||||
|
activityLocation: 'Activity Location',
|
||||||
|
position: 'Position',
|
||||||
|
nearPlanet: 'Near Planet',
|
||||||
|
activityDescription: 'Activity Description',
|
||||||
|
npcActivityMessage: '{npc} is {activity} at {position}',
|
||||||
|
arrivalTime: 'Arrival Time',
|
||||||
|
npcActivityTip: 'NPCs may collect debris from battles. You can try to reach the location first if you want to compete for resources'
|
||||||
},
|
},
|
||||||
missionReports: {
|
missionReports: {
|
||||||
transportSuccess: 'Transport mission completed successfully',
|
transportSuccess: 'Transport mission completed successfully',
|
||||||
@@ -697,10 +764,24 @@ export default {
|
|||||||
gamePaused: 'Game paused',
|
gamePaused: 'Game paused',
|
||||||
gameResumed: 'Game resumed',
|
gameResumed: 'Game resumed',
|
||||||
playerName: 'Player Name',
|
playerName: 'Player Name',
|
||||||
gameSpeed: 'Game Speed',
|
gameSpeed: 'Resource Production Speed',
|
||||||
gameSpeedDesc: 'Current game speed multiplier',
|
gameSpeedDesc: 'Current resource production speed multiplier',
|
||||||
|
speedChanged: 'Resource production speed changed to {speed}x',
|
||||||
|
speedReset: 'Resource production speed reset to 1x',
|
||||||
|
reset: 'Reset',
|
||||||
about: 'About',
|
about: 'About',
|
||||||
version: 'Version',
|
version: 'Version',
|
||||||
|
latestVersion: 'Latest Version',
|
||||||
|
checkUpdate: 'Check Update',
|
||||||
|
checking: 'Checking...',
|
||||||
|
newVersionAvailable: 'New version {version} available',
|
||||||
|
upToDate: 'Already up to date',
|
||||||
|
checkUpdateCooldown: 'Please try again later (5 minute cooldown)',
|
||||||
|
checkUpdateFailed: 'Failed to check for updates, please check your network connection',
|
||||||
|
viewUpdate: 'View Update',
|
||||||
|
updateAvailable: 'A new version is available. Click to view release notes.',
|
||||||
|
download: 'Download',
|
||||||
|
goToDownload: 'Go to Download',
|
||||||
buildDate: 'Build Date',
|
buildDate: 'Build Date',
|
||||||
community: 'Community',
|
community: 'Community',
|
||||||
github: 'GitHub Repository',
|
github: 'GitHub Repository',
|
||||||
@@ -719,6 +800,8 @@ export default {
|
|||||||
officers: 'Officers',
|
officers: 'Officers',
|
||||||
modifyResources: 'Modify Resources',
|
modifyResources: 'Modify Resources',
|
||||||
resourcesDesc: 'Quickly modify planet resources',
|
resourcesDesc: 'Quickly modify planet resources',
|
||||||
|
maxAllResources: 'Max All',
|
||||||
|
maxAllResourcesSuccess: 'All resources maxed out',
|
||||||
modifyBuildings: 'Modify Buildings',
|
modifyBuildings: 'Modify Buildings',
|
||||||
buildingsDesc: 'Quickly set building levels',
|
buildingsDesc: 'Quickly set building levels',
|
||||||
modifyResearch: 'Modify Research',
|
modifyResearch: 'Modify Research',
|
||||||
@@ -739,16 +822,32 @@ export default {
|
|||||||
testSpy: 'Test Spy',
|
testSpy: 'Test Spy',
|
||||||
testAttack: 'Test Attack',
|
testAttack: 'Test Attack',
|
||||||
testSpyAndAttack: 'Test Spy & Attack',
|
testSpyAndAttack: 'Test Spy & Attack',
|
||||||
|
testSpyMessage: 'Click confirm to accelerate the spy mission',
|
||||||
|
testAttackMessage: 'Click confirm to accelerate the attack mission',
|
||||||
|
testSpyAndAttackMessage: 'Click confirm to accelerate the missions',
|
||||||
initializeFleet: 'Initialize NPC Fleet',
|
initializeFleet: 'Initialize NPC Fleet',
|
||||||
accelerateMissions: 'Accelerate All Missions (5s)',
|
accelerateMissions: 'Accelerate All Missions (5s)',
|
||||||
selectNPCFirst: 'Please select an NPC first',
|
selectNPCFirst: 'Please select an NPC first',
|
||||||
npcNoProbes: 'NPC has no spy probes',
|
npcNoProbes: 'NPC has no spy probes',
|
||||||
npcNoSpyReport: 'NPC needs to spy first',
|
npcNoSpyReport: 'NPC needs to spy first',
|
||||||
npcMissionFailed: 'Failed to create mission',
|
npcMissionFailed: 'Failed to create mission',
|
||||||
|
npcNoPlanets: 'NPC has no planets',
|
||||||
|
npcWillSpyIn5s: '{npcName} will spy in 5 seconds',
|
||||||
|
npcWillAttackIn5s: '{npcName} will attack in 5 seconds',
|
||||||
|
npcWillSpyAndAttack: '{npcName} will spy in 5s and attack in 10s',
|
||||||
|
acceleratedMissions: 'Accelerated {count} missions to 5 seconds',
|
||||||
|
npcFleetInitialized: '{npcName} fleet initialized',
|
||||||
|
npcFleetDetails:
|
||||||
|
'100 Spy Probes\n500 Light Fighters\n300 Heavy Fighters\n200 Cruisers\n100 Battleships\n50 Bombers\n30 Destroyers\n20 Battlecruisers',
|
||||||
dangerZone: 'Danger Zone',
|
dangerZone: 'Danger Zone',
|
||||||
dangerZoneDesc: 'The following operations are irreversible',
|
dangerZoneDesc: 'The following operations are irreversible',
|
||||||
resetGame: 'Reset Game',
|
resetGame: 'Reset Game',
|
||||||
resetGameConfirm: 'Are you sure you want to reset the game? This will delete all data!'
|
resetGameConfirm: 'Are you sure you want to reset the game? This will delete all data!',
|
||||||
|
completeAllQueues: 'Complete All Queues',
|
||||||
|
completeAllQueuesDesc: 'Instantly complete all building, research, ship, defense queues and fleet missions',
|
||||||
|
completeQueues: 'Complete Queues',
|
||||||
|
completeQueuesSuccess:
|
||||||
|
'Completed {buildingCount} building queues, {researchCount} research queues, {missionCount} fleet missions, {missileCount} missile attacks'
|
||||||
},
|
},
|
||||||
alerts: {
|
alerts: {
|
||||||
npcSpyIncoming: 'NPC Spy Probe Incoming',
|
npcSpyIncoming: 'NPC Spy Probe Incoming',
|
||||||
@@ -778,6 +877,10 @@ export default {
|
|||||||
recentEvents: 'Recent Events',
|
recentEvents: 'Recent Events',
|
||||||
recentEventsDescription: 'Recent diplomatic activity log',
|
recentEventsDescription: 'Recent diplomatic activity log',
|
||||||
ago: 'ago',
|
ago: 'ago',
|
||||||
|
notifications: 'Diplomatic Notifications',
|
||||||
|
markAllRead: 'Mark All Read',
|
||||||
|
noReports: 'No diplomatic events',
|
||||||
|
viewAll: 'View All',
|
||||||
status: {
|
status: {
|
||||||
friendly: 'Friendly',
|
friendly: 'Friendly',
|
||||||
neutral: 'Neutral',
|
neutral: 'Neutral',
|
||||||
@@ -793,12 +896,49 @@ export default {
|
|||||||
viewPlanets: 'View Planets'
|
viewPlanets: 'View Planets'
|
||||||
},
|
},
|
||||||
lastEvent: 'Last Event',
|
lastEvent: 'Last Event',
|
||||||
|
reportDetails: 'Diplomatic Report Details',
|
||||||
|
eventDescription: 'Event Description',
|
||||||
|
reputationChange: 'Reputation Change',
|
||||||
|
before: 'Before',
|
||||||
|
after: 'After',
|
||||||
|
statusChange: 'Status Change',
|
||||||
|
viewDiplomacy: 'View Diplomacy Page',
|
||||||
events: {
|
events: {
|
||||||
gift: 'Sent Gift',
|
gift: 'Sent Gift',
|
||||||
attack: 'Attack',
|
attack: 'Attack',
|
||||||
|
missileAttack: 'Missile Attack',
|
||||||
allyAttacked: 'Ally Attacked',
|
allyAttacked: 'Ally Attacked',
|
||||||
spy: 'Espionage',
|
spy: 'Espionage',
|
||||||
stealDebris: 'Debris Stolen'
|
stealDebris: 'Debris Stolen'
|
||||||
|
},
|
||||||
|
reports: {
|
||||||
|
giftedResources: 'Gifted {metal}M {crystal}C {deuterium}D',
|
||||||
|
receivedGiftFromPlayer: 'Received gift from player',
|
||||||
|
giftedToNpc: 'You gifted resources to {npcName}. Reputation +{reputation}',
|
||||||
|
rejectedPlayerGift: "Rejected player's gift",
|
||||||
|
npcRejectedGift: '{npcName} rejected your gift. Reputation {reputation}',
|
||||||
|
attackedNpc: 'Attacked {npcName}',
|
||||||
|
wasAttackedByPlayer: 'Was attacked by player',
|
||||||
|
youAttackedNpc: 'You attacked {npcName}',
|
||||||
|
playerAttackedAlly: 'Player attacked ally {allyName}',
|
||||||
|
allyDispleased: '{allyName} is displeased that you attacked their ally {targetName}',
|
||||||
|
wasSpiedByPlayer: 'Was spied by player (detected: {detected})',
|
||||||
|
spyDetected: 'Your espionage was detected by {npcName}',
|
||||||
|
stoleDebrisFromTerritory: "Stole debris from {npcName}'s territory",
|
||||||
|
playerStoleDebris: 'Player stole debris from territory',
|
||||||
|
recycledDebrisNearNpc: "You recycled debris near {npcName}'s planet. They are displeased.",
|
||||||
|
giftedResourcesToPlayer: 'Gifted resources to player',
|
||||||
|
receivedGiftFromNpc: 'Received gift from {npcName}',
|
||||||
|
acceptedGiftFromNpc: 'You accepted a gift from {npcName}: {metal}M {crystal}C {deuterium}D',
|
||||||
|
playerRejectedGift: 'Player rejected gift',
|
||||||
|
rejectedGiftFromNpc: 'You rejected a gift from {npcName}. Reputation {reputation}',
|
||||||
|
destroyedNpcPlanet: "Destroyed {npcName}'s {planetName}",
|
||||||
|
playerDestroyedPlanet: 'Player destroyed {planetName}',
|
||||||
|
youDestroyedNpcPlanet: "You destroyed {npcName}'s {planetName}. Reputation {reputation}",
|
||||||
|
playerDestroyedAllyPlanet: "Player destroyed ally {allyName}'s {planetName}",
|
||||||
|
allyOutraged: "{allyName} is outraged that you destroyed their ally {targetName}'s {planetName}",
|
||||||
|
npcEliminated: 'NPC {npcName} has been completely eliminated',
|
||||||
|
npcEliminatedMessage: "You destroyed all of {npcName}'s planets! This faction has been completely wiped out."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pagination: {
|
pagination: {
|
||||||
@@ -807,5 +947,167 @@ export default {
|
|||||||
first: 'First',
|
first: 'First',
|
||||||
last: 'Last',
|
last: 'Last',
|
||||||
page: 'Page {page}'
|
page: 'Page {page}'
|
||||||
|
},
|
||||||
|
notFound: {
|
||||||
|
title: 'Page Not Found',
|
||||||
|
description: 'Sorry, the page you are looking for does not exist',
|
||||||
|
goHome: 'Go Home'
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
days: 'days',
|
||||||
|
hours: 'hours',
|
||||||
|
minutes: 'minutes',
|
||||||
|
seconds: 'seconds'
|
||||||
|
},
|
||||||
|
tutorial: {
|
||||||
|
progress: 'Progress',
|
||||||
|
previous: 'Previous',
|
||||||
|
next: 'Next',
|
||||||
|
gotIt: 'Got It',
|
||||||
|
completeButton: 'Complete',
|
||||||
|
skip: 'Skip Tutorial',
|
||||||
|
welcome: {
|
||||||
|
title: 'Welcome to OGame',
|
||||||
|
content:
|
||||||
|
'Welcome, Commander! This tutorial will guide you through the basics of building your empire. Click "Next" to begin your journey.'
|
||||||
|
},
|
||||||
|
resources: {
|
||||||
|
title: 'Resource Overview',
|
||||||
|
content:
|
||||||
|
'These are your resources: Metal, Crystal, and Deuterium. They are essential for building structures and researching technologies. Energy is also important to power your infrastructure.'
|
||||||
|
},
|
||||||
|
planet: {
|
||||||
|
title: 'Your Planet',
|
||||||
|
content: 'This is your home planet. You can view its name, coordinates, and switch between planets here as you expand your empire.'
|
||||||
|
},
|
||||||
|
navigation: {
|
||||||
|
title: 'Navigation Menu',
|
||||||
|
content:
|
||||||
|
'Use this menu to navigate between different sections: Buildings, Research, Fleet, Galaxy, and more. Each section offers unique gameplay features.'
|
||||||
|
},
|
||||||
|
gotoBuildings: {
|
||||||
|
title: 'Go to Buildings',
|
||||||
|
content: 'Let\'s start by building some structures. Click on the "Buildings" menu item to view available structures.'
|
||||||
|
},
|
||||||
|
buildSolarPlant: {
|
||||||
|
title: 'Build Solar Plant',
|
||||||
|
content:
|
||||||
|
'First, build a Solar Plant! It generates energy for your planet. Without energy, other resource buildings cannot function. This is the most important first step.'
|
||||||
|
},
|
||||||
|
waitBuild: {
|
||||||
|
title: 'Build Queue',
|
||||||
|
content:
|
||||||
|
'Your building is now in the construction queue. Click the queue icon in the top-right corner to view all ongoing construction and research tasks. Buildings take time to complete, but you can continue working while waiting.'
|
||||||
|
},
|
||||||
|
buildMetalMine: {
|
||||||
|
title: 'Build Metal Mine',
|
||||||
|
content:
|
||||||
|
"Now that you have energy, you can build the Metal Mine. It's your primary source of metal, which is used in almost every structure and ship."
|
||||||
|
},
|
||||||
|
buildCrystalMine: {
|
||||||
|
title: 'Build Crystal Mine',
|
||||||
|
content: 'Crystal is rarer but essential for advanced technologies. Build a Crystal Mine to start collecting this valuable resource.'
|
||||||
|
},
|
||||||
|
buildDeuterium: {
|
||||||
|
title: 'Build Deuterium Synthesizer',
|
||||||
|
content:
|
||||||
|
'Deuterium is essential for ship fuel and advanced research. Build a Deuterium Synthesizer to start producing this critical resource.'
|
||||||
|
},
|
||||||
|
upgradeMines: {
|
||||||
|
title: 'Upgrade Resource Mines',
|
||||||
|
content:
|
||||||
|
'Next, you need to upgrade all three resource mines (Metal, Crystal, Deuterium) to level 2 to meet the requirements for building a Robotics Factory. Upgrade them when you have enough resources.'
|
||||||
|
},
|
||||||
|
buildRobotics: {
|
||||||
|
title: 'Build Robotics Factory',
|
||||||
|
content:
|
||||||
|
'The Robotics Factory significantly speeds up construction. It requires Metal Mine, Crystal Mine, and Deuterium Synthesizer at level 2 each. Build it to improve construction efficiency!'
|
||||||
|
},
|
||||||
|
upgradeMinesForLab: {
|
||||||
|
title: 'Continue Upgrading Mines',
|
||||||
|
content:
|
||||||
|
'Now you need to upgrade all three resource mines to level 3 to meet the requirements for the Research Lab. Keep developing your resource production.'
|
||||||
|
},
|
||||||
|
buildResearchLab: {
|
||||||
|
title: 'Build Research Lab',
|
||||||
|
content:
|
||||||
|
'The Research Lab is the foundation of technological advancement. It requires all three resource mines at level 3. Build it to unlock technology research!'
|
||||||
|
},
|
||||||
|
gotoResearch: {
|
||||||
|
title: 'Go to Research',
|
||||||
|
content: 'Now that you have a Research Lab, click on the "Research" menu to view available technologies.'
|
||||||
|
},
|
||||||
|
researchEnergy: {
|
||||||
|
title: 'Research Energy Technology',
|
||||||
|
content:
|
||||||
|
"Energy Technology improves your energy production and unlocks advanced structures. It's one of the most fundamental and important technologies."
|
||||||
|
},
|
||||||
|
shipyardIntro: {
|
||||||
|
title: 'Fleet and Shipyard',
|
||||||
|
content:
|
||||||
|
'Ships allow you to explore the galaxy, transport resources, and defend your empire. To build ships, you need a Shipyard (requires Robotics Factory level 2).'
|
||||||
|
},
|
||||||
|
gotoBuildingsForShipyard: {
|
||||||
|
title: 'Return to Buildings',
|
||||||
|
content: 'Go back to the Buildings page to construct your Shipyard.'
|
||||||
|
},
|
||||||
|
buildShipyard: {
|
||||||
|
title: 'Build Shipyard',
|
||||||
|
content: 'The Shipyard allows you to construct ships and defense systems. This is crucial for fleet operations.'
|
||||||
|
},
|
||||||
|
fleetIntro: {
|
||||||
|
title: 'Fleet Operations',
|
||||||
|
content:
|
||||||
|
'Once you have ships, you can send them on missions: transport resources, colonize planets, attack enemies, or explore debris fields.'
|
||||||
|
},
|
||||||
|
galaxyIntro: {
|
||||||
|
title: 'Explore the Galaxy',
|
||||||
|
content:
|
||||||
|
'The Galaxy view shows other planets, debris fields, and opportunities for expansion. Use it to scout targets and plan your strategy.'
|
||||||
|
},
|
||||||
|
complete: {
|
||||||
|
title: 'Tutorial Complete!',
|
||||||
|
content:
|
||||||
|
'Congratulations, Commander! You now know the basics. Continue building your empire, research technologies, and explore the galaxy. Remember: develop energy first, then resources, then factories and research! Good luck!'
|
||||||
|
},
|
||||||
|
// Mobile tutorial
|
||||||
|
mobile: {
|
||||||
|
welcome: {
|
||||||
|
title: 'Welcome to OGame (Mobile)',
|
||||||
|
content:
|
||||||
|
"Welcome, Commander! This is a streamlined tutorial designed for touchscreens. We'll quickly cover the core features to get you started building your empire."
|
||||||
|
},
|
||||||
|
resources: {
|
||||||
|
title: 'Top Resource Bar',
|
||||||
|
content: 'At the top, you see your resources: Metal, Crystal, and Deuterium. Tap to view detailed production info.'
|
||||||
|
},
|
||||||
|
menu: {
|
||||||
|
title: 'Open Navigation Menu',
|
||||||
|
content:
|
||||||
|
'Tap this menu icon to open the navigation bar. You can access Buildings, Research, Fleet, and all other features from here.'
|
||||||
|
},
|
||||||
|
gotoBuildings: {
|
||||||
|
title: 'Go to Buildings Page',
|
||||||
|
content: 'The menu is now open! Now tap "Buildings" to start constructing your infrastructure.'
|
||||||
|
},
|
||||||
|
buildSolarPlant: {
|
||||||
|
title: 'Build Solar Plant',
|
||||||
|
content: 'First, build a Solar Plant! Scroll down to find it and tap the card to build. Energy is the foundation of everything.'
|
||||||
|
},
|
||||||
|
waitBuild: {
|
||||||
|
title: 'Build Queue',
|
||||||
|
content:
|
||||||
|
'Click the queue icon in the top-right corner to view build progress. You can continue browsing other pages - construction happens in the background.'
|
||||||
|
},
|
||||||
|
buildMetalMine: {
|
||||||
|
title: 'Build Metal Mine',
|
||||||
|
content: 'Now that you have energy, build a Metal Mine. Scroll down to find it and tap to build.'
|
||||||
|
},
|
||||||
|
complete: {
|
||||||
|
title: 'Quick Tutorial Complete!',
|
||||||
|
content:
|
||||||
|
"Great! You've mastered the basics. Continue building Crystal and Deuterium facilities, then explore other features. Remember: energy first, then resources!"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export default {
|
|||||||
close: '閉じる',
|
close: '閉じる',
|
||||||
back: '戻る',
|
back: '戻る',
|
||||||
next: '次へ',
|
next: '次へ',
|
||||||
|
gotIt: '',
|
||||||
previous: '前へ',
|
previous: '前へ',
|
||||||
submit: '送信',
|
submit: '送信',
|
||||||
reset: 'リセット',
|
reset: 'リセット',
|
||||||
@@ -33,13 +34,19 @@ export default {
|
|||||||
viewRequirements: '必要条件を表示',
|
viewRequirements: '必要条件を表示',
|
||||||
requirementsNotMet: '必要条件が満たされていません',
|
requirementsNotMet: '必要条件が満たされていません',
|
||||||
current: '現在',
|
current: '現在',
|
||||||
level: 'レベル'
|
level: 'レベル',
|
||||||
|
gmModeActivated: 'GMモードが有効になりました!ナビゲーションメニューをご確認ください。'
|
||||||
},
|
},
|
||||||
errors: {
|
errors: {
|
||||||
requirementsNotMet: '前提条件を満たしていません',
|
requirementsNotMet: '前提条件を満たしていません',
|
||||||
insufficientResources: '資源が不足しています',
|
insufficientResources: '資源が不足しています',
|
||||||
insufficientFleetStorage: '艦隊ストレージが不足しています',
|
insufficientFleetStorage: '艦隊ストレージが不足しています',
|
||||||
shieldDomeLimit: 'シールドドームの上限に達しました',
|
shieldDomeLimit: 'シールドドームの上限に達しました',
|
||||||
|
missileSiloLimit: 'ミサイル格納庫の容量を超えています',
|
||||||
|
insufficientMissiles: '惑星間ミサイルが不足しています',
|
||||||
|
invalidMissileCount: 'ミサイル数が無効です',
|
||||||
|
targetOutOfRange: 'ターゲットが射程外です',
|
||||||
|
cannotAttackOwnPlanet: '自分の惑星を攻撃できません',
|
||||||
fleetMissionsFull: '艦隊ミッションスロットが満杯です',
|
fleetMissionsFull: '艦隊ミッションスロットが満杯です',
|
||||||
insufficientFleet: '艦隊が不足しています',
|
insufficientFleet: '艦隊が不足しています',
|
||||||
insufficientFuel: '燃料が不足しています',
|
insufficientFuel: '燃料が不足しています',
|
||||||
@@ -119,6 +126,7 @@ export default {
|
|||||||
roboticsFactory: 'ロボット工場',
|
roboticsFactory: 'ロボット工場',
|
||||||
naniteFactory: 'ナノマシン工場',
|
naniteFactory: 'ナノマシン工場',
|
||||||
shipyard: '造船所',
|
shipyard: '造船所',
|
||||||
|
hangar: '格納庫',
|
||||||
researchLab: '研究所',
|
researchLab: '研究所',
|
||||||
metalStorage: '金属倉庫',
|
metalStorage: '金属倉庫',
|
||||||
crystalStorage: 'クリスタル倉庫',
|
crystalStorage: 'クリスタル倉庫',
|
||||||
@@ -159,6 +167,7 @@ export default {
|
|||||||
roboticsFactory: '建設速度を向上',
|
roboticsFactory: '建設速度を向上',
|
||||||
naniteFactory: '建設キュー数を増加、レベル毎に+1(最大10レベル)',
|
naniteFactory: '建設キュー数を増加、レベル毎に+1(最大10レベル)',
|
||||||
shipyard: '艦船を建造',
|
shipyard: '艦船を建造',
|
||||||
|
hangar: '艦隊収容能力を拡張する専用施設、惑星の専門化をサポート',
|
||||||
researchLab: '技術を研究',
|
researchLab: '技術を研究',
|
||||||
metalStorage: '金属の貯蔵上限を増加',
|
metalStorage: '金属の貯蔵上限を増加',
|
||||||
crystalStorage: 'クリスタルの貯蔵上限を増加',
|
crystalStorage: 'クリスタルの貯蔵上限を増加',
|
||||||
@@ -166,8 +175,8 @@ export default {
|
|||||||
darkMatterCollector: '希少なダークマター資源を収集',
|
darkMatterCollector: '希少なダークマター資源を収集',
|
||||||
darkMatterTank: 'ダークマターの貯蔵上限を増加',
|
darkMatterTank: 'ダークマターの貯蔵上限を増加',
|
||||||
missileSilo: 'ミサイルを保管・発射、レベル毎に10発',
|
missileSilo: 'ミサイルを保管・発射、レベル毎に10発',
|
||||||
terraformer: '惑星地形を改造、レベル毎に利用可能スペース5増加',
|
terraformer: '惑星地形を改造、レベル毎に利用可能スペース30増加',
|
||||||
lunarBase: '月の利用可能スペースを増加、レベル毎に+5スペース',
|
lunarBase: '月の利用可能スペースを増加、レベル毎に+30スペース',
|
||||||
sensorPhalanx: '周辺星系の艦隊活動を探知',
|
sensorPhalanx: '周辺星系の艦隊活動を探知',
|
||||||
jumpGate: '他の月へ艦隊を瞬間移動',
|
jumpGate: '他の月へ艦隊を瞬間移動',
|
||||||
planetDestroyerFactory: '惑星を破壊できる究極兵器を建造'
|
planetDestroyerFactory: '惑星を破壊できる究極兵器を建造'
|
||||||
@@ -193,10 +202,10 @@ export default {
|
|||||||
lightFighter: '基本戦闘ユニット',
|
lightFighter: '基本戦闘ユニット',
|
||||||
heavyFighter: '重装甲戦闘機',
|
heavyFighter: '重装甲戦闘機',
|
||||||
cruiser: '中型戦艦、攻守バランス型',
|
cruiser: '中型戦艦、攻守バランス型',
|
||||||
battleship: '強力な戦艦',
|
battleship: '主力重戦艦、強力な火力と高い防御力を持つ',
|
||||||
battlecruiser: '高速強力な戦闘艦、戦艦への攻撃に優れる',
|
battlecruiser: '高速強力な戦闘艦、戦艦への攻撃に優れる',
|
||||||
bomber: '防御施設への攻撃に特化した艦船',
|
bomber: '防御施設への攻撃に特化した艦船',
|
||||||
destroyer: '大型艦の破壊に特化したハンター',
|
destroyer: '対大型艦専用艦、高火力だが防御力が低い',
|
||||||
smallCargo: '少量の資源を輸送',
|
smallCargo: '少量の資源を輸送',
|
||||||
largeCargo: '大量の資源を輸送',
|
largeCargo: '大量の資源を輸送',
|
||||||
colonyShip: '新惑星の植民に使用',
|
colonyShip: '新惑星の植民に使用',
|
||||||
@@ -283,7 +292,7 @@ export default {
|
|||||||
impulseDrive: '中級推進技術',
|
impulseDrive: '中級推進技術',
|
||||||
hyperspaceDrive: '高級推進技術',
|
hyperspaceDrive: '高級推進技術',
|
||||||
darkMatterTechnology: 'ダークマターの性質と応用を研究',
|
darkMatterTechnology: 'ダークマターの性質と応用を研究',
|
||||||
terraformingTechnology: '惑星地形改造技術を研究、レベル毎に全惑星の利用可能スペース3増加',
|
terraformingTechnology: '惑星地形改造技術を研究、レベル毎に全惑星の利用可能スペース30増加',
|
||||||
planetDestructionTech: '惑星全体を破壊する恐怖の技術を研究'
|
planetDestructionTech: '惑星全体を破壊する恐怖の技術を研究'
|
||||||
},
|
},
|
||||||
officers: {
|
officers: {
|
||||||
@@ -306,20 +315,25 @@ export default {
|
|||||||
darkMatterSpecialist: 'ダークマター採取効率を向上'
|
darkMatterSpecialist: 'ダークマター採取効率を向上'
|
||||||
},
|
},
|
||||||
queue: {
|
queue: {
|
||||||
|
title: '建設キュー',
|
||||||
|
empty: '進行中のタスクはありません',
|
||||||
buildQueue: '建設キュー',
|
buildQueue: '建設キュー',
|
||||||
researchQueue: '研究キュー',
|
researchQueue: '研究キュー',
|
||||||
building: '建設中',
|
building: '建設中',
|
||||||
researching: '研究中',
|
researching: '研究中',
|
||||||
|
demolishing: '解体中',
|
||||||
remaining: '残り時間',
|
remaining: '残り時間',
|
||||||
cancel: 'キャンセル',
|
cancel: 'キャンセル',
|
||||||
cancelBuild: '建設キャンセル',
|
cancelBuild: '建設キャンセル',
|
||||||
cancelResearch: '研究キャンセル',
|
cancelResearch: '研究キャンセル',
|
||||||
confirmCancel: 'キャンセルしますか?資源の50%が返還されます。',
|
confirmCancel: 'キャンセルしますか?資源の50%が返還されます。',
|
||||||
level: 'レベル',
|
level: 'レベル',
|
||||||
|
gmModeActivated: '',
|
||||||
upgradeToLevel: 'レベルにアップグレード'
|
upgradeToLevel: 'レベルにアップグレード'
|
||||||
},
|
},
|
||||||
shipyard: {
|
shipyard: {
|
||||||
attack: '攻撃力',
|
attack: '攻撃力',
|
||||||
|
missileAttack: 'ミサイル攻撃',
|
||||||
shield: 'シールド',
|
shield: 'シールド',
|
||||||
armor: '装甲',
|
armor: '装甲',
|
||||||
speed: '速度',
|
speed: '速度',
|
||||||
@@ -351,6 +365,7 @@ export default {
|
|||||||
usedSpace: '使用済みスペース',
|
usedSpace: '使用済みスペース',
|
||||||
spaceUsage: 'スペース使用量',
|
spaceUsage: 'スペース使用量',
|
||||||
level: 'レベル',
|
level: 'レベル',
|
||||||
|
gmModeActivated: '',
|
||||||
upgradeCost: 'アップグレードコスト',
|
upgradeCost: 'アップグレードコスト',
|
||||||
buildTime: '建設時間',
|
buildTime: '建設時間',
|
||||||
upgrade: 'アップグレード',
|
upgrade: 'アップグレード',
|
||||||
@@ -362,8 +377,8 @@ export default {
|
|||||||
demolishRefund: '解体返還',
|
demolishRefund: '解体返還',
|
||||||
demolishFailed: '解体失敗',
|
demolishFailed: '解体失敗',
|
||||||
demolishFailedMessage: 'この建物を解体できません。建設キューが満杯か、建物レベルが0でないか確認してください。',
|
demolishFailedMessage: 'この建物を解体できません。建設キューが満杯か、建物レベルが0でないか確認してください。',
|
||||||
confirmDemolish: '',
|
confirmDemolish: '解体確認',
|
||||||
confirmDemolishMessage: ''
|
confirmDemolishMessage: '以下の建物を解体しますか?'
|
||||||
},
|
},
|
||||||
researchView: {
|
researchView: {
|
||||||
title: '研究',
|
title: '研究',
|
||||||
@@ -375,6 +390,7 @@ export default {
|
|||||||
},
|
},
|
||||||
defense: {
|
defense: {
|
||||||
attack: '攻撃力',
|
attack: '攻撃力',
|
||||||
|
missileAttack: 'ミサイル攻撃',
|
||||||
shield: 'シールド',
|
shield: 'シールド',
|
||||||
armor: '装甲',
|
armor: '装甲',
|
||||||
buildCost: '建設コスト',
|
buildCost: '建設コスト',
|
||||||
@@ -389,6 +405,7 @@ export default {
|
|||||||
title: '造船所',
|
title: '造船所',
|
||||||
fleetStorage: '艦隊ストレージ',
|
fleetStorage: '艦隊ストレージ',
|
||||||
attack: '攻撃力',
|
attack: '攻撃力',
|
||||||
|
missileAttack: 'ミサイル攻撃',
|
||||||
shield: 'シールド',
|
shield: 'シールド',
|
||||||
speed: '速度',
|
speed: '速度',
|
||||||
cargoCapacity: '積載量',
|
cargoCapacity: '積載量',
|
||||||
@@ -404,6 +421,7 @@ export default {
|
|||||||
defenseView: {
|
defenseView: {
|
||||||
title: '防衛施設',
|
title: '防衛施設',
|
||||||
attack: '攻撃力',
|
attack: '攻撃力',
|
||||||
|
missileAttack: 'ミサイル攻撃',
|
||||||
shield: 'シールド',
|
shield: 'シールド',
|
||||||
armor: '装甲',
|
armor: '装甲',
|
||||||
buildTime: '建設時間',
|
buildTime: '建設時間',
|
||||||
@@ -413,6 +431,7 @@ export default {
|
|||||||
totalCost: '総コスト',
|
totalCost: '総コスト',
|
||||||
build: '建造',
|
build: '建造',
|
||||||
shieldDomeBuilt: 'シールドドーム建設済み',
|
shieldDomeBuilt: 'シールドドーム建設済み',
|
||||||
|
missileCapacity: 'ミサイル容量',
|
||||||
inputError: '入力エラー',
|
inputError: '入力エラー',
|
||||||
inputErrorMessage: '建造数を入力してください!',
|
inputErrorMessage: '建造数を入力してください!',
|
||||||
buildFailed: '建造失敗',
|
buildFailed: '建造失敗',
|
||||||
@@ -425,6 +444,7 @@ export default {
|
|||||||
flightMissions: '飛行ミッション',
|
flightMissions: '飛行ミッション',
|
||||||
currentPlanetFleet: '現在の惑星艦隊',
|
currentPlanetFleet: '現在の惑星艦隊',
|
||||||
attack: '攻撃',
|
attack: '攻撃',
|
||||||
|
missileAttack: 'ミサイル攻撃',
|
||||||
shield: 'シールド',
|
shield: 'シールド',
|
||||||
armor: '装甲',
|
armor: '装甲',
|
||||||
speed: '速度',
|
speed: '速度',
|
||||||
@@ -459,6 +479,11 @@ export default {
|
|||||||
arrivalTime: '到着時刻',
|
arrivalTime: '到着時刻',
|
||||||
returnTime: '帰還時刻',
|
returnTime: '帰還時刻',
|
||||||
recallFleet: '艦隊召還',
|
recallFleet: '艦隊召還',
|
||||||
|
abortMission: '',
|
||||||
|
abortMissionTitle: '',
|
||||||
|
abortMissionWarning: '',
|
||||||
|
abortMissionSuccess: '',
|
||||||
|
abortMissionSuccessMessage: '',
|
||||||
sendFailed: '派遣失敗',
|
sendFailed: '派遣失敗',
|
||||||
sendFailedMessage: '艦隊数、燃料の充足、または積載量の制限を確認してください。',
|
sendFailedMessage: '艦隊数、燃料の充足、または積載量の制限を確認してください。',
|
||||||
recallFailed: '召還失敗',
|
recallFailed: '召還失敗',
|
||||||
@@ -519,25 +544,36 @@ export default {
|
|||||||
selectSystem: '星系を選択',
|
selectSystem: '星系を選択',
|
||||||
view: '表示',
|
view: '表示',
|
||||||
myPlanet: '自分の惑星',
|
myPlanet: '自分の惑星',
|
||||||
myPlanets: '私の惑星',
|
myPlanets: '自分の星系を表示',
|
||||||
npcPlanets: 'NPCの惑星',
|
npcPlanets: 'NPCの惑星',
|
||||||
selectPlanetToView: '表示する惑星を選択',
|
selectPlanetToView: '惑星を選択して星系を表示',
|
||||||
totalPositions: '全10惑星位置',
|
totalPositions: '全10惑星位置',
|
||||||
mine: '自分',
|
mine: '自分',
|
||||||
hostile: '敵対',
|
hostile: '敵対',
|
||||||
emptySlot: '空き - 植民可能',
|
emptySlot: '空き - 植民可能',
|
||||||
scout: '偵察',
|
scout: '偵察',
|
||||||
attack: '攻撃',
|
attack: '攻撃',
|
||||||
|
missileAttack: 'ミサイル攻撃',
|
||||||
colonize: '植民',
|
colonize: '植民',
|
||||||
switch: '切り替え',
|
switch: '切り替え',
|
||||||
recycle: '回収',
|
recycle: '回収',
|
||||||
debrisField: 'デブリフィールド',
|
debrisField: 'デブリフィールド',
|
||||||
scoutPlanetTitle: '惑星偵察',
|
scoutPlanetTitle: '惑星偵察',
|
||||||
attackPlanetTitle: '惑星攻撃',
|
attackPlanetTitle: '惑星攻撃',
|
||||||
|
missileAttackTitle: 'ミサイル攻撃',
|
||||||
colonizePlanetTitle: '惑星植民',
|
colonizePlanetTitle: '惑星植民',
|
||||||
recyclePlanetTitle: 'デブリ回収',
|
recyclePlanetTitle: 'デブリ回収',
|
||||||
scoutPlanetMessage: '惑星[{coordinates}]にスパイプローブを送りますか?\n\n艦隊ページに移動して艦船を選択して派遣してください。',
|
scoutPlanetMessage: '惑星[{coordinates}]にスパイプローブを送りますか?\n\n艦隊ページに移動して艦船を選択して派遣してください。',
|
||||||
attackPlanetMessage: '惑星[{coordinates}]を攻撃しますか?\n\n艦隊ページに移動して艦船を選択して派遣してください。',
|
attackPlanetMessage: '惑星[{coordinates}]を攻撃しますか?\n\n艦隊ページに移動して艦船を選択して派遣してください。',
|
||||||
|
missileAttackMessage: '惑星[{coordinates}]に惑星間ミサイルを発射',
|
||||||
|
missileCount: 'ミサイル数',
|
||||||
|
availableMissiles: '利用可能なミサイル',
|
||||||
|
missileRange: 'ミサイル射程',
|
||||||
|
systems: 'システム',
|
||||||
|
distance: '距離',
|
||||||
|
flightTime: '飛行時間',
|
||||||
|
launchMissile: '発射',
|
||||||
|
cancel: 'キャンセル',
|
||||||
colonizePlanetMessage: '位置[{coordinates}]を植民しますか?\n\n艦隊ページに移動してコロニーシップを派遣してください。',
|
colonizePlanetMessage: '位置[{coordinates}]を植民しますか?\n\n艦隊ページに移動してコロニーシップを派遣してください。',
|
||||||
recyclePlanetMessage: '位置[{coordinates}]のデブリを回収しますか?\n\n艦隊ページに移動してリサイクラーを派遣してください。',
|
recyclePlanetMessage: '位置[{coordinates}]のデブリを回収しますか?\n\n艦隊ページに移動してリサイクラーを派遣してください。',
|
||||||
sendGift: 'ギフト送信',
|
sendGift: 'ギフト送信',
|
||||||
@@ -550,10 +586,12 @@ export default {
|
|||||||
battles: '戦闘',
|
battles: '戦闘',
|
||||||
spy: 'スパイ',
|
spy: 'スパイ',
|
||||||
npc: 'NPC',
|
npc: 'NPC',
|
||||||
|
diplomacy: '',
|
||||||
battleReports: '戦闘レポート',
|
battleReports: '戦闘レポート',
|
||||||
spyReports: 'スパイレポート',
|
spyReports: 'スパイレポート',
|
||||||
noBattleReports: '戦闘レポートなし',
|
noBattleReports: '戦闘レポートなし',
|
||||||
noSpyReports: 'スパイレポートなし',
|
noSpyReports: 'スパイレポートなし',
|
||||||
|
noDiplomaticReports: '',
|
||||||
battleReport: '戦闘レポート',
|
battleReport: '戦闘レポート',
|
||||||
spyReport: 'スパイレポート',
|
spyReport: 'スパイレポート',
|
||||||
victory: '勝利',
|
victory: '勝利',
|
||||||
@@ -609,7 +647,38 @@ export default {
|
|||||||
hostile: '相手は敵対的でギフトを受け取りません',
|
hostile: '相手は敵対的でギフトを受け取りません',
|
||||||
neutral_distrust: '相手はあなたを信頼していません',
|
neutral_distrust: '相手はあなたを信頼していません',
|
||||||
polite_decline: '丁重に断りました'
|
polite_decline: '丁重に断りました'
|
||||||
}
|
},
|
||||||
|
// Spied notification dialog
|
||||||
|
spiedNotificationDetails: '',
|
||||||
|
spyDetected: '',
|
||||||
|
detectionResult: '',
|
||||||
|
detectionSuccess: '',
|
||||||
|
spiedNotificationMessage: '',
|
||||||
|
spiedNotificationTip: '',
|
||||||
|
viewInGalaxy: '',
|
||||||
|
// Mission report dialog
|
||||||
|
missionReportDetails: '',
|
||||||
|
missionSuccess: '',
|
||||||
|
missionFailed: '',
|
||||||
|
origin: '',
|
||||||
|
destination: '',
|
||||||
|
missionDetails: '',
|
||||||
|
transportedResources: '',
|
||||||
|
recycledResources: '',
|
||||||
|
remainingDebris: '',
|
||||||
|
newPlanet: '',
|
||||||
|
// NPC activity dialog
|
||||||
|
npcActivityDetails: '',
|
||||||
|
activityType: {
|
||||||
|
recycle: ''
|
||||||
|
},
|
||||||
|
activityLocation: '',
|
||||||
|
position: '',
|
||||||
|
nearPlanet: '',
|
||||||
|
activityDescription: '',
|
||||||
|
npcActivityMessage: '',
|
||||||
|
arrivalTime: '',
|
||||||
|
npcActivityTip: ''
|
||||||
},
|
},
|
||||||
missionReports: {
|
missionReports: {
|
||||||
transportSuccess: '輸送ミッションが正常に完了しました',
|
transportSuccess: '輸送ミッションが正常に完了しました',
|
||||||
@@ -690,10 +759,24 @@ export default {
|
|||||||
gamePaused: 'ゲームを一時停止しました',
|
gamePaused: 'ゲームを一時停止しました',
|
||||||
gameResumed: 'ゲームを再開しました',
|
gameResumed: 'ゲームを再開しました',
|
||||||
playerName: 'プレイヤー名',
|
playerName: 'プレイヤー名',
|
||||||
gameSpeed: 'ゲーム速度',
|
gameSpeed: '資源生産速度',
|
||||||
gameSpeedDesc: '現在のゲーム速度倍率',
|
gameSpeedDesc: '現在の資源生産速度倍率',
|
||||||
|
speedChanged: '資源生産速度を{speed}xに変更しました',
|
||||||
|
speedReset: '資源生産速度を1xにリセットしました',
|
||||||
|
reset: 'リセット',
|
||||||
about: 'について',
|
about: 'について',
|
||||||
version: 'バージョン',
|
version: 'バージョン',
|
||||||
|
latestVersion: '最新バージョン',
|
||||||
|
checkUpdate: 'アップデート確認',
|
||||||
|
checking: '確認中...',
|
||||||
|
newVersionAvailable: '新バージョン{version}が利用可能です',
|
||||||
|
upToDate: '最新バージョンです',
|
||||||
|
checkUpdateCooldown: 'しばらくしてから再度お試しください(5分間のクールダウン)',
|
||||||
|
checkUpdateFailed: 'アップデートの確認に失敗しました。ネットワーク接続を確認してください',
|
||||||
|
viewUpdate: '更新を表示',
|
||||||
|
updateAvailable: '新しいバージョンが利用可能です。クリックしてリリースノートを表示します。',
|
||||||
|
download: 'ダウンロード',
|
||||||
|
goToDownload: 'ダウンロードへ',
|
||||||
buildDate: 'ビルド日',
|
buildDate: 'ビルド日',
|
||||||
community: 'コミュニティ',
|
community: 'コミュニティ',
|
||||||
github: 'GitHubリポジトリ',
|
github: 'GitHubリポジトリ',
|
||||||
@@ -712,6 +795,8 @@ export default {
|
|||||||
officers: '士官',
|
officers: '士官',
|
||||||
modifyResources: '資源を変更',
|
modifyResources: '資源を変更',
|
||||||
resourcesDesc: '惑星の資源を素早く変更',
|
resourcesDesc: '惑星の資源を素早く変更',
|
||||||
|
maxAllResources: '',
|
||||||
|
maxAllResourcesSuccess: '',
|
||||||
modifyBuildings: '建物を変更',
|
modifyBuildings: '建物を変更',
|
||||||
buildingsDesc: '建物レベルを素早く設定',
|
buildingsDesc: '建物レベルを素早く設定',
|
||||||
modifyResearch: '研究を変更',
|
modifyResearch: '研究を変更',
|
||||||
@@ -732,16 +817,30 @@ export default {
|
|||||||
testSpy: '偵察テスト',
|
testSpy: '偵察テスト',
|
||||||
testAttack: '攻撃テスト',
|
testAttack: '攻撃テスト',
|
||||||
testSpyAndAttack: '偵察&攻撃テスト',
|
testSpyAndAttack: '偵察&攻撃テスト',
|
||||||
|
testSpyMessage: '確認をクリックして偵察ミッションを加速',
|
||||||
|
testAttackMessage: '確認をクリックして攻撃ミッションを加速',
|
||||||
|
testSpyAndAttackMessage: '確認をクリックしてミッションを加速',
|
||||||
initializeFleet: 'NPC艦隊を初期化',
|
initializeFleet: 'NPC艦隊を初期化',
|
||||||
accelerateMissions: 'すべてのミッションを加速(5秒)',
|
accelerateMissions: 'すべてのミッションを加速(5秒)',
|
||||||
selectNPCFirst: '最初にNPCを選択してください',
|
selectNPCFirst: '最初にNPCを選択してください',
|
||||||
npcNoProbes: 'NPCには偵察プローブがありません',
|
npcNoProbes: 'NPCには偵察プローブがありません',
|
||||||
npcNoSpyReport: 'NPCは最初に偵察する必要があります',
|
npcNoSpyReport: 'NPCは最初に偵察する必要があります',
|
||||||
npcMissionFailed: 'ミッションの作成に失敗しました',
|
npcMissionFailed: 'ミッションの作成に失敗しました',
|
||||||
|
npcNoPlanets: 'NPCに惑星がありません',
|
||||||
|
npcWillSpyIn5s: '{npcName}は5秒後に偵察します',
|
||||||
|
npcWillAttackIn5s: '{npcName}は5秒後に攻撃します',
|
||||||
|
npcWillSpyAndAttack: '{npcName}は5秒後に偵察し、10秒後に攻撃します',
|
||||||
|
acceleratedMissions: '{count}個のミッションを5秒後に加速しました',
|
||||||
|
npcFleetInitialized: '{npcName}艦隊が初期化されました',
|
||||||
|
npcFleetDetails: '100 偵察プローブ\n500 軽戦闘機\n300 重戦闘機\n200 巡洋艦\n100 戦艦\n50 爆撃機\n30 駆逐艦\n20 巡洋戦艦',
|
||||||
dangerZone: '危険ゾーン',
|
dangerZone: '危険ゾーン',
|
||||||
dangerZoneDesc: '以下の操作は元に戻せません',
|
dangerZoneDesc: '以下の操作は元に戻せません',
|
||||||
resetGame: 'ゲームをリセット',
|
resetGame: 'ゲームをリセット',
|
||||||
resetGameConfirm: 'ゲームをリセットしてもよろしいですか?すべてのデータが削除されます!'
|
resetGameConfirm: 'ゲームをリセットしてもよろしいですか?すべてのデータが削除されます!',
|
||||||
|
completeAllQueues: '',
|
||||||
|
completeAllQueuesDesc: '',
|
||||||
|
completeQueues: '',
|
||||||
|
completeQueuesSuccess: ''
|
||||||
},
|
},
|
||||||
alerts: {
|
alerts: {
|
||||||
npcSpyIncoming: 'NPC偵察プローブが接近中',
|
npcSpyIncoming: 'NPC偵察プローブが接近中',
|
||||||
@@ -771,6 +870,10 @@ export default {
|
|||||||
recentEvents: '最近のイベント',
|
recentEvents: '最近のイベント',
|
||||||
recentEventsDescription: '最近の外交活動ログ',
|
recentEventsDescription: '最近の外交活動ログ',
|
||||||
ago: '前',
|
ago: '前',
|
||||||
|
notifications: '',
|
||||||
|
markAllRead: '',
|
||||||
|
noReports: '',
|
||||||
|
viewAll: '',
|
||||||
status: {
|
status: {
|
||||||
friendly: '友好的',
|
friendly: '友好的',
|
||||||
neutral: '中立',
|
neutral: '中立',
|
||||||
@@ -786,19 +889,96 @@ export default {
|
|||||||
viewPlanets: '惑星を表示'
|
viewPlanets: '惑星を表示'
|
||||||
},
|
},
|
||||||
lastEvent: '最後のイベント',
|
lastEvent: '最後のイベント',
|
||||||
|
reportDetails: '',
|
||||||
|
eventDescription: '',
|
||||||
|
reputationChange: '',
|
||||||
|
before: '',
|
||||||
|
after: '',
|
||||||
|
statusChange: '',
|
||||||
|
viewDiplomacy: '',
|
||||||
events: {
|
events: {
|
||||||
gift: 'ギフト送信',
|
gift: 'ギフト送信',
|
||||||
attack: '攻撃',
|
attack: '攻撃',
|
||||||
|
missileAttack: 'ミサイル攻撃',
|
||||||
allyAttacked: '同盟が攻撃された',
|
allyAttacked: '同盟が攻撃された',
|
||||||
spy: '諜報活動',
|
spy: '諜報活動',
|
||||||
stealDebris: '残骸を略奪'
|
stealDebris: '残骸を略奪'
|
||||||
|
},
|
||||||
|
reports: {
|
||||||
|
giftedResources: '{metal}M {crystal}C {deuterium}Dを贈呈',
|
||||||
|
receivedGiftFromPlayer: 'プレイヤーからギフトを受け取りました',
|
||||||
|
giftedToNpc: '{npcName}にリソースを贈呈しました。評判+{reputation}',
|
||||||
|
rejectedPlayerGift: 'プレイヤーのギフトを拒否しました',
|
||||||
|
npcRejectedGift: '{npcName}があなたのギフトを拒否しました。評判{reputation}',
|
||||||
|
attackedNpc: '{npcName}を攻撃しました',
|
||||||
|
wasAttackedByPlayer: 'プレイヤーに攻撃されました',
|
||||||
|
youAttackedNpc: 'あなたは{npcName}を攻撃しました',
|
||||||
|
playerAttackedAlly: 'プレイヤーが同盟{allyName}を攻撃しました',
|
||||||
|
allyDispleased: '{allyName}はあなたが同盟{targetName}を攻撃したことに不満です',
|
||||||
|
wasSpiedByPlayer: 'プレイヤーに偵察されました(発見:{detected})',
|
||||||
|
spyDetected: 'あなたの偵察が{npcName}に発見されました',
|
||||||
|
stoleDebrisFromTerritory: '{npcName}の領域から残骸を略奪しました',
|
||||||
|
playerStoleDebris: 'プレイヤーが領域から残骸を略奪しました',
|
||||||
|
recycledDebrisNearNpc: '{npcName}の惑星近くで残骸を回収しました。彼らは不満です。',
|
||||||
|
giftedResourcesToPlayer: 'プレイヤーにリソースを贈呈しました',
|
||||||
|
receivedGiftFromNpc: '{npcName}からギフトを受け取りました',
|
||||||
|
acceptedGiftFromNpc: '{npcName}からのギフトを受け取りました:{metal}M {crystal}C {deuterium}D',
|
||||||
|
playerRejectedGift: 'プレイヤーがギフトを拒否しました',
|
||||||
|
rejectedGiftFromNpc: '{npcName}からのギフトを拒否しました。評判{reputation}',
|
||||||
|
destroyedNpcPlanet: '{npcName}の{planetName}を破壊しました',
|
||||||
|
playerDestroyedPlanet: 'プレイヤーが{planetName}を破壊しました',
|
||||||
|
youDestroyedNpcPlanet: 'あなたは{npcName}の{planetName}を破壊しました。評判{reputation}',
|
||||||
|
playerDestroyedAllyPlanet: 'プレイヤーが同盟{allyName}の{planetName}を破壊しました',
|
||||||
|
allyOutraged: '{allyName}はあなたが同盟{targetName}の{planetName}を破壊したことに激怒しています',
|
||||||
|
npcEliminated: 'NPC {npcName}は完全に排除されました',
|
||||||
|
npcEliminatedMessage: 'あなたは{npcName}のすべての惑星を破壊しました!この勢力は完全に壊滅しました。'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pagination: {
|
pagination: {
|
||||||
previous: '前へ',
|
previous: '前へ',
|
||||||
next: '次へ',
|
next: '次へ',
|
||||||
|
gotIt: '',
|
||||||
first: '最初',
|
first: '最初',
|
||||||
last: '最後',
|
last: '最後',
|
||||||
page: '{page}ページ'
|
page: '{page}ページ'
|
||||||
|
},
|
||||||
|
notFound: {
|
||||||
|
title: 'ページが見つかりません',
|
||||||
|
description: '申し訳ございません。お探しのページは存在しません',
|
||||||
|
goHome: 'ホームに戻る'
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
days: '日',
|
||||||
|
hours: '時間',
|
||||||
|
minutes: '分',
|
||||||
|
seconds: '秒'
|
||||||
|
},
|
||||||
|
tutorial: {
|
||||||
|
welcome: {
|
||||||
|
title: 'OGame-Vue-Ts へようこそ',
|
||||||
|
content: 'ようこそ、司令官!基礎から始めて、宇宙帝国を築きましょう。'
|
||||||
|
},
|
||||||
|
buildSolarPlant: {
|
||||||
|
title: '太陽光発電所を建設',
|
||||||
|
content:
|
||||||
|
'まず太陽光発電所を建設しましょう!惑星にエネルギーを供給します。エネルギーがないと、他の資源施設が機能しません。これが最も重要な第一歩です。'
|
||||||
|
},
|
||||||
|
waitBuild: {
|
||||||
|
title: '建設キュー',
|
||||||
|
content:
|
||||||
|
'建物は建設キューに追加されました。右上のキューアイコンをクリックすると、進行中のすべての建設と研究タスクを確認できます。建設には時間がかかりますが、待機中も作業を続けられます。'
|
||||||
|
},
|
||||||
|
mobile: {
|
||||||
|
welcome: {
|
||||||
|
title: 'OGame-Vue-Ts へようこそ(モバイル版)',
|
||||||
|
content:
|
||||||
|
'ようこそ、司令官!これはタッチスクリーン向けに最適化された簡易チュートリアルです。帝国建設を始めるために、コア機能を素早くご紹介します。'
|
||||||
|
},
|
||||||
|
waitBuild: {
|
||||||
|
title: '建設キュー',
|
||||||
|
content:
|
||||||
|
'右上のキューアイコンをクリックして建設進度を確認できます。他のページを閲覧し続けることができます。建設はバックグラウンドで進行します。'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export default {
|
|||||||
close: '닫기',
|
close: '닫기',
|
||||||
back: '돌아가기',
|
back: '돌아가기',
|
||||||
next: '다음',
|
next: '다음',
|
||||||
|
gotIt: '',
|
||||||
previous: '이전',
|
previous: '이전',
|
||||||
submit: '제출',
|
submit: '제출',
|
||||||
reset: '초기화',
|
reset: '초기화',
|
||||||
@@ -33,13 +34,19 @@ export default {
|
|||||||
viewRequirements: '요구사항 보기',
|
viewRequirements: '요구사항 보기',
|
||||||
requirementsNotMet: '요구사항 미충족',
|
requirementsNotMet: '요구사항 미충족',
|
||||||
current: '현재',
|
current: '현재',
|
||||||
level: '레벨'
|
level: '레벨',
|
||||||
|
gmModeActivated: 'GM 모드가 활성화되었습니다! 탐색 메뉴를 확인하세요.'
|
||||||
},
|
},
|
||||||
errors: {
|
errors: {
|
||||||
requirementsNotMet: '전제 조건 미충족',
|
requirementsNotMet: '전제 조건 미충족',
|
||||||
insufficientResources: '자원 부족',
|
insufficientResources: '자원 부족',
|
||||||
insufficientFleetStorage: '함대 저장소 부족',
|
insufficientFleetStorage: '함대 저장소 부족',
|
||||||
shieldDomeLimit: '실드 돔 한도 도달',
|
shieldDomeLimit: '실드 돔 한도 도달',
|
||||||
|
missileSiloLimit: '미사일 사일로 용량 초과',
|
||||||
|
insufficientMissiles: '행성간 미사일 부족',
|
||||||
|
invalidMissileCount: '잘못된 미사일 수량',
|
||||||
|
targetOutOfRange: '목표가 사정거리 밖',
|
||||||
|
cannotAttackOwnPlanet: '자신의 행성 공격 불가',
|
||||||
fleetMissionsFull: '함대 임무 슬롯 가득 참',
|
fleetMissionsFull: '함대 임무 슬롯 가득 참',
|
||||||
insufficientFleet: '함대 부족',
|
insufficientFleet: '함대 부족',
|
||||||
insufficientFuel: '연료 부족',
|
insufficientFuel: '연료 부족',
|
||||||
@@ -119,6 +126,7 @@ export default {
|
|||||||
roboticsFactory: '로봇 공장',
|
roboticsFactory: '로봇 공장',
|
||||||
naniteFactory: '나노 공장',
|
naniteFactory: '나노 공장',
|
||||||
shipyard: '조선소',
|
shipyard: '조선소',
|
||||||
|
hangar: '격납고',
|
||||||
researchLab: '연구소',
|
researchLab: '연구소',
|
||||||
metalStorage: '금속 창고',
|
metalStorage: '금속 창고',
|
||||||
crystalStorage: '크리스탈 창고',
|
crystalStorage: '크리스탈 창고',
|
||||||
@@ -159,6 +167,7 @@ export default {
|
|||||||
roboticsFactory: '건설 속도 향상',
|
roboticsFactory: '건설 속도 향상',
|
||||||
naniteFactory: '건설 대기열 수 증가, 레벨당 +1 (최대 10레벨)',
|
naniteFactory: '건설 대기열 수 증가, 레벨당 +1 (최대 10레벨)',
|
||||||
shipyard: '함선 건조',
|
shipyard: '함선 건조',
|
||||||
|
hangar: '함대 저장 용량 확장 전용 시설, 행성 전문화 지원',
|
||||||
researchLab: '기술 연구',
|
researchLab: '기술 연구',
|
||||||
metalStorage: '금속 저장 용량 증가',
|
metalStorage: '금속 저장 용량 증가',
|
||||||
crystalStorage: '크리스탈 저장 용량 증가',
|
crystalStorage: '크리스탈 저장 용량 증가',
|
||||||
@@ -166,8 +175,8 @@ export default {
|
|||||||
darkMatterCollector: '희귀한 암흑 물질 자원 수집',
|
darkMatterCollector: '희귀한 암흑 물질 자원 수집',
|
||||||
darkMatterTank: '암흑 물질 저장 용량 증가',
|
darkMatterTank: '암흑 물질 저장 용량 증가',
|
||||||
missileSilo: '미사일을 저장 및 발사, 레벨당 10발',
|
missileSilo: '미사일을 저장 및 발사, 레벨당 10발',
|
||||||
terraformer: '행성 지형 개조, 레벨당 가용 공간 5 증가',
|
terraformer: '행성 지형 개조, 레벨당 가용 공간 30 증가',
|
||||||
lunarBase: '달 가용 공간 증가, 레벨당 +5 공간',
|
lunarBase: '달 가용 공간 증가, 레벨당 +30 공간',
|
||||||
sensorPhalanx: '주변 행성계의 함대 활동 감지',
|
sensorPhalanx: '주변 행성계의 함대 활동 감지',
|
||||||
jumpGate: '다른 위성으로 함대 순간 이동',
|
jumpGate: '다른 위성으로 함대 순간 이동',
|
||||||
planetDestroyerFactory: '행성을 파괴할 수 있는 궁극 병기 건조'
|
planetDestroyerFactory: '행성을 파괴할 수 있는 궁극 병기 건조'
|
||||||
@@ -193,10 +202,10 @@ export default {
|
|||||||
lightFighter: '기본 전투 유닛',
|
lightFighter: '기본 전투 유닛',
|
||||||
heavyFighter: '중장갑 전투기',
|
heavyFighter: '중장갑 전투기',
|
||||||
cruiser: '중형 전함, 공격과 방어 균형',
|
cruiser: '중형 전함, 공격과 방어 균형',
|
||||||
battleship: '강력한 전함',
|
battleship: '주력 중전함, 강력한 화력과 높은 방어력 보유',
|
||||||
battlecruiser: '빠르고 강력한 전투함, 전함 공격에 탁월',
|
battlecruiser: '빠르고 강력한 전투함, 전함 공격에 탁월',
|
||||||
bomber: '방어 시설 공격 전문 함선',
|
bomber: '방어 시설 공격 전문 함선',
|
||||||
destroyer: '대형 함선 파괴 전문 헌터',
|
destroyer: '대형 함선 전문 격파함, 높은 화력이지만 방어력 낮음',
|
||||||
smallCargo: '소량의 자원 운송',
|
smallCargo: '소량의 자원 운송',
|
||||||
largeCargo: '대량의 자원 운송',
|
largeCargo: '대량의 자원 운송',
|
||||||
colonyShip: '새로운 행성 식민에 사용',
|
colonyShip: '새로운 행성 식민에 사용',
|
||||||
@@ -283,7 +292,7 @@ export default {
|
|||||||
impulseDrive: '중급 추진 기술',
|
impulseDrive: '중급 추진 기술',
|
||||||
hyperspaceDrive: '고급 추진 기술',
|
hyperspaceDrive: '고급 추진 기술',
|
||||||
darkMatterTechnology: '암흑 물질의 성질과 응용 연구',
|
darkMatterTechnology: '암흑 물질의 성질과 응용 연구',
|
||||||
terraformingTechnology: '행성 지형 개조 기술 연구, 레벨당 모든 행성의 가용 공간 3 증가',
|
terraformingTechnology: '행성 지형 개조 기술 연구, 레벨당 모든 행성의 가용 공간 30 증가',
|
||||||
planetDestructionTech: '행성 전체를 파괴하는 공포의 기술 연구'
|
planetDestructionTech: '행성 전체를 파괴하는 공포의 기술 연구'
|
||||||
},
|
},
|
||||||
officers: {
|
officers: {
|
||||||
@@ -306,16 +315,20 @@ export default {
|
|||||||
darkMatterSpecialist: '암흑 물질 수집 효율 향상'
|
darkMatterSpecialist: '암흑 물질 수집 효율 향상'
|
||||||
},
|
},
|
||||||
queue: {
|
queue: {
|
||||||
|
title: '건설 대기열',
|
||||||
|
empty: '활성 작업 없음',
|
||||||
buildQueue: '건설 대기열',
|
buildQueue: '건설 대기열',
|
||||||
researchQueue: '연구 대기열',
|
researchQueue: '연구 대기열',
|
||||||
building: '건설 중',
|
building: '건설 중',
|
||||||
researching: '연구 중',
|
researching: '연구 중',
|
||||||
|
demolishing: '철거 중',
|
||||||
remaining: '남은 시간',
|
remaining: '남은 시간',
|
||||||
cancel: '취소',
|
cancel: '취소',
|
||||||
cancelBuild: '건설 취소',
|
cancelBuild: '건설 취소',
|
||||||
cancelResearch: '연구 취소',
|
cancelResearch: '연구 취소',
|
||||||
confirmCancel: '취소하시겠습니까? 자원의 50%가 환불됩니다.',
|
confirmCancel: '취소하시겠습니까? 자원의 50%가 환불됩니다.',
|
||||||
level: '레벨',
|
level: '레벨',
|
||||||
|
gmModeActivated: '',
|
||||||
upgradeToLevel: '레벨로 업그레이드'
|
upgradeToLevel: '레벨로 업그레이드'
|
||||||
},
|
},
|
||||||
overview: {
|
overview: {
|
||||||
@@ -336,6 +349,7 @@ export default {
|
|||||||
usedSpace: '사용된 공간',
|
usedSpace: '사용된 공간',
|
||||||
spaceUsage: '공간 사용',
|
spaceUsage: '공간 사용',
|
||||||
level: '레벨',
|
level: '레벨',
|
||||||
|
gmModeActivated: '',
|
||||||
upgradeCost: '업그레이드 비용',
|
upgradeCost: '업그레이드 비용',
|
||||||
buildTime: '건설 시간',
|
buildTime: '건설 시간',
|
||||||
upgrade: '업그레이드',
|
upgrade: '업그레이드',
|
||||||
@@ -347,8 +361,8 @@ export default {
|
|||||||
demolishRefund: '철거 환불',
|
demolishRefund: '철거 환불',
|
||||||
demolishFailed: '철거 실패',
|
demolishFailed: '철거 실패',
|
||||||
demolishFailedMessage: '이 건물을 철거할 수 없습니다. 건설 대기열이 가득 찼거나 건물 레벨이 0인지 확인하세요.',
|
demolishFailedMessage: '이 건물을 철거할 수 없습니다. 건설 대기열이 가득 찼거나 건물 레벨이 0인지 확인하세요.',
|
||||||
confirmDemolish: '',
|
confirmDemolish: '철거 확인',
|
||||||
confirmDemolishMessage: ''
|
confirmDemolishMessage: '다음 건물을 철거하시겠습니까?'
|
||||||
},
|
},
|
||||||
researchView: {
|
researchView: {
|
||||||
title: '연구',
|
title: '연구',
|
||||||
@@ -360,6 +374,7 @@ export default {
|
|||||||
},
|
},
|
||||||
shipyard: {
|
shipyard: {
|
||||||
attack: '공격력',
|
attack: '공격력',
|
||||||
|
missileAttack: '미사일 공격',
|
||||||
shield: '쉴드',
|
shield: '쉴드',
|
||||||
armor: '장갑',
|
armor: '장갑',
|
||||||
speed: '속도',
|
speed: '속도',
|
||||||
@@ -377,6 +392,7 @@ export default {
|
|||||||
title: '조선소',
|
title: '조선소',
|
||||||
fleetStorage: '함대 저장소',
|
fleetStorage: '함대 저장소',
|
||||||
attack: '공격력',
|
attack: '공격력',
|
||||||
|
missileAttack: '미사일 공격',
|
||||||
shield: '실드',
|
shield: '실드',
|
||||||
speed: '속도',
|
speed: '속도',
|
||||||
cargoCapacity: '적재량',
|
cargoCapacity: '적재량',
|
||||||
@@ -391,6 +407,7 @@ export default {
|
|||||||
},
|
},
|
||||||
defense: {
|
defense: {
|
||||||
attack: '공격력',
|
attack: '공격력',
|
||||||
|
missileAttack: '미사일 공격',
|
||||||
shield: '쉴드',
|
shield: '쉴드',
|
||||||
armor: '장갑',
|
armor: '장갑',
|
||||||
buildCost: '건설 비용',
|
buildCost: '건설 비용',
|
||||||
@@ -404,6 +421,7 @@ export default {
|
|||||||
defenseView: {
|
defenseView: {
|
||||||
title: '방어 시설',
|
title: '방어 시설',
|
||||||
attack: '공격력',
|
attack: '공격력',
|
||||||
|
missileAttack: '미사일 공격',
|
||||||
shield: '실드',
|
shield: '실드',
|
||||||
armor: '장갑',
|
armor: '장갑',
|
||||||
buildTime: '건설 시간',
|
buildTime: '건설 시간',
|
||||||
@@ -413,6 +431,7 @@ export default {
|
|||||||
totalCost: '총 비용',
|
totalCost: '총 비용',
|
||||||
build: '건조',
|
build: '건조',
|
||||||
shieldDomeBuilt: '실드 돔이 이미 건설됨',
|
shieldDomeBuilt: '실드 돔이 이미 건설됨',
|
||||||
|
missileCapacity: '미사일 용량',
|
||||||
inputError: '입력 오류',
|
inputError: '입력 오류',
|
||||||
inputErrorMessage: '건조 수량을 입력하세요!',
|
inputErrorMessage: '건조 수량을 입력하세요!',
|
||||||
buildFailed: '건조 실패',
|
buildFailed: '건조 실패',
|
||||||
@@ -425,6 +444,7 @@ export default {
|
|||||||
flightMissions: '비행 임무',
|
flightMissions: '비행 임무',
|
||||||
currentPlanetFleet: '현재 행성 함대',
|
currentPlanetFleet: '현재 행성 함대',
|
||||||
attack: '공격',
|
attack: '공격',
|
||||||
|
missileAttack: '미사일 공격',
|
||||||
shield: '실드',
|
shield: '실드',
|
||||||
armor: '장갑',
|
armor: '장갑',
|
||||||
speed: '속도',
|
speed: '속도',
|
||||||
@@ -459,6 +479,11 @@ export default {
|
|||||||
arrivalTime: '도착 시간',
|
arrivalTime: '도착 시간',
|
||||||
returnTime: '귀환 시간',
|
returnTime: '귀환 시간',
|
||||||
recallFleet: '함대 소환',
|
recallFleet: '함대 소환',
|
||||||
|
abortMission: '',
|
||||||
|
abortMissionTitle: '',
|
||||||
|
abortMissionWarning: '',
|
||||||
|
abortMissionSuccess: '',
|
||||||
|
abortMissionSuccessMessage: '',
|
||||||
sendFailed: '파견 실패',
|
sendFailed: '파견 실패',
|
||||||
sendFailedMessage: '함대 수, 연료 충분 여부 또는 적재량 한계를 확인하세요.',
|
sendFailedMessage: '함대 수, 연료 충분 여부 또는 적재량 한계를 확인하세요.',
|
||||||
recallFailed: '소환 실패',
|
recallFailed: '소환 실패',
|
||||||
@@ -519,26 +544,37 @@ export default {
|
|||||||
selectSystem: '행성계 선택',
|
selectSystem: '행성계 선택',
|
||||||
view: '보기',
|
view: '보기',
|
||||||
myPlanet: '내 행성',
|
myPlanet: '내 행성',
|
||||||
myPlanets: '내 행성들',
|
myPlanets: '내 행성계 보기',
|
||||||
npcPlanets: 'NPC 행성들',
|
npcPlanets: 'NPC 행성들',
|
||||||
selectPlanetToView: '볼 행성 선택',
|
selectPlanetToView: '행성을 선택하여 행성계 보기',
|
||||||
totalPositions: '총 10개 행성 위치',
|
totalPositions: '총 10개 행성 위치',
|
||||||
mine: '내 것',
|
mine: '내 것',
|
||||||
hostile: '적대',
|
hostile: '적대',
|
||||||
emptySlot: '빈 자리 - 식민 가능',
|
emptySlot: '빈 자리 - 식민 가능',
|
||||||
scout: '정찰',
|
scout: '정찰',
|
||||||
attack: '공격',
|
attack: '공격',
|
||||||
|
missileAttack: '미사일 공격',
|
||||||
colonize: '식민',
|
colonize: '식민',
|
||||||
switch: '전환',
|
switch: '전환',
|
||||||
recycle: '회수',
|
recycle: '회수',
|
||||||
debrisField: '잔해 필드',
|
debrisField: '잔해 필드',
|
||||||
scoutPlanetTitle: '행성 정찰',
|
scoutPlanetTitle: '행성 정찰',
|
||||||
attackPlanetTitle: '행성 공격',
|
attackPlanetTitle: '행성 공격',
|
||||||
|
missileAttackTitle: '미사일 공격',
|
||||||
colonizePlanetTitle: '행성 식민',
|
colonizePlanetTitle: '행성 식민',
|
||||||
recyclePlanetTitle: '잔해 회수',
|
recyclePlanetTitle: '잔해 회수',
|
||||||
scoutPlanetMessage:
|
scoutPlanetMessage:
|
||||||
'행성 [{coordinates}]을(를) 정찰하기 위해 정찰기를 보내시겠습니까?\n\n함대 페이지로 이동하여 함선을 선택하고 파견하세요.',
|
'행성 [{coordinates}]을(를) 정찰하기 위해 정찰기를 보내시겠습니까?\n\n함대 페이지로 이동하여 함선을 선택하고 파견하세요.',
|
||||||
attackPlanetMessage: '행성 [{coordinates}]을(를) 공격하시겠습니까?\n\n함대 페이지로 이동하여 함선을 선택하고 파견하세요.',
|
attackPlanetMessage: '행성 [{coordinates}]을(를) 공격하시겠습니까?\n\n함대 페이지로 이동하여 함선을 선택하고 파견하세요.',
|
||||||
|
missileAttackMessage: '행성 [{coordinates}]에 행성간 미사일 발사',
|
||||||
|
missileCount: '미사일 수량',
|
||||||
|
availableMissiles: '사용 가능한 미사일',
|
||||||
|
missileRange: '미사일 사정거리',
|
||||||
|
systems: '시스템',
|
||||||
|
distance: '거리',
|
||||||
|
flightTime: '비행 시간',
|
||||||
|
launchMissile: '발사',
|
||||||
|
cancel: '취소',
|
||||||
colonizePlanetMessage: '위치 [{coordinates}]을(를) 식민하시겠습니까?\n\n함대 페이지로 이동하여 식민선을 파견하세요.',
|
colonizePlanetMessage: '위치 [{coordinates}]을(를) 식민하시겠습니까?\n\n함대 페이지로 이동하여 식민선을 파견하세요.',
|
||||||
recyclePlanetMessage: '위치 [{coordinates}]의 잔해를 회수하시겠습니까?\n\n함대 페이지로 이동하여 회수선을 파견하세요.',
|
recyclePlanetMessage: '위치 [{coordinates}]의 잔해를 회수하시겠습니까?\n\n함대 페이지로 이동하여 회수선을 파견하세요.',
|
||||||
sendGift: '선물 보내기',
|
sendGift: '선물 보내기',
|
||||||
@@ -551,10 +587,12 @@ export default {
|
|||||||
battles: '전투',
|
battles: '전투',
|
||||||
spy: '정찰',
|
spy: '정찰',
|
||||||
npc: 'NPC',
|
npc: 'NPC',
|
||||||
|
diplomacy: '',
|
||||||
battleReports: '전투 보고서',
|
battleReports: '전투 보고서',
|
||||||
spyReports: '정찰 보고서',
|
spyReports: '정찰 보고서',
|
||||||
noBattleReports: '전투 보고서 없음',
|
noBattleReports: '전투 보고서 없음',
|
||||||
noSpyReports: '정찰 보고서 없음',
|
noSpyReports: '정찰 보고서 없음',
|
||||||
|
noDiplomaticReports: '',
|
||||||
battleReport: '전투 보고서',
|
battleReport: '전투 보고서',
|
||||||
spyReport: '정찰 보고서',
|
spyReport: '정찰 보고서',
|
||||||
victory: '승리',
|
victory: '승리',
|
||||||
@@ -610,7 +648,38 @@ export default {
|
|||||||
hostile: '상대방이 적대적이어서 선물을 받지 않습니다',
|
hostile: '상대방이 적대적이어서 선물을 받지 않습니다',
|
||||||
neutral_distrust: '상대방이 당신을 신뢰하지 않습니다',
|
neutral_distrust: '상대방이 당신을 신뢰하지 않습니다',
|
||||||
polite_decline: '정중하게 거절했습니다'
|
polite_decline: '정중하게 거절했습니다'
|
||||||
}
|
},
|
||||||
|
// Spied notification dialog
|
||||||
|
spiedNotificationDetails: '',
|
||||||
|
spyDetected: '',
|
||||||
|
detectionResult: '',
|
||||||
|
detectionSuccess: '',
|
||||||
|
spiedNotificationMessage: '',
|
||||||
|
spiedNotificationTip: '',
|
||||||
|
viewInGalaxy: '',
|
||||||
|
// Mission report dialog
|
||||||
|
missionReportDetails: '',
|
||||||
|
missionSuccess: '',
|
||||||
|
missionFailed: '',
|
||||||
|
origin: '',
|
||||||
|
destination: '',
|
||||||
|
missionDetails: '',
|
||||||
|
transportedResources: '',
|
||||||
|
recycledResources: '',
|
||||||
|
remainingDebris: '',
|
||||||
|
newPlanet: '',
|
||||||
|
// NPC activity dialog
|
||||||
|
npcActivityDetails: '',
|
||||||
|
activityType: {
|
||||||
|
recycle: ''
|
||||||
|
},
|
||||||
|
activityLocation: '',
|
||||||
|
position: '',
|
||||||
|
nearPlanet: '',
|
||||||
|
activityDescription: '',
|
||||||
|
npcActivityMessage: '',
|
||||||
|
arrivalTime: '',
|
||||||
|
npcActivityTip: ''
|
||||||
},
|
},
|
||||||
missionReports: {
|
missionReports: {
|
||||||
transportSuccess: '수송 임무가 성공적으로 완료되었습니다',
|
transportSuccess: '수송 임무가 성공적으로 완료되었습니다',
|
||||||
@@ -691,10 +760,24 @@ export default {
|
|||||||
gamePaused: '게임이 일시정지되었습니다',
|
gamePaused: '게임이 일시정지되었습니다',
|
||||||
gameResumed: '게임이 재개되었습니다',
|
gameResumed: '게임이 재개되었습니다',
|
||||||
playerName: '플레이어 이름',
|
playerName: '플레이어 이름',
|
||||||
gameSpeed: '게임 속도',
|
gameSpeed: '자원 생산 속도',
|
||||||
gameSpeedDesc: '현재 게임 속도 배율',
|
gameSpeedDesc: '현재 자원 생산 속도 배율',
|
||||||
|
speedChanged: '자원 생산 속도가 {speed}x로 변경되었습니다',
|
||||||
|
speedReset: '자원 생산 속도가 1x로 재설정되었습니다',
|
||||||
|
reset: '재설정',
|
||||||
about: '정보',
|
about: '정보',
|
||||||
version: '버전',
|
version: '버전',
|
||||||
|
latestVersion: '최신 버전',
|
||||||
|
checkUpdate: '업데이트 확인',
|
||||||
|
checking: '확인 중...',
|
||||||
|
newVersionAvailable: '새 버전 {version} 사용 가능',
|
||||||
|
upToDate: '이미 최신 버전입니다',
|
||||||
|
checkUpdateCooldown: '나중에 다시 시도해주세요 (5분 쿨다운)',
|
||||||
|
checkUpdateFailed: '업데이트 확인 실패, 네트워크 연결을 확인하세요',
|
||||||
|
viewUpdate: '업데이트 보기',
|
||||||
|
updateAvailable: '새 버전이 사용 가능합니다. 릴리스 노트를 보려면 클릭하세요.',
|
||||||
|
download: '다운로드',
|
||||||
|
goToDownload: '다운로드로 이동',
|
||||||
buildDate: '빌드 날짜',
|
buildDate: '빌드 날짜',
|
||||||
community: '커뮤니티',
|
community: '커뮤니티',
|
||||||
github: 'GitHub 저장소',
|
github: 'GitHub 저장소',
|
||||||
@@ -713,6 +796,8 @@ export default {
|
|||||||
officers: '장교',
|
officers: '장교',
|
||||||
modifyResources: '자원 수정',
|
modifyResources: '자원 수정',
|
||||||
resourcesDesc: '행성 자원을 빠르게 수정',
|
resourcesDesc: '행성 자원을 빠르게 수정',
|
||||||
|
maxAllResources: '',
|
||||||
|
maxAllResourcesSuccess: '',
|
||||||
modifyBuildings: '건물 수정',
|
modifyBuildings: '건물 수정',
|
||||||
buildingsDesc: '건물 레벨을 빠르게 설정',
|
buildingsDesc: '건물 레벨을 빠르게 설정',
|
||||||
modifyResearch: '연구 수정',
|
modifyResearch: '연구 수정',
|
||||||
@@ -733,16 +818,30 @@ export default {
|
|||||||
testSpy: '정찰 테스트',
|
testSpy: '정찰 테스트',
|
||||||
testAttack: '공격 테스트',
|
testAttack: '공격 테스트',
|
||||||
testSpyAndAttack: '정찰 & 공격 테스트',
|
testSpyAndAttack: '정찰 & 공격 테스트',
|
||||||
initializeFleet: 'NPC 함대 초기화',
|
testSpyMessage: '확인을 클릭하여 정찰 임무를 가속화',
|
||||||
|
testAttackMessage: '확인을 클릭하여 공격 임무를 가속화',
|
||||||
|
testSpyAndAttackMessage: '확인을 클릭하여 임무를 가속화',
|
||||||
|
initializeFleet: 'NPC 함대 초기化',
|
||||||
accelerateMissions: '모든 임무 가속(5초)',
|
accelerateMissions: '모든 임무 가속(5초)',
|
||||||
selectNPCFirst: '먼저 NPC를 선택하세요',
|
selectNPCFirst: '먼저 NPC를 선택하세요',
|
||||||
npcNoProbes: 'NPC에 정찰 프로브가 없습니다',
|
npcNoProbes: 'NPC에 정찰 프로브가 없습니다',
|
||||||
npcNoSpyReport: 'NPC가 먼저 정찰해야 합니다',
|
npcNoSpyReport: 'NPC가 먼저 정찰해야 합니다',
|
||||||
npcMissionFailed: '임무 생성 실패',
|
npcMissionFailed: '임무 생성 실패',
|
||||||
|
npcNoPlanets: 'NPC에 행성이 없습니다',
|
||||||
|
npcWillSpyIn5s: '{npcName}이(가) 5초 후에 정찰합니다',
|
||||||
|
npcWillAttackIn5s: '{npcName}이(가) 5초 후에 공격합니다',
|
||||||
|
npcWillSpyAndAttack: '{npcName}이(가) 5초 후에 정찰하고 10초 후에 공격합니다',
|
||||||
|
acceleratedMissions: '{count}개의 임무를 5초로 가속화했습니다',
|
||||||
|
npcFleetInitialized: '{npcName} 함대가 초기화되었습니다',
|
||||||
|
npcFleetDetails: '100 정찰 프로브\n500 경전투기\n300 중전투기\n200 순양함\n100 전함\n50 폭격기\n30 구축함\n20 순양전함',
|
||||||
dangerZone: '위험 구역',
|
dangerZone: '위험 구역',
|
||||||
dangerZoneDesc: '다음 작업은 되돌릴 수 없습니다',
|
dangerZoneDesc: '다음 작업은 되돌릴 수 없습니다',
|
||||||
resetGame: '게임 초기화',
|
resetGame: '게임 초기화',
|
||||||
resetGameConfirm: '게임을 초기화하시겠습니까? 모든 데이터가 삭제됩니다!'
|
resetGameConfirm: '게임을 초기화하시겠습니까? 모든 데이터가 삭제됩니다!',
|
||||||
|
completeAllQueues: '',
|
||||||
|
completeAllQueuesDesc: '',
|
||||||
|
completeQueues: '',
|
||||||
|
completeQueuesSuccess: ''
|
||||||
},
|
},
|
||||||
alerts: {
|
alerts: {
|
||||||
npcSpyIncoming: 'NPC 정찰 프로브 접근 중',
|
npcSpyIncoming: 'NPC 정찰 프로브 접근 중',
|
||||||
@@ -772,6 +871,10 @@ export default {
|
|||||||
recentEvents: '최근 이벤트',
|
recentEvents: '최근 이벤트',
|
||||||
recentEventsDescription: '최근 외교 활동 로그',
|
recentEventsDescription: '최근 외교 활동 로그',
|
||||||
ago: '전',
|
ago: '전',
|
||||||
|
notifications: '',
|
||||||
|
markAllRead: '',
|
||||||
|
noReports: '',
|
||||||
|
viewAll: '',
|
||||||
status: {
|
status: {
|
||||||
friendly: '우호적',
|
friendly: '우호적',
|
||||||
neutral: '중립',
|
neutral: '중립',
|
||||||
@@ -787,19 +890,96 @@ export default {
|
|||||||
viewPlanets: '행성 보기'
|
viewPlanets: '행성 보기'
|
||||||
},
|
},
|
||||||
lastEvent: '최근 이벤트',
|
lastEvent: '최근 이벤트',
|
||||||
|
reportDetails: '',
|
||||||
|
eventDescription: '',
|
||||||
|
reputationChange: '',
|
||||||
|
before: '',
|
||||||
|
after: '',
|
||||||
|
statusChange: '',
|
||||||
|
viewDiplomacy: '',
|
||||||
events: {
|
events: {
|
||||||
gift: '선물 전송',
|
gift: '선물 전송',
|
||||||
attack: '공격',
|
attack: '공격',
|
||||||
|
missileAttack: '미사일 공격',
|
||||||
allyAttacked: '동맹 공격당함',
|
allyAttacked: '동맹 공격당함',
|
||||||
spy: '정찰',
|
spy: '정찰',
|
||||||
stealDebris: '잔해 약탈'
|
stealDebris: '잔해 약탈'
|
||||||
|
},
|
||||||
|
reports: {
|
||||||
|
giftedResources: '{metal}M {crystal}C {deuterium}D 선물함',
|
||||||
|
receivedGiftFromPlayer: '플레이어로부터 선물을 받았습니다',
|
||||||
|
giftedToNpc: '{npcName}에게 자원을 선물했습니다. 평판 +{reputation}',
|
||||||
|
rejectedPlayerGift: '플레이어의 선물을 거부했습니다',
|
||||||
|
npcRejectedGift: '{npcName}이(가) 당신의 선물을 거부했습니다. 평판 {reputation}',
|
||||||
|
attackedNpc: '{npcName}을(를) 공격했습니다',
|
||||||
|
wasAttackedByPlayer: '플레이어에게 공격당했습니다',
|
||||||
|
youAttackedNpc: '당신은 {npcName}을(를) 공격했습니다',
|
||||||
|
playerAttackedAlly: '플레이어가 동맹 {allyName}을(를) 공격했습니다',
|
||||||
|
allyDispleased: '{allyName}은(는) 당신이 동맹 {targetName}을(를) 공격한 것에 불만입니다',
|
||||||
|
wasSpiedByPlayer: '플레이어에게 정찰당했습니다 (발견: {detected})',
|
||||||
|
spyDetected: '당신의 정찰이 {npcName}에게 발견되었습니다',
|
||||||
|
stoleDebrisFromTerritory: '{npcName}의 영역에서 잔해를 약탈했습니다',
|
||||||
|
playerStoleDebris: '플레이어가 영역에서 잔해를 약탈했습니다',
|
||||||
|
recycledDebrisNearNpc: '{npcName}의 행성 근처에서 잔해를 수집했습니다. 그들은 불만족스러워합니다.',
|
||||||
|
giftedResourcesToPlayer: '플레이어에게 자원을 선물했습니다',
|
||||||
|
receivedGiftFromNpc: '{npcName}로부터 선물을 받았습니다',
|
||||||
|
acceptedGiftFromNpc: '{npcName}의 선물을 받았습니다: {metal}M {crystal}C {deuterium}D',
|
||||||
|
playerRejectedGift: '플레이어가 선물을 거부했습니다',
|
||||||
|
rejectedGiftFromNpc: '{npcName}의 선물을 거부했습니다. 평판 {reputation}',
|
||||||
|
destroyedNpcPlanet: '{npcName}의 {planetName}을(를) 파괴했습니다',
|
||||||
|
playerDestroyedPlanet: '플레이어가 {planetName}을(를) 파괴했습니다',
|
||||||
|
youDestroyedNpcPlanet: '당신은 {npcName}의 {planetName}을(를) 파괴했습니다. 평판 {reputation}',
|
||||||
|
playerDestroyedAllyPlanet: '플레이어가 동맹 {allyName}의 {planetName}을(를) 파괴했습니다',
|
||||||
|
allyOutraged: '{allyName}은(는) 당신이 동맹 {targetName}의 {planetName}을(를) 파괴한 것에 분노하고 있습니다',
|
||||||
|
npcEliminated: 'NPC {npcName}이(가) 완전히 제거되었습니다',
|
||||||
|
npcEliminatedMessage: '당신은 {npcName}의 모든 행성을 파괴했습니다! 이 세력은 완전히 소멸되었습니다.'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pagination: {
|
pagination: {
|
||||||
previous: '이전',
|
previous: '이전',
|
||||||
next: '다음',
|
next: '다음',
|
||||||
|
gotIt: '',
|
||||||
first: '처음',
|
first: '처음',
|
||||||
last: '마지막',
|
last: '마지막',
|
||||||
page: '{page}페이지'
|
page: '{page}페이지'
|
||||||
|
},
|
||||||
|
notFound: {
|
||||||
|
title: '페이지를 찾을 수 없습니다',
|
||||||
|
description: '죄송합니다. 찾으시는 페이지가 존재하지 않습니다',
|
||||||
|
goHome: '홈으로 이동'
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
days: '일',
|
||||||
|
hours: '시간',
|
||||||
|
minutes: '분',
|
||||||
|
seconds: '초'
|
||||||
|
},
|
||||||
|
tutorial: {
|
||||||
|
welcome: {
|
||||||
|
title: 'OGame에 오신 것을 환영합니다',
|
||||||
|
content: '환영합니다, 사령관! 기초부터 시작하여 우주 제국을 건설해 봅시다.'
|
||||||
|
},
|
||||||
|
buildSolarPlant: {
|
||||||
|
title: '태양광 발전소 건설',
|
||||||
|
content:
|
||||||
|
'먼저 태양광 발전소를 건설하세요! 행성에 에너지를 공급합니다. 에너지가 없으면 다른 자원 건물이 작동할 수 없습니다. 가장 중요한 첫 단계입니다.'
|
||||||
|
},
|
||||||
|
waitBuild: {
|
||||||
|
title: '건설 대기열',
|
||||||
|
content:
|
||||||
|
'건물이 건설 대기열에 추가되었습니다. 오른쪽 상단의 대기열 아이콘을 클릭하면 진행 중인 모든 건설 및 연구 작업을 확인할 수 있습니다. 건설에는 시간이 걸리지만 대기하는 동안 계속 작업할 수 있습니다.'
|
||||||
|
},
|
||||||
|
mobile: {
|
||||||
|
welcome: {
|
||||||
|
title: 'OGame에 오신 것을 환영합니다 (모바일)',
|
||||||
|
content:
|
||||||
|
'환영합니다, 사령관! 터치스크린용으로 설계된 간소화된 튜토리얼입니다. 제국 건설을 시작할 수 있도록 핵심 기능을 빠르게 소개하겠습니다.'
|
||||||
|
},
|
||||||
|
waitBuild: {
|
||||||
|
title: '건설 대기열',
|
||||||
|
content:
|
||||||
|
'오른쪽 상단의 대기열 아이콘을 클릭하여 건설 진행 상황을 확인하세요. 다른 페이지를 계속 탐색할 수 있으며, 건설은 백그라운드에서 진행됩니다.'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export default {
|
|||||||
close: 'Закрыть',
|
close: 'Закрыть',
|
||||||
back: 'Назад',
|
back: 'Назад',
|
||||||
next: 'Далее',
|
next: 'Далее',
|
||||||
|
gotIt: '',
|
||||||
previous: 'Предыдущий',
|
previous: 'Предыдущий',
|
||||||
submit: 'Отправить',
|
submit: 'Отправить',
|
||||||
reset: 'Сбросить',
|
reset: 'Сбросить',
|
||||||
@@ -33,13 +34,19 @@ export default {
|
|||||||
viewRequirements: 'Просмотр требований',
|
viewRequirements: 'Просмотр требований',
|
||||||
requirementsNotMet: 'Требования не выполнены',
|
requirementsNotMet: 'Требования не выполнены',
|
||||||
current: 'Текущий',
|
current: 'Текущий',
|
||||||
level: 'Уровень'
|
level: 'Уровень',
|
||||||
|
gmModeActivated: 'Режим GM активирован! Проверьте навигационное меню.'
|
||||||
},
|
},
|
||||||
errors: {
|
errors: {
|
||||||
requirementsNotMet: 'Требования не выполнены',
|
requirementsNotMet: 'Требования не выполнены',
|
||||||
insufficientResources: 'Недостаточно ресурсов',
|
insufficientResources: 'Недостаточно ресурсов',
|
||||||
insufficientFleetStorage: 'Недостаточно места для флота',
|
insufficientFleetStorage: 'Недостаточно места для флота',
|
||||||
shieldDomeLimit: 'Достигнут лимит щитовых куполов',
|
shieldDomeLimit: 'Достигнут лимит щитовых куполов',
|
||||||
|
missileSiloLimit: 'Превышена вместимость ракетной шахты',
|
||||||
|
insufficientMissiles: 'Недостаточно межпланетных ракет',
|
||||||
|
invalidMissileCount: 'Неверное количество ракет',
|
||||||
|
targetOutOfRange: 'Цель вне дальности',
|
||||||
|
cannotAttackOwnPlanet: 'Нельзя атаковать свою планету',
|
||||||
fleetMissionsFull: 'Слоты миссий флота заполнены',
|
fleetMissionsFull: 'Слоты миссий флота заполнены',
|
||||||
insufficientFleet: 'Недостаточно флота',
|
insufficientFleet: 'Недостаточно флота',
|
||||||
insufficientFuel: 'Недостаточно топлива',
|
insufficientFuel: 'Недостаточно топлива',
|
||||||
@@ -119,6 +126,7 @@ export default {
|
|||||||
roboticsFactory: 'Фабрика роботов',
|
roboticsFactory: 'Фабрика роботов',
|
||||||
naniteFactory: 'Нанитная фабрика',
|
naniteFactory: 'Нанитная фабрика',
|
||||||
shipyard: 'Верфь',
|
shipyard: 'Верфь',
|
||||||
|
hangar: 'Ангар',
|
||||||
researchLab: 'Исследовательская лаборатория',
|
researchLab: 'Исследовательская лаборатория',
|
||||||
metalStorage: 'Хранилище металла',
|
metalStorage: 'Хранилище металла',
|
||||||
crystalStorage: 'Хранилище кристалла',
|
crystalStorage: 'Хранилище кристалла',
|
||||||
@@ -159,6 +167,7 @@ export default {
|
|||||||
roboticsFactory: 'Ускоряет скорость строительства',
|
roboticsFactory: 'Ускоряет скорость строительства',
|
||||||
naniteFactory: 'Увеличивает вместимость очереди строительства, +1 за уровень (макс 10 уровней)',
|
naniteFactory: 'Увеличивает вместимость очереди строительства, +1 за уровень (макс 10 уровней)',
|
||||||
shipyard: 'Строит корабли',
|
shipyard: 'Строит корабли',
|
||||||
|
hangar: 'Специализированное сооружение для расширения вместимости флота, поддерживает специализацию планет',
|
||||||
researchLab: 'Исследует технологии',
|
researchLab: 'Исследует технологии',
|
||||||
metalStorage: 'Увеличивает ёмкость хранилища металла',
|
metalStorage: 'Увеличивает ёмкость хранилища металла',
|
||||||
crystalStorage: 'Увеличивает ёмкость хранилища кристалла',
|
crystalStorage: 'Увеличивает ёмкость хранилища кристалла',
|
||||||
@@ -166,8 +175,8 @@ export default {
|
|||||||
darkMatterCollector: 'Собирает редкие ресурсы тёмной материи',
|
darkMatterCollector: 'Собирает редкие ресурсы тёмной материи',
|
||||||
darkMatterTank: 'Увеличивает ёмкость хранилища тёмной материи',
|
darkMatterTank: 'Увеличивает ёмкость хранилища тёмной материи',
|
||||||
missileSilo: 'Хранит и запускает ракеты, 10 ракет на уровень',
|
missileSilo: 'Хранит и запускает ракеты, 10 ракет на уровень',
|
||||||
terraformer: 'Терраформирует поверхность планеты, увеличивает доступное пространство на 5 за уровень',
|
terraformer: 'Терраформирует поверхность планеты, увеличивает доступное пространство на 30 за уровень',
|
||||||
lunarBase: 'Увеличивает доступное пространство на луне, +5 пространства за уровень',
|
lunarBase: 'Увеличивает доступное пространство на луне, +30 пространства за уровень',
|
||||||
sensorPhalanx: 'Обнаруживает активность флота в окружающих системах',
|
sensorPhalanx: 'Обнаруживает активность флота в окружающих системах',
|
||||||
jumpGate: 'Мгновенно переносит флоты на другие луны',
|
jumpGate: 'Мгновенно переносит флоты на другие луны',
|
||||||
planetDestroyerFactory: 'Производит абсолютное оружие, способное уничтожать планеты'
|
planetDestroyerFactory: 'Производит абсолютное оружие, способное уничтожать планеты'
|
||||||
@@ -193,10 +202,10 @@ export default {
|
|||||||
lightFighter: 'Базовая боевая единица',
|
lightFighter: 'Базовая боевая единица',
|
||||||
heavyFighter: 'Тяжелобронированный истребитель',
|
heavyFighter: 'Тяжелобронированный истребитель',
|
||||||
cruiser: 'Средний боевой корабль, сбалансированная атака и защита',
|
cruiser: 'Средний боевой корабль, сбалансированная атака и защита',
|
||||||
battleship: 'Мощный боевой корабль',
|
battleship: 'Основной тяжёлый боевой корабль с мощной огневой мощью и высокой защитой',
|
||||||
battlecruiser: 'Быстрый мощный боевой корабль, отлично атакует линкоры',
|
battlecruiser: 'Быстрый мощный боевой корабль, отлично атакует линкоры',
|
||||||
bomber: 'Специализированный корабль для атаки оборонительных сооружений',
|
bomber: 'Специализированный корабль для атаки оборонительных сооружений',
|
||||||
destroyer: 'Охотник, специализирующийся на уничтожении крупных кораблей',
|
destroyer: 'Специализированный противокапитальный корабль с высокой огневой мощью, но низкой защитой',
|
||||||
smallCargo: 'Транспортирует небольшое количество ресурсов',
|
smallCargo: 'Транспортирует небольшое количество ресурсов',
|
||||||
largeCargo: 'Транспортирует большое количество ресурсов',
|
largeCargo: 'Транспортирует большое количество ресурсов',
|
||||||
colonyShip: 'Используется для колонизации новых планет',
|
colonyShip: 'Используется для колонизации новых планет',
|
||||||
@@ -284,7 +293,7 @@ export default {
|
|||||||
hyperspaceDrive: 'Продвинутая технология двигателей',
|
hyperspaceDrive: 'Продвинутая технология двигателей',
|
||||||
darkMatterTechnology: 'Исследование свойств и применения тёмной материи',
|
darkMatterTechnology: 'Исследование свойств и применения тёмной материи',
|
||||||
terraformingTechnology:
|
terraformingTechnology:
|
||||||
'Исследование технологии терраформирования планет, увеличивает доступное пространство всех планет на 3 за уровень',
|
'Исследование технологии терраформирования планет, увеличивает доступное пространство всех планет на 30 за уровень',
|
||||||
planetDestructionTech: 'Исследование ужасающей технологии уничтожения целых планет'
|
planetDestructionTech: 'Исследование ужасающей технологии уничтожения целых планет'
|
||||||
},
|
},
|
||||||
officers: {
|
officers: {
|
||||||
@@ -307,16 +316,20 @@ export default {
|
|||||||
darkMatterSpecialist: 'Улучшает эффективность сбора тёмной материи'
|
darkMatterSpecialist: 'Улучшает эффективность сбора тёмной материи'
|
||||||
},
|
},
|
||||||
queue: {
|
queue: {
|
||||||
|
title: 'Очередь строительства',
|
||||||
|
empty: 'Нет активных задач',
|
||||||
buildQueue: 'Очередь строительства',
|
buildQueue: 'Очередь строительства',
|
||||||
researchQueue: 'Очередь исследований',
|
researchQueue: 'Очередь исследований',
|
||||||
building: 'Строится',
|
building: 'Строится',
|
||||||
researching: 'Исследуется',
|
researching: 'Исследуется',
|
||||||
|
demolishing: 'Сносится',
|
||||||
remaining: 'Осталось',
|
remaining: 'Осталось',
|
||||||
cancel: 'Отменить',
|
cancel: 'Отменить',
|
||||||
cancelBuild: 'Отменить строительство',
|
cancelBuild: 'Отменить строительство',
|
||||||
cancelResearch: 'Отменить исследование',
|
cancelResearch: 'Отменить исследование',
|
||||||
confirmCancel: 'Вы уверены, что хотите отменить? 50% ресурсов будет возвращено.',
|
confirmCancel: 'Вы уверены, что хотите отменить? 50% ресурсов будет возвращено.',
|
||||||
level: 'Уровень',
|
level: 'Уровень',
|
||||||
|
gmModeActivated: '',
|
||||||
upgradeToLevel: 'Улучшить до уровня'
|
upgradeToLevel: 'Улучшить до уровня'
|
||||||
},
|
},
|
||||||
overview: {
|
overview: {
|
||||||
@@ -337,6 +350,7 @@ export default {
|
|||||||
usedSpace: 'Использовано полей',
|
usedSpace: 'Использовано полей',
|
||||||
spaceUsage: 'Использование полей',
|
spaceUsage: 'Использование полей',
|
||||||
level: 'Уровень',
|
level: 'Уровень',
|
||||||
|
gmModeActivated: '',
|
||||||
upgradeCost: 'Стоимость улучшения',
|
upgradeCost: 'Стоимость улучшения',
|
||||||
buildTime: 'Время строительства',
|
buildTime: 'Время строительства',
|
||||||
upgrade: 'Улучшить',
|
upgrade: 'Улучшить',
|
||||||
@@ -348,8 +362,8 @@ export default {
|
|||||||
demolishRefund: 'Возврат от сноса',
|
demolishRefund: 'Возврат от сноса',
|
||||||
demolishFailed: 'Снос не удался',
|
demolishFailed: 'Снос не удался',
|
||||||
demolishFailedMessage: 'Невозможно снести это здание. Проверьте, не заполнена ли очередь строительства или уровень здания не равен 0.',
|
demolishFailedMessage: 'Невозможно снести это здание. Проверьте, не заполнена ли очередь строительства или уровень здания не равен 0.',
|
||||||
confirmDemolish: '',
|
confirmDemolish: 'Подтвердить снос',
|
||||||
confirmDemolishMessage: ''
|
confirmDemolishMessage: 'Вы уверены, что хотите снести следующее здание?'
|
||||||
},
|
},
|
||||||
researchView: {
|
researchView: {
|
||||||
title: 'Исследования',
|
title: 'Исследования',
|
||||||
@@ -362,6 +376,7 @@ export default {
|
|||||||
},
|
},
|
||||||
shipyard: {
|
shipyard: {
|
||||||
attack: 'Атака',
|
attack: 'Атака',
|
||||||
|
missileAttack: 'Ракетная атака',
|
||||||
shield: 'Щит',
|
shield: 'Щит',
|
||||||
armor: 'Броня',
|
armor: 'Броня',
|
||||||
speed: 'Скорость',
|
speed: 'Скорость',
|
||||||
@@ -379,6 +394,7 @@ export default {
|
|||||||
title: 'Верфь',
|
title: 'Верфь',
|
||||||
fleetStorage: 'Хранилище флота',
|
fleetStorage: 'Хранилище флота',
|
||||||
attack: 'Атака',
|
attack: 'Атака',
|
||||||
|
missileAttack: 'Ракетная атака',
|
||||||
shield: 'Щит',
|
shield: 'Щит',
|
||||||
speed: 'Скорость',
|
speed: 'Скорость',
|
||||||
cargoCapacity: 'Грузоподъёмность',
|
cargoCapacity: 'Грузоподъёмность',
|
||||||
@@ -393,6 +409,7 @@ export default {
|
|||||||
},
|
},
|
||||||
defense: {
|
defense: {
|
||||||
attack: 'Атака',
|
attack: 'Атака',
|
||||||
|
missileAttack: 'Ракетная атака',
|
||||||
shield: 'Щит',
|
shield: 'Щит',
|
||||||
armor: 'Броня',
|
armor: 'Броня',
|
||||||
buildCost: 'Стоимость постройки',
|
buildCost: 'Стоимость постройки',
|
||||||
@@ -406,6 +423,7 @@ export default {
|
|||||||
defenseView: {
|
defenseView: {
|
||||||
title: 'Оборона',
|
title: 'Оборона',
|
||||||
attack: 'Атака',
|
attack: 'Атака',
|
||||||
|
missileAttack: 'Ракетная атака',
|
||||||
shield: 'Щит',
|
shield: 'Щит',
|
||||||
armor: 'Броня',
|
armor: 'Броня',
|
||||||
buildTime: 'Время постройки',
|
buildTime: 'Время постройки',
|
||||||
@@ -415,6 +433,7 @@ export default {
|
|||||||
totalCost: 'Общая стоимость',
|
totalCost: 'Общая стоимость',
|
||||||
build: 'Построить',
|
build: 'Построить',
|
||||||
shieldDomeBuilt: 'Щитовой купол уже построен',
|
shieldDomeBuilt: 'Щитовой купол уже построен',
|
||||||
|
missileCapacity: 'Вместимость ракет',
|
||||||
inputError: 'Ошибка ввода',
|
inputError: 'Ошибка ввода',
|
||||||
inputErrorMessage: 'Пожалуйста, введите количество для постройки!',
|
inputErrorMessage: 'Пожалуйста, введите количество для постройки!',
|
||||||
buildFailed: 'Постройка не удалась',
|
buildFailed: 'Постройка не удалась',
|
||||||
@@ -428,6 +447,7 @@ export default {
|
|||||||
flightMissions: 'Полетные миссии',
|
flightMissions: 'Полетные миссии',
|
||||||
currentPlanetFleet: 'Флот на этой планете',
|
currentPlanetFleet: 'Флот на этой планете',
|
||||||
attack: 'Атака',
|
attack: 'Атака',
|
||||||
|
missileAttack: 'Ракетная атака',
|
||||||
shield: 'Щит',
|
shield: 'Щит',
|
||||||
armor: 'Броня',
|
armor: 'Броня',
|
||||||
speed: 'Скорость',
|
speed: 'Скорость',
|
||||||
@@ -462,6 +482,11 @@ export default {
|
|||||||
arrivalTime: 'Время прибытия',
|
arrivalTime: 'Время прибытия',
|
||||||
returnTime: 'Время возврата',
|
returnTime: 'Время возврата',
|
||||||
recallFleet: 'Отозвать флот',
|
recallFleet: 'Отозвать флот',
|
||||||
|
abortMission: '',
|
||||||
|
abortMissionTitle: '',
|
||||||
|
abortMissionWarning: '',
|
||||||
|
abortMissionSuccess: '',
|
||||||
|
abortMissionSuccessMessage: '',
|
||||||
sendFailed: 'Отправка не удалась',
|
sendFailed: 'Отправка не удалась',
|
||||||
sendFailedMessage: 'Пожалуйста, проверьте количество флота, наличие топлива или ограничения грузоподъёмности.',
|
sendFailedMessage: 'Пожалуйста, проверьте количество флота, наличие топлива или ограничения грузоподъёмности.',
|
||||||
recallFailed: 'Отзыв не удался',
|
recallFailed: 'Отзыв не удался',
|
||||||
@@ -522,27 +547,38 @@ export default {
|
|||||||
selectSystem: 'Выбрать систему',
|
selectSystem: 'Выбрать систему',
|
||||||
view: 'Показать',
|
view: 'Показать',
|
||||||
myPlanet: 'Моя планета',
|
myPlanet: 'Моя планета',
|
||||||
myPlanets: 'Мои планеты',
|
myPlanets: 'Просмотр моих систем',
|
||||||
npcPlanets: 'Планеты NPC',
|
npcPlanets: 'Планеты NPC',
|
||||||
selectPlanetToView: 'Выберите планету для просмотра',
|
selectPlanetToView: 'Выберите планету для просмотра её системы',
|
||||||
totalPositions: 'Всего 10 позиций планет',
|
totalPositions: 'Всего 10 позиций планет',
|
||||||
mine: 'Моя',
|
mine: 'Моя',
|
||||||
hostile: 'Враждебная',
|
hostile: 'Враждебная',
|
||||||
emptySlot: 'Пусто - можно колонизировать',
|
emptySlot: 'Пусто - можно колонизировать',
|
||||||
scout: 'Разведка',
|
scout: 'Разведка',
|
||||||
attack: 'Атака',
|
attack: 'Атака',
|
||||||
|
missileAttack: 'Ракетная атака',
|
||||||
colonize: 'Колонизация',
|
colonize: 'Колонизация',
|
||||||
switch: 'Переключить',
|
switch: 'Переключить',
|
||||||
recycle: 'Переработка',
|
recycle: 'Переработка',
|
||||||
debrisField: 'Поле обломков',
|
debrisField: 'Поле обломков',
|
||||||
scoutPlanetTitle: 'Разведать планету',
|
scoutPlanetTitle: 'Разведать планету',
|
||||||
attackPlanetTitle: 'Атаковать планету',
|
attackPlanetTitle: 'Атаковать планету',
|
||||||
|
missileAttackTitle: 'Ракетная атака',
|
||||||
colonizePlanetTitle: 'Колонизировать планету',
|
colonizePlanetTitle: 'Колонизировать планету',
|
||||||
recyclePlanetTitle: 'Переработать обломки',
|
recyclePlanetTitle: 'Переработать обломки',
|
||||||
scoutPlanetMessage:
|
scoutPlanetMessage:
|
||||||
'Вы уверены, что хотите отправить шпионские зонды для разведки планеты [{coordinates}]?\n\nПерейдите на страницу флота, чтобы выбрать корабли и отправить.',
|
'Вы уверены, что хотите отправить шпионские зонды для разведки планеты [{coordinates}]?\n\nПерейдите на страницу флота, чтобы выбрать корабли и отправить.',
|
||||||
attackPlanetMessage:
|
attackPlanetMessage:
|
||||||
'Вы уверены, что хотите атаковать планету [{coordinates}]?\n\nПерейдите на страницу флота, чтобы выбрать корабли и отправить.',
|
'Вы уверены, что хотите атаковать планету [{coordinates}]?\n\nПерейдите на страницу флота, чтобы выбрать корабли и отправить.',
|
||||||
|
missileAttackMessage: 'Запустить межпланетные ракеты по планете [{coordinates}]',
|
||||||
|
missileCount: 'Количество ракет',
|
||||||
|
availableMissiles: 'Доступно ракет',
|
||||||
|
missileRange: 'Дальность ракет',
|
||||||
|
systems: 'систем',
|
||||||
|
distance: 'Расстояние',
|
||||||
|
flightTime: 'Время полета',
|
||||||
|
launchMissile: 'Запустить',
|
||||||
|
cancel: 'Отмена',
|
||||||
colonizePlanetMessage:
|
colonizePlanetMessage:
|
||||||
'Вы уверены, что хотите колонизировать позицию [{coordinates}]?\n\nПерейдите на страницу флота, чтобы отправить колонизационный корабль.',
|
'Вы уверены, что хотите колонизировать позицию [{coordinates}]?\n\nПерейдите на страницу флота, чтобы отправить колонизационный корабль.',
|
||||||
recyclePlanetMessage:
|
recyclePlanetMessage:
|
||||||
@@ -558,10 +594,12 @@ export default {
|
|||||||
battles: 'Битвы',
|
battles: 'Битвы',
|
||||||
spy: 'Разведка',
|
spy: 'Разведка',
|
||||||
npc: 'NPC',
|
npc: 'NPC',
|
||||||
|
diplomacy: '',
|
||||||
battleReports: 'Отчёты о боях',
|
battleReports: 'Отчёты о боях',
|
||||||
spyReports: 'Отчёты разведки',
|
spyReports: 'Отчёты разведки',
|
||||||
noBattleReports: 'Нет отчётов о боях',
|
noBattleReports: 'Нет отчётов о боях',
|
||||||
noSpyReports: 'Нет отчётов разведки',
|
noSpyReports: 'Нет отчётов разведки',
|
||||||
|
noDiplomaticReports: '',
|
||||||
battleReport: 'Отчёт о бое',
|
battleReport: 'Отчёт о бое',
|
||||||
spyReport: 'Отчёт разведки',
|
spyReport: 'Отчёт разведки',
|
||||||
victory: 'Победа',
|
victory: 'Победа',
|
||||||
@@ -617,7 +655,38 @@ export default {
|
|||||||
hostile: 'Они враждебны и не принимают подарки',
|
hostile: 'Они враждебны и не принимают подарки',
|
||||||
neutral_distrust: 'Они вам не доверяют',
|
neutral_distrust: 'Они вам не доверяют',
|
||||||
polite_decline: 'Вежливо отказались'
|
polite_decline: 'Вежливо отказались'
|
||||||
}
|
},
|
||||||
|
// Spied notification dialog
|
||||||
|
spiedNotificationDetails: '',
|
||||||
|
spyDetected: '',
|
||||||
|
detectionResult: '',
|
||||||
|
detectionSuccess: '',
|
||||||
|
spiedNotificationMessage: '',
|
||||||
|
spiedNotificationTip: '',
|
||||||
|
viewInGalaxy: '',
|
||||||
|
// Mission report dialog
|
||||||
|
missionReportDetails: '',
|
||||||
|
missionSuccess: '',
|
||||||
|
missionFailed: '',
|
||||||
|
origin: '',
|
||||||
|
destination: '',
|
||||||
|
missionDetails: '',
|
||||||
|
transportedResources: '',
|
||||||
|
recycledResources: '',
|
||||||
|
remainingDebris: '',
|
||||||
|
newPlanet: '',
|
||||||
|
// NPC activity dialog
|
||||||
|
npcActivityDetails: '',
|
||||||
|
activityType: {
|
||||||
|
recycle: ''
|
||||||
|
},
|
||||||
|
activityLocation: '',
|
||||||
|
position: '',
|
||||||
|
nearPlanet: '',
|
||||||
|
activityDescription: '',
|
||||||
|
npcActivityMessage: '',
|
||||||
|
arrivalTime: '',
|
||||||
|
npcActivityTip: ''
|
||||||
},
|
},
|
||||||
missionReports: {
|
missionReports: {
|
||||||
transportSuccess: 'Миссия транспортировки успешно завершена',
|
transportSuccess: 'Миссия транспортировки успешно завершена',
|
||||||
@@ -698,10 +767,24 @@ export default {
|
|||||||
gamePaused: 'Игра приостановлена',
|
gamePaused: 'Игра приостановлена',
|
||||||
gameResumed: 'Игра возобновлена',
|
gameResumed: 'Игра возобновлена',
|
||||||
playerName: 'Имя игрока',
|
playerName: 'Имя игрока',
|
||||||
gameSpeed: 'Скорость игры',
|
gameSpeed: 'Скорость производства ресурсов',
|
||||||
gameSpeedDesc: 'Текущий множитель скорости игры',
|
gameSpeedDesc: 'Текущий множитель скорости производства ресурсов',
|
||||||
|
speedChanged: 'Скорость производства ресурсов изменена на {speed}x',
|
||||||
|
speedReset: 'Скорость производства ресурсов сброшена на 1x',
|
||||||
|
reset: 'Сбросить',
|
||||||
about: 'О программе',
|
about: 'О программе',
|
||||||
version: 'Версия',
|
version: 'Версия',
|
||||||
|
latestVersion: 'Последняя версия',
|
||||||
|
checkUpdate: 'Проверить обновление',
|
||||||
|
checking: 'Проверка...',
|
||||||
|
newVersionAvailable: 'Доступна новая версия {version}',
|
||||||
|
upToDate: 'Уже актуальная версия',
|
||||||
|
checkUpdateCooldown: 'Пожалуйста, попробуйте позже (5 минут перезарядки)',
|
||||||
|
checkUpdateFailed: 'Не удалось проверить обновления, проверьте подключение к Интернету',
|
||||||
|
viewUpdate: 'Просмотреть обновление',
|
||||||
|
updateAvailable: 'Доступна новая версия. Нажмите, чтобы просмотреть примечания к выпуску.',
|
||||||
|
download: 'Скачать',
|
||||||
|
goToDownload: 'Перейти к загрузке',
|
||||||
buildDate: 'Дата сборки',
|
buildDate: 'Дата сборки',
|
||||||
community: 'Сообщество',
|
community: 'Сообщество',
|
||||||
github: 'Репозиторий GitHub',
|
github: 'Репозиторий GitHub',
|
||||||
@@ -720,6 +803,8 @@ export default {
|
|||||||
officers: 'Офицеры',
|
officers: 'Офицеры',
|
||||||
modifyResources: 'Изменить ресурсы',
|
modifyResources: 'Изменить ресурсы',
|
||||||
resourcesDesc: 'Быстрое изменение ресурсов планеты',
|
resourcesDesc: 'Быстрое изменение ресурсов планеты',
|
||||||
|
maxAllResources: '',
|
||||||
|
maxAllResourcesSuccess: '',
|
||||||
modifyBuildings: 'Изменить здания',
|
modifyBuildings: 'Изменить здания',
|
||||||
buildingsDesc: 'Быстрая установка уровней зданий',
|
buildingsDesc: 'Быстрая установка уровней зданий',
|
||||||
modifyResearch: 'Изменить исследования',
|
modifyResearch: 'Изменить исследования',
|
||||||
@@ -740,16 +825,31 @@ export default {
|
|||||||
testSpy: 'Тест разведки',
|
testSpy: 'Тест разведки',
|
||||||
testAttack: 'Тест атаки',
|
testAttack: 'Тест атаки',
|
||||||
testSpyAndAttack: 'Тест разведки и атаки',
|
testSpyAndAttack: 'Тест разведки и атаки',
|
||||||
|
testSpyMessage: 'Нажмите подтвердить, чтобы ускорить миссию разведки',
|
||||||
|
testAttackMessage: 'Нажмите подтвердить, чтобы ускорить миссию атаки',
|
||||||
|
testSpyAndAttackMessage: 'Нажмите подтвердить, чтобы ускорить миссии',
|
||||||
initializeFleet: 'Инициализировать флот NPC',
|
initializeFleet: 'Инициализировать флот NPC',
|
||||||
accelerateMissions: 'Ускорить все миссии (5с)',
|
accelerateMissions: 'Ускорить все миссии (5с)',
|
||||||
selectNPCFirst: 'Сначала выберите NPC',
|
selectNPCFirst: 'Сначала выберите NPC',
|
||||||
npcNoProbes: 'У NPC нет шпионских зондов',
|
npcNoProbes: 'У NPC нет шпионских зондов',
|
||||||
npcNoSpyReport: 'NPC нужно сначала разведать',
|
npcNoSpyReport: 'NPC нужно сначала разведать',
|
||||||
npcMissionFailed: 'Не удалось создать миссию',
|
npcMissionFailed: 'Не удалось создать миссию',
|
||||||
|
npcNoPlanets: 'У NPC нет планет',
|
||||||
|
npcWillSpyIn5s: '{npcName} проведет разведку через 5 секунд',
|
||||||
|
npcWillAttackIn5s: '{npcName} атакует через 5 секунд',
|
||||||
|
npcWillSpyAndAttack: '{npcName} проведет разведку через 5с и атакует через 10с',
|
||||||
|
acceleratedMissions: 'Ускорено {count} миссий до 5 секунд',
|
||||||
|
npcFleetInitialized: 'Флот {npcName} инициализирован',
|
||||||
|
npcFleetDetails:
|
||||||
|
'100 шпионских зондов\n500 легких истребителей\n300 тяжелых истребителей\n200 крейсеров\n100 линкоров\n50 бомбардировщиков\n30 эсминцев\n20 линейных крейсеров',
|
||||||
dangerZone: 'Опасная зона',
|
dangerZone: 'Опасная зона',
|
||||||
dangerZoneDesc: 'Следующие операции необратимы',
|
dangerZoneDesc: 'Следующие операции необратимы',
|
||||||
resetGame: 'Сбросить игру',
|
resetGame: 'Сбросить игру',
|
||||||
resetGameConfirm: 'Вы уверены, что хотите сбросить игру? Все данные будут удалены!'
|
resetGameConfirm: 'Вы уверены, что хотите сбросить игру? Все данные будут удалены!',
|
||||||
|
completeAllQueues: '',
|
||||||
|
completeAllQueuesDesc: '',
|
||||||
|
completeQueues: '',
|
||||||
|
completeQueuesSuccess: ''
|
||||||
},
|
},
|
||||||
alerts: {
|
alerts: {
|
||||||
npcSpyIncoming: 'Приближается шпионский зонд NPC',
|
npcSpyIncoming: 'Приближается шпионский зонд NPC',
|
||||||
@@ -779,6 +879,10 @@ export default {
|
|||||||
recentEvents: 'Недавние события',
|
recentEvents: 'Недавние события',
|
||||||
recentEventsDescription: 'Журнал последних дипломатических действий',
|
recentEventsDescription: 'Журнал последних дипломатических действий',
|
||||||
ago: 'назад',
|
ago: 'назад',
|
||||||
|
notifications: '',
|
||||||
|
markAllRead: '',
|
||||||
|
noReports: '',
|
||||||
|
viewAll: '',
|
||||||
status: {
|
status: {
|
||||||
friendly: 'Дружественный',
|
friendly: 'Дружественный',
|
||||||
neutral: 'Нейтральный',
|
neutral: 'Нейтральный',
|
||||||
@@ -794,19 +898,96 @@ export default {
|
|||||||
viewPlanets: 'Посмотреть планеты'
|
viewPlanets: 'Посмотреть планеты'
|
||||||
},
|
},
|
||||||
lastEvent: 'Последнее событие',
|
lastEvent: 'Последнее событие',
|
||||||
|
reportDetails: '',
|
||||||
|
eventDescription: '',
|
||||||
|
reputationChange: '',
|
||||||
|
before: '',
|
||||||
|
after: '',
|
||||||
|
statusChange: '',
|
||||||
|
viewDiplomacy: '',
|
||||||
events: {
|
events: {
|
||||||
gift: 'Подарок отправлен',
|
gift: 'Подарок отправлен',
|
||||||
attack: 'Атака',
|
attack: 'Атака',
|
||||||
|
missileAttack: 'Ракетная атака',
|
||||||
allyAttacked: 'Союзник атакован',
|
allyAttacked: 'Союзник атакован',
|
||||||
spy: 'Шпионаж',
|
spy: 'Шпионаж',
|
||||||
stealDebris: 'Обломки украдены'
|
stealDebris: 'Обломки украдены'
|
||||||
|
},
|
||||||
|
reports: {
|
||||||
|
giftedResources: 'Подарено {metal}M {crystal}C {deuterium}D',
|
||||||
|
receivedGiftFromPlayer: 'Получен подарок от игрока',
|
||||||
|
giftedToNpc: 'Вы подарили ресурсы {npcName}. Репутация +{reputation}',
|
||||||
|
rejectedPlayerGift: 'Отклонен подарок игрока',
|
||||||
|
npcRejectedGift: '{npcName} отклонил ваш подарок. Репутация {reputation}',
|
||||||
|
attackedNpc: 'Атакован {npcName}',
|
||||||
|
wasAttackedByPlayer: 'Был атакован игроком',
|
||||||
|
youAttackedNpc: 'Вы атаковали {npcName}',
|
||||||
|
playerAttackedAlly: 'Игрок атаковал союзника {allyName}',
|
||||||
|
allyDispleased: '{allyName} недоволен тем, что вы атаковали их союзника {targetName}',
|
||||||
|
wasSpiedByPlayer: 'Был разведан игроком (обнаружен: {detected})',
|
||||||
|
spyDetected: 'Ваш шпионаж был обнаружен {npcName}',
|
||||||
|
stoleDebrisFromTerritory: 'Украдены обломки с территории {npcName}',
|
||||||
|
playerStoleDebris: 'Игрок украл обломки с территории',
|
||||||
|
recycledDebrisNearNpc: 'Вы переработали обломки возле планеты {npcName}. Они недовольны.',
|
||||||
|
giftedResourcesToPlayer: 'Подарены ресурсы игроку',
|
||||||
|
receivedGiftFromNpc: 'Получен подарок от {npcName}',
|
||||||
|
acceptedGiftFromNpc: 'Вы приняли подарок от {npcName}: {metal}M {crystal}C {deuterium}D',
|
||||||
|
playerRejectedGift: 'Игрок отклонил подарок',
|
||||||
|
rejectedGiftFromNpc: 'Вы отклонили подарок от {npcName}. Репутация {reputation}',
|
||||||
|
destroyedNpcPlanet: 'Уничтожена {planetName} игрока {npcName}',
|
||||||
|
playerDestroyedPlanet: 'Игрок уничтожил {planetName}',
|
||||||
|
youDestroyedNpcPlanet: 'Вы уничтожили {planetName} игрока {npcName}. Репутация {reputation}',
|
||||||
|
playerDestroyedAllyPlanet: 'Игрок уничтожил {planetName} союзника {allyName}',
|
||||||
|
allyOutraged: '{allyName} возмущен тем, что вы уничтожили {planetName} их союзника {targetName}',
|
||||||
|
npcEliminated: 'NPC {npcName} полностью уничтожен',
|
||||||
|
npcEliminatedMessage: 'Вы уничтожили все планеты {npcName}! Эта фракция полностью уничтожена.'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pagination: {
|
pagination: {
|
||||||
previous: 'Предыдущая',
|
previous: 'Предыдущая',
|
||||||
next: 'Следующая',
|
next: 'Следующая',
|
||||||
|
gotIt: '',
|
||||||
first: 'Первая',
|
first: 'Первая',
|
||||||
last: 'Последняя',
|
last: 'Последняя',
|
||||||
page: 'Страница {page}'
|
page: 'Страница {page}'
|
||||||
|
},
|
||||||
|
notFound: {
|
||||||
|
title: 'Страница не найдена',
|
||||||
|
description: 'Извините, страница, которую вы ищете, не существует',
|
||||||
|
goHome: 'На главную'
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
days: 'дней',
|
||||||
|
hours: 'часов',
|
||||||
|
minutes: 'минут',
|
||||||
|
seconds: 'секунд'
|
||||||
|
},
|
||||||
|
tutorial: {
|
||||||
|
welcome: {
|
||||||
|
title: 'Добро пожаловать в OGame',
|
||||||
|
content: 'Добро пожаловать, Командир! Давайте начнём с основ и построим вашу космическую империю.'
|
||||||
|
},
|
||||||
|
buildSolarPlant: {
|
||||||
|
title: 'Постройте солнечную электростанцию',
|
||||||
|
content:
|
||||||
|
'Сначала постройте солнечную электростанцию! Она обеспечивает энергией вашу планету. Без энергии другие ресурсные здания не могут функционировать. Это самый важный первый шаг.'
|
||||||
|
},
|
||||||
|
waitBuild: {
|
||||||
|
title: 'Очередь строительства',
|
||||||
|
content:
|
||||||
|
'Ваше здание теперь в очереди строительства. Нажмите на значок очереди в правом верхнем углу, чтобы увидеть все текущие задачи строительства и исследований. Строительство занимает время, но вы можете продолжать работать во время ожидания.'
|
||||||
|
},
|
||||||
|
mobile: {
|
||||||
|
welcome: {
|
||||||
|
title: 'Добро пожаловать в OGame (Мобильная версия)',
|
||||||
|
content:
|
||||||
|
'Добро пожаловать, Командир! Это упрощённое руководство, разработанное для сенсорных экранов. Мы быстро рассмотрим основные функции, чтобы вы могли начать строить свою империю.'
|
||||||
|
},
|
||||||
|
waitBuild: {
|
||||||
|
title: 'Очередь строительства',
|
||||||
|
content:
|
||||||
|
'Нажмите на значок очереди в правом верхнем углу, чтобы увидеть прогресс строительства. Вы можете продолжать просматривать другие страницы - строительство происходит в фоновом режиме.'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,13 +33,20 @@ export default {
|
|||||||
viewRequirements: '查看前置条件',
|
viewRequirements: '查看前置条件',
|
||||||
requirementsNotMet: '前置条件未满足',
|
requirementsNotMet: '前置条件未满足',
|
||||||
current: '当前',
|
current: '当前',
|
||||||
level: '等级'
|
level: '等级',
|
||||||
|
gmModeActivated: 'GM 模式已激活!请查看导航菜单。'
|
||||||
},
|
},
|
||||||
errors: {
|
errors: {
|
||||||
requirementsNotMet: '不满足前置条件',
|
requirementsNotMet: '不满足前置条件',
|
||||||
insufficientResources: '资源不足',
|
insufficientResources: '资源不足',
|
||||||
insufficientFleetStorage: '舰队仓储空间不足',
|
insufficientFleetStorage: '舰队仓储空间不足',
|
||||||
shieldDomeLimit: '护盾罩数量限制',
|
shieldDomeLimit: '护盾罩数量限制',
|
||||||
|
missileSiloLimit: '导弹发射井容量不足',
|
||||||
|
insufficientMissiles: '星际导弹数量不足',
|
||||||
|
invalidMissileCount: '导弹数量无效',
|
||||||
|
targetOutOfRange: '目标超出射程',
|
||||||
|
cannotAttackOwnPlanet: '不能攻击自己的星球',
|
||||||
|
launchFailed: '发射失败',
|
||||||
fleetMissionsFull: '舰队任务槽位已满',
|
fleetMissionsFull: '舰队任务槽位已满',
|
||||||
insufficientFleet: '舰队数量不足',
|
insufficientFleet: '舰队数量不足',
|
||||||
insufficientFuel: '燃料不足',
|
insufficientFuel: '燃料不足',
|
||||||
@@ -119,6 +126,7 @@ export default {
|
|||||||
roboticsFactory: '机器人工厂',
|
roboticsFactory: '机器人工厂',
|
||||||
naniteFactory: '纳米工厂',
|
naniteFactory: '纳米工厂',
|
||||||
shipyard: '船坞',
|
shipyard: '船坞',
|
||||||
|
hangar: '机库',
|
||||||
researchLab: '研究实验室',
|
researchLab: '研究实验室',
|
||||||
metalStorage: '金属仓库',
|
metalStorage: '金属仓库',
|
||||||
crystalStorage: '晶体仓库',
|
crystalStorage: '晶体仓库',
|
||||||
@@ -157,6 +165,7 @@ export default {
|
|||||||
roboticsFactory: '加快建造速度',
|
roboticsFactory: '加快建造速度',
|
||||||
naniteFactory: '增加建造队列数量,每级+1队列(最多10级)',
|
naniteFactory: '增加建造队列数量,每级+1队列(最多10级)',
|
||||||
shipyard: '建造舰船',
|
shipyard: '建造舰船',
|
||||||
|
hangar: '专门用于扩展舰队存储容量,支持星球专业化发展',
|
||||||
researchLab: '研究科技',
|
researchLab: '研究科技',
|
||||||
metalStorage: '增加金属存储上限',
|
metalStorage: '增加金属存储上限',
|
||||||
crystalStorage: '增加晶体存储上限',
|
crystalStorage: '增加晶体存储上限',
|
||||||
@@ -164,8 +173,8 @@ export default {
|
|||||||
darkMatterCollector: '收集稀有的暗物质资源',
|
darkMatterCollector: '收集稀有的暗物质资源',
|
||||||
darkMatterTank: '增加暗物质存储上限',
|
darkMatterTank: '增加暗物质存储上限',
|
||||||
missileSilo: '存储和发射导弹,每级可存储10枚导弹',
|
missileSilo: '存储和发射导弹,每级可存储10枚导弹',
|
||||||
terraformer: '改造行星地形,每级增加5个可用空间',
|
terraformer: '改造行星地形,每级增加30个可用空间',
|
||||||
lunarBase: '增加月球可用空间,每级+5空间',
|
lunarBase: '增加月球可用空间,每级+30空间',
|
||||||
sensorPhalanx: '侦测周围星系的舰队活动',
|
sensorPhalanx: '侦测周围星系的舰队活动',
|
||||||
jumpGate: '瞬间传送舰队到其他月球',
|
jumpGate: '瞬间传送舰队到其他月球',
|
||||||
planetDestroyerFactory: '建造能够摧毁行星的终极武器'
|
planetDestroyerFactory: '建造能够摧毁行星的终极武器'
|
||||||
@@ -191,10 +200,10 @@ export default {
|
|||||||
lightFighter: '基础战斗单位',
|
lightFighter: '基础战斗单位',
|
||||||
heavyFighter: '重装战斗机',
|
heavyFighter: '重装战斗机',
|
||||||
cruiser: '中型战舰,攻守平衡',
|
cruiser: '中型战舰,攻守平衡',
|
||||||
battleship: '强力战舰',
|
battleship: '主力重型战舰,拥有强大的火力和防护',
|
||||||
battlecruiser: '快速强大的战斗舰船,擅长攻击战列舰',
|
battlecruiser: '快速强大的战斗舰船,擅长攻击战列舰',
|
||||||
bomber: '专门对付防御设施的轰炸舰',
|
bomber: '专门对付防御设施的轰炸舰',
|
||||||
destroyer: '擅长摧毁大型舰船的猎杀者',
|
destroyer: '专业反大型舰船战舰,高火力低防护',
|
||||||
smallCargo: '运输少量资源',
|
smallCargo: '运输少量资源',
|
||||||
largeCargo: '运输大量资源',
|
largeCargo: '运输大量资源',
|
||||||
colonyShip: '用于殖民新星球',
|
colonyShip: '用于殖民新星球',
|
||||||
@@ -283,7 +292,7 @@ export default {
|
|||||||
impulseDrive: '中级推进技术',
|
impulseDrive: '中级推进技术',
|
||||||
hyperspaceDrive: '高级推进技术',
|
hyperspaceDrive: '高级推进技术',
|
||||||
darkMatterTechnology: '研究暗物质的性质和应用',
|
darkMatterTechnology: '研究暗物质的性质和应用',
|
||||||
terraformingTechnology: '研究行星地形改造技术,每级为所有行星增加3个可用空间',
|
terraformingTechnology: '研究行星地形改造技术,每级为所有行星增加30个可用空间',
|
||||||
planetDestructionTech: '研究如何摧毁整个行星的恐怖技术'
|
planetDestructionTech: '研究如何摧毁整个行星的恐怖技术'
|
||||||
},
|
},
|
||||||
officers: {
|
officers: {
|
||||||
@@ -306,11 +315,14 @@ export default {
|
|||||||
darkMatterSpecialist: '提升暗物质采集效率'
|
darkMatterSpecialist: '提升暗物质采集效率'
|
||||||
},
|
},
|
||||||
queue: {
|
queue: {
|
||||||
|
title: '建造队列',
|
||||||
|
empty: '当前没有进行中的任务',
|
||||||
buildQueueBonus: '建造队列',
|
buildQueueBonus: '建造队列',
|
||||||
spaceBonus: '空间加成',
|
spaceBonus: '空间加成',
|
||||||
researchQueueBonus: '研究队列',
|
researchQueueBonus: '研究队列',
|
||||||
building: '建造中',
|
building: '建造中',
|
||||||
researching: '研究中',
|
researching: '研究中',
|
||||||
|
demolishing: '拆除中',
|
||||||
remaining: '剩余时间',
|
remaining: '剩余时间',
|
||||||
cancel: '取消',
|
cancel: '取消',
|
||||||
cancelBuild: '取消建造',
|
cancelBuild: '取消建造',
|
||||||
@@ -415,6 +427,7 @@ export default {
|
|||||||
totalCost: '总成本',
|
totalCost: '总成本',
|
||||||
build: '建造',
|
build: '建造',
|
||||||
shieldDomeBuilt: '护盾罩已建造',
|
shieldDomeBuilt: '护盾罩已建造',
|
||||||
|
missileCapacity: '导弹容量',
|
||||||
inputError: '输入错误',
|
inputError: '输入错误',
|
||||||
inputErrorMessage: '请输入建造数量!',
|
inputErrorMessage: '请输入建造数量!',
|
||||||
buildFailed: '建造失败',
|
buildFailed: '建造失败',
|
||||||
@@ -461,6 +474,11 @@ export default {
|
|||||||
arrivalTime: '到达时间',
|
arrivalTime: '到达时间',
|
||||||
returnTime: '返回时间',
|
returnTime: '返回时间',
|
||||||
recallFleet: '召回舰队',
|
recallFleet: '召回舰队',
|
||||||
|
abortMission: '终止任务',
|
||||||
|
abortMissionTitle: '确认终止任务',
|
||||||
|
abortMissionWarning: '警告:终止任务将永久损失 {ships} 艘舰船和 {resources} 资源!\n\n此操作不可撤销,舰队和资源将不会返回。',
|
||||||
|
abortMissionSuccess: '任务已终止',
|
||||||
|
abortMissionSuccessMessage: '任务已终止,舰队和资源已损失。',
|
||||||
sendFailed: '派遣失败',
|
sendFailed: '派遣失败',
|
||||||
sendFailedMessage: '请检查舰队数量、燃料是否充足,或载货量是否超出限制。',
|
sendFailedMessage: '请检查舰队数量、燃料是否充足,或载货量是否超出限制。',
|
||||||
recallFailed: '召回失败',
|
recallFailed: '召回失败',
|
||||||
@@ -520,15 +538,16 @@ export default {
|
|||||||
selectSystem: '选择星系',
|
selectSystem: '选择星系',
|
||||||
view: '查看',
|
view: '查看',
|
||||||
myPlanet: '我的星球',
|
myPlanet: '我的星球',
|
||||||
myPlanets: '我的星球',
|
myPlanets: '查看我的星系',
|
||||||
npcPlanets: 'NPC星球',
|
npcPlanets: 'NPC星球',
|
||||||
selectPlanetToView: '选择要查看的星球',
|
selectPlanetToView: '选择星球以查看其所在星系',
|
||||||
totalPositions: '共10个星球位置',
|
totalPositions: '共10个星球位置',
|
||||||
mine: '我的',
|
mine: '我的',
|
||||||
hostile: '敌对',
|
hostile: '敌对',
|
||||||
emptySlot: '空位 - 可殖民',
|
emptySlot: '空位 - 可殖民',
|
||||||
scout: '侦察',
|
scout: '侦察',
|
||||||
attack: '攻击',
|
attack: '攻击',
|
||||||
|
missileAttack: '导弹攻击',
|
||||||
colonize: '殖民',
|
colonize: '殖民',
|
||||||
switch: '切换',
|
switch: '切换',
|
||||||
recycle: '回收',
|
recycle: '回收',
|
||||||
@@ -537,11 +556,22 @@ export default {
|
|||||||
debrisField: '残骸场',
|
debrisField: '残骸场',
|
||||||
scoutPlanetTitle: '侦察星球',
|
scoutPlanetTitle: '侦察星球',
|
||||||
attackPlanetTitle: '攻击星球',
|
attackPlanetTitle: '攻击星球',
|
||||||
|
missileAttackTitle: '导弹攻击',
|
||||||
colonizePlanetTitle: '殖民星球',
|
colonizePlanetTitle: '殖民星球',
|
||||||
recyclePlanetTitle: '回收残骸',
|
recyclePlanetTitle: '回收残骸',
|
||||||
giftPlanetTitle: '赠送礼物',
|
giftPlanetTitle: '赠送礼物',
|
||||||
scoutPlanetMessage: '确定要派遣间谍探测器侦察星球 [{coordinates}] 吗?\n\n请前往舰队页面选择舰船并派遣。',
|
scoutPlanetMessage: '确定要派遣间谍探测器侦察星球 [{coordinates}] 吗?\n\n请前往舰队页面选择舰船并派遣。',
|
||||||
attackPlanetMessage: '确定要攻击星球 [{coordinates}] 吗?\n\n请前往舰队页面选择舰船并派遣。',
|
attackPlanetMessage: '确定要攻击星球 [{coordinates}] 吗?\n\n请前往舰队页面选择舰船并派遣。',
|
||||||
|
missileAttackMessage: '向星球 [{coordinates}] 发射导弹',
|
||||||
|
missileCount: '导弹数量',
|
||||||
|
availableMissiles: '可用导弹',
|
||||||
|
missileRange: '射程',
|
||||||
|
systems: '系统',
|
||||||
|
distance: '距离',
|
||||||
|
flightTime: '飞行时间',
|
||||||
|
launchMissile: '发射',
|
||||||
|
missileLaunched: '导弹已发射',
|
||||||
|
cancel: '取消',
|
||||||
colonizePlanetMessage: '确定要殖民位置 [{coordinates}] 吗?\n\n请前往舰队页面派遣殖民船。',
|
colonizePlanetMessage: '确定要殖民位置 [{coordinates}] 吗?\n\n请前往舰队页面派遣殖民船。',
|
||||||
recyclePlanetMessage: '确定要回收位置 [{coordinates}] 的残骸吗?\n\n请前往舰队页面派遣回收船。',
|
recyclePlanetMessage: '确定要回收位置 [{coordinates}] 的残骸吗?\n\n请前往舰队页面派遣回收船。',
|
||||||
giftPlanetMessage: '确定要向星球 [{coordinates}] 赠送资源吗?\n\n请前往舰队页面选择运输船并装载资源。'
|
giftPlanetMessage: '确定要向星球 [{coordinates}] 赠送资源吗?\n\n请前往舰队页面选择运输船并装载资源。'
|
||||||
@@ -551,10 +581,12 @@ export default {
|
|||||||
battles: '战斗',
|
battles: '战斗',
|
||||||
spy: '侦查',
|
spy: '侦查',
|
||||||
npc: 'NPC',
|
npc: 'NPC',
|
||||||
|
diplomacy: '',
|
||||||
battleReports: '战斗报告',
|
battleReports: '战斗报告',
|
||||||
spyReports: '间谍报告',
|
spyReports: '间谍报告',
|
||||||
noBattleReports: '暂无战斗报告',
|
noBattleReports: '暂无战斗报告',
|
||||||
noSpyReports: '暂无间谍报告',
|
noSpyReports: '暂无间谍报告',
|
||||||
|
noDiplomaticReports: '',
|
||||||
battleReport: '战斗报告',
|
battleReport: '战斗报告',
|
||||||
spyReport: '间谍报告',
|
spyReport: '间谍报告',
|
||||||
victory: '胜利',
|
victory: '胜利',
|
||||||
@@ -610,7 +642,38 @@ export default {
|
|||||||
hostile: '对方对你有敌意,不接受礼物',
|
hostile: '对方对你有敌意,不接受礼物',
|
||||||
neutral_distrust: '对方对你缺乏信任',
|
neutral_distrust: '对方对你缺乏信任',
|
||||||
polite_decline: '对方礼貌地拒绝了'
|
polite_decline: '对方礼貌地拒绝了'
|
||||||
}
|
},
|
||||||
|
// 被侦查通知对话框
|
||||||
|
spiedNotificationDetails: '被侦查通知详情',
|
||||||
|
spyDetected: '侦查被发现',
|
||||||
|
detectionResult: '检测结果',
|
||||||
|
detectionSuccess: '你的侦查探测被发现了!',
|
||||||
|
spiedNotificationMessage: '{npc}试图侦查你的星球{planet}',
|
||||||
|
spiedNotificationTip: '考虑增强防御或反击,如果这个NPC对你有敌意',
|
||||||
|
viewInGalaxy: '在星系中查看',
|
||||||
|
// 任务报告对话框
|
||||||
|
missionReportDetails: '任务报告详情',
|
||||||
|
missionSuccess: '成功',
|
||||||
|
missionFailed: '失败',
|
||||||
|
origin: '起点',
|
||||||
|
destination: '终点',
|
||||||
|
missionDetails: '任务详情',
|
||||||
|
transportedResources: '运输资源',
|
||||||
|
recycledResources: '回收资源',
|
||||||
|
remainingDebris: '剩余残骸',
|
||||||
|
newPlanet: '新星球',
|
||||||
|
// NPC活动对话框
|
||||||
|
npcActivityDetails: 'NPC活动详情',
|
||||||
|
activityType: {
|
||||||
|
recycle: '回收残骸'
|
||||||
|
},
|
||||||
|
activityLocation: '活动位置',
|
||||||
|
position: '位置',
|
||||||
|
nearPlanet: '附近星球',
|
||||||
|
activityDescription: '活动描述',
|
||||||
|
npcActivityMessage: '{npc}正在{position}{activity}',
|
||||||
|
arrivalTime: '到达时间',
|
||||||
|
npcActivityTip: 'NPC可能会收集战斗产生的残骸。如果你想竞争资源,可以尝试先到达该位置'
|
||||||
},
|
},
|
||||||
missionReports: {
|
missionReports: {
|
||||||
transportSuccess: '运输任务成功完成',
|
transportSuccess: '运输任务成功完成',
|
||||||
@@ -622,7 +685,11 @@ export default {
|
|||||||
recycleSuccess: '回收任务成功完成',
|
recycleSuccess: '回收任务成功完成',
|
||||||
recycleFailed: '回收任务失败,目标位置没有残骸',
|
recycleFailed: '回收任务失败,目标位置没有残骸',
|
||||||
destroySuccess: '行星毁灭任务成功执行',
|
destroySuccess: '行星毁灭任务成功执行',
|
||||||
destroyFailed: '行星毁灭任务失败'
|
destroyFailed: '行星毁灭任务失败',
|
||||||
|
missileAttackSuccess: '导弹攻击成功',
|
||||||
|
missileAttackFailed: '导弹攻击失败,目标星球不存在',
|
||||||
|
missileAttackIntercepted: '所有导弹被拦截',
|
||||||
|
hits: '枚命中'
|
||||||
},
|
},
|
||||||
simulatorView: {
|
simulatorView: {
|
||||||
title: '战斗模拟器',
|
title: '战斗模拟器',
|
||||||
@@ -691,10 +758,24 @@ export default {
|
|||||||
gamePaused: '游戏已暂停',
|
gamePaused: '游戏已暂停',
|
||||||
gameResumed: '游戏已恢复',
|
gameResumed: '游戏已恢复',
|
||||||
playerName: '玩家名称',
|
playerName: '玩家名称',
|
||||||
gameSpeed: '游戏速度',
|
gameSpeed: '资源产出速度',
|
||||||
gameSpeedDesc: '当前游戏速度倍率',
|
gameSpeedDesc: '当前资源产出速度倍率',
|
||||||
|
speedChanged: '资源产出速度已更改为 {speed}x',
|
||||||
|
speedReset: '资源产出速度已重置为 1x',
|
||||||
|
reset: '重置',
|
||||||
about: '关于',
|
about: '关于',
|
||||||
version: '版本',
|
version: '版本',
|
||||||
|
latestVersion: '最新版本',
|
||||||
|
checkUpdate: '检查更新',
|
||||||
|
checking: '检查中...',
|
||||||
|
newVersionAvailable: '发现新版本 {version}',
|
||||||
|
upToDate: '已是最新版本',
|
||||||
|
checkUpdateCooldown: '请稍后再试(5分钟冷却时间)',
|
||||||
|
checkUpdateFailed: '检查更新失败,请检查网络连接',
|
||||||
|
viewUpdate: '查看更新',
|
||||||
|
updateAvailable: '有新版本可用。点击查看更新内容。',
|
||||||
|
download: '下载',
|
||||||
|
goToDownload: '前往下载',
|
||||||
buildDate: '构建日期',
|
buildDate: '构建日期',
|
||||||
community: '社区',
|
community: '社区',
|
||||||
github: 'GitHub 仓库',
|
github: 'GitHub 仓库',
|
||||||
@@ -713,6 +794,8 @@ export default {
|
|||||||
officers: '军官',
|
officers: '军官',
|
||||||
modifyResources: '修改资源',
|
modifyResources: '修改资源',
|
||||||
resourcesDesc: '快速修改星球资源数量',
|
resourcesDesc: '快速修改星球资源数量',
|
||||||
|
maxAllResources: '一键拉满',
|
||||||
|
maxAllResourcesSuccess: '所有资源已拉满',
|
||||||
modifyBuildings: '修改建筑',
|
modifyBuildings: '修改建筑',
|
||||||
buildingsDesc: '快速设置建筑等级',
|
buildingsDesc: '快速设置建筑等级',
|
||||||
modifyResearch: '修改科技',
|
modifyResearch: '修改科技',
|
||||||
@@ -733,16 +816,31 @@ export default {
|
|||||||
testSpy: '测试侦查',
|
testSpy: '测试侦查',
|
||||||
testAttack: '测试攻击',
|
testAttack: '测试攻击',
|
||||||
testSpyAndAttack: '测试侦查&攻击',
|
testSpyAndAttack: '测试侦查&攻击',
|
||||||
|
testSpyMessage: '点击确认以加速侦查任务',
|
||||||
|
testAttackMessage: '点击确认以加速攻击任务',
|
||||||
|
testSpyAndAttackMessage: '点击确认以加速任务执行',
|
||||||
initializeFleet: '初始化NPC舰队',
|
initializeFleet: '初始化NPC舰队',
|
||||||
accelerateMissions: '加速所有任务(5秒)',
|
accelerateMissions: '加速所有任务(5秒)',
|
||||||
selectNPCFirst: '请先选择一个NPC',
|
selectNPCFirst: '请先选择一个NPC',
|
||||||
npcNoProbes: 'NPC没有间谍探测器',
|
npcNoProbes: 'NPC没有间谍探测器',
|
||||||
npcNoSpyReport: 'NPC需要先侦查',
|
npcNoSpyReport: 'NPC需要先侦查',
|
||||||
npcMissionFailed: '创建任务失败',
|
npcMissionFailed: '创建任务失败',
|
||||||
|
npcNoPlanets: 'NPC没有星球',
|
||||||
|
npcWillSpyIn5s: '{npcName}将在5秒后侦查',
|
||||||
|
npcWillAttackIn5s: '{npcName}将在5秒后攻击',
|
||||||
|
npcWillSpyAndAttack: '{npcName}将在5秒后侦查,10秒后攻击',
|
||||||
|
acceleratedMissions: '已加速{count}个任务至5秒后',
|
||||||
|
npcFleetInitialized: '{npcName}舰队已初始化',
|
||||||
|
npcFleetDetails: '100 间谍探测器\n500 轻型战机\n300 重型战机\n200 巡洋舰\n100 战列舰\n50 轰炸机\n30 毁灭者\n20 战列巡洋舰',
|
||||||
dangerZone: '危险区域',
|
dangerZone: '危险区域',
|
||||||
dangerZoneDesc: '以下操作不可撤销,请谨慎操作',
|
dangerZoneDesc: '以下操作不可撤销,请谨慎操作',
|
||||||
resetGame: '重置游戏',
|
resetGame: '重置游戏',
|
||||||
resetGameConfirm: '确定要重置游戏吗?这将删除所有数据!'
|
resetGameConfirm: '确定要重置游戏吗?这将删除所有数据!',
|
||||||
|
completeAllQueues: '一键完成所有队列',
|
||||||
|
completeAllQueuesDesc: '立即完成所有建筑、科技、舰船、防御队列和飞行任务',
|
||||||
|
completeQueues: '完成队列',
|
||||||
|
completeQueuesSuccess:
|
||||||
|
'已完成 {buildingCount} 个建筑队列、{researchCount} 个科技队列、{missionCount} 个飞行任务、{missileCount} 个导弹任务'
|
||||||
},
|
},
|
||||||
alerts: {
|
alerts: {
|
||||||
npcSpyIncoming: 'NPC侦查即将到达',
|
npcSpyIncoming: 'NPC侦查即将到达',
|
||||||
@@ -772,6 +870,10 @@ export default {
|
|||||||
recentEvents: '最近事件',
|
recentEvents: '最近事件',
|
||||||
recentEventsDescription: '最近的外交活动记录',
|
recentEventsDescription: '最近的外交活动记录',
|
||||||
ago: '前',
|
ago: '前',
|
||||||
|
notifications: '外交通知',
|
||||||
|
markAllRead: '全部已读',
|
||||||
|
noReports: '暂无外交事件',
|
||||||
|
viewAll: '查看全部',
|
||||||
status: {
|
status: {
|
||||||
friendly: '友好',
|
friendly: '友好',
|
||||||
neutral: '中立',
|
neutral: '中立',
|
||||||
@@ -787,12 +889,48 @@ export default {
|
|||||||
viewPlanets: '查看星球'
|
viewPlanets: '查看星球'
|
||||||
},
|
},
|
||||||
lastEvent: '最近活动',
|
lastEvent: '最近活动',
|
||||||
|
reportDetails: '外交报告详情',
|
||||||
|
eventDescription: '事件描述',
|
||||||
|
reputationChange: '好感度变化',
|
||||||
|
before: '之前',
|
||||||
|
after: '之后',
|
||||||
|
statusChange: '关系状态变化',
|
||||||
|
viewDiplomacy: '查看外交页面',
|
||||||
events: {
|
events: {
|
||||||
gift: '赠送资源',
|
gift: '赠送资源',
|
||||||
attack: '攻击',
|
attack: '攻击',
|
||||||
allyAttacked: '攻击盟友',
|
allyAttacked: '攻击盟友',
|
||||||
spy: '侦查',
|
spy: '侦查',
|
||||||
stealDebris: '抢夺残骸'
|
stealDebris: '抢夺残骸'
|
||||||
|
},
|
||||||
|
reports: {
|
||||||
|
giftedResources: '赠送了 {metal}金属 {crystal}晶体 {deuterium}氘',
|
||||||
|
receivedGiftFromPlayer: '收到玩家的礼物',
|
||||||
|
giftedToNpc: '你向{npcName}赠送了资源。好感度+{reputation}',
|
||||||
|
rejectedPlayerGift: '拒绝了玩家的礼物',
|
||||||
|
npcRejectedGift: '{npcName}拒绝了你的礼物。好感度{reputation}',
|
||||||
|
attackedNpc: '攻击了{npcName}',
|
||||||
|
wasAttackedByPlayer: '被玩家攻击',
|
||||||
|
youAttackedNpc: '你攻击了{npcName}',
|
||||||
|
playerAttackedAlly: '玩家攻击了盟友{allyName}',
|
||||||
|
allyDispleased: '{allyName}对你攻击盟友{targetName}感到不满',
|
||||||
|
wasSpiedByPlayer: '被玩家侦查(被发现:{detected})',
|
||||||
|
spyDetected: '你的侦查被{npcName}发现了',
|
||||||
|
stoleDebrisFromTerritory: '从{npcName}的领地抢夺了残骸',
|
||||||
|
playerStoleDebris: '玩家从领地抢夺了残骸',
|
||||||
|
recycledDebrisNearNpc: '你在{npcName}的星球附近回收了残骸。他们很不高兴。',
|
||||||
|
giftedResourcesToPlayer: '向玩家赠送了资源',
|
||||||
|
receivedGiftFromNpc: '收到了{npcName}的礼物',
|
||||||
|
acceptedGiftFromNpc: '你接受了{npcName}的礼物:{metal}金属 {crystal}晶体 {deuterium}氘',
|
||||||
|
playerRejectedGift: '玩家拒绝了礼物',
|
||||||
|
rejectedGiftFromNpc: '你拒绝了{npcName}的礼物。好感度{reputation}',
|
||||||
|
destroyedNpcPlanet: '摧毁了{npcName}的{planetName}',
|
||||||
|
playerDestroyedPlanet: '玩家摧毁了{planetName}',
|
||||||
|
youDestroyedNpcPlanet: '你摧毁了{npcName}的{planetName}。好感度{reputation}',
|
||||||
|
playerDestroyedAllyPlanet: '玩家摧毁了盟友{allyName}的{planetName}',
|
||||||
|
allyOutraged: '{allyName}对你摧毁盟友{targetName}的{planetName}感到愤怒',
|
||||||
|
npcEliminated: 'NPC {npcName}已被彻底消灭',
|
||||||
|
npcEliminatedMessage: '你消灭了{npcName}的所有星球!该势力已被彻底摧毁。'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pagination: {
|
pagination: {
|
||||||
@@ -801,5 +939,149 @@ export default {
|
|||||||
first: '首页',
|
first: '首页',
|
||||||
last: '末页',
|
last: '末页',
|
||||||
page: '第 {page} 页'
|
page: '第 {page} 页'
|
||||||
|
},
|
||||||
|
notFound: {
|
||||||
|
title: '页面未找到',
|
||||||
|
description: '抱歉,您访问的页面不存在',
|
||||||
|
goHome: '返回首页'
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
days: '天',
|
||||||
|
hours: '小时',
|
||||||
|
minutes: '分钟',
|
||||||
|
seconds: '秒'
|
||||||
|
},
|
||||||
|
tutorial: {
|
||||||
|
progress: '进度',
|
||||||
|
previous: '上一步',
|
||||||
|
next: '下一步',
|
||||||
|
gotIt: '我知道了',
|
||||||
|
completeButton: '完成',
|
||||||
|
skip: '跳过引导',
|
||||||
|
welcome: {
|
||||||
|
title: '欢迎来到 OGame',
|
||||||
|
content: '欢迎,指挥官!本教程将引导您了解建立帝国的基础知识。点击"下一步"开始您的征程。'
|
||||||
|
},
|
||||||
|
resources: {
|
||||||
|
title: '资源概览',
|
||||||
|
content: '这些是您的资源:金属、晶体和重氢。它们是建造建筑和研究科技的必需品。能量也很重要,用于为您的基础设施供电。'
|
||||||
|
},
|
||||||
|
planet: {
|
||||||
|
title: '您的星球',
|
||||||
|
content: '这是您的母星。您可以在这里查看星球名称、坐标,并在扩张帝国时切换星球。'
|
||||||
|
},
|
||||||
|
navigation: {
|
||||||
|
title: '导航菜单',
|
||||||
|
content: '使用此菜单在不同部分之间导航:建筑、研究、舰队、星系等。每个部分都提供独特的游戏功能。'
|
||||||
|
},
|
||||||
|
gotoBuildings: {
|
||||||
|
title: '前往建筑页面',
|
||||||
|
content: '让我们从建造一些建筑开始。点击"建筑"菜单项查看可用建筑。'
|
||||||
|
},
|
||||||
|
buildSolarPlant: {
|
||||||
|
title: '建造太阳能电站',
|
||||||
|
content: '首先建造太阳能电站!它为您的星球提供能量。没有能量,其他资源建筑无法运作。这是最重要的第一步。'
|
||||||
|
},
|
||||||
|
waitBuild: {
|
||||||
|
title: '建造队列',
|
||||||
|
content:
|
||||||
|
'您的建筑现在在建造队列中。点击右上角的队列图标可以查看所有正在进行的建造和研究任务。建筑需要时间完成,但您可以在等待时继续操作。'
|
||||||
|
},
|
||||||
|
buildMetalMine: {
|
||||||
|
title: '建造金属矿',
|
||||||
|
content: '现在有了能量,可以建造金属矿了。金属矿是您的主要金属来源,金属几乎用于每个建筑和舰船。'
|
||||||
|
},
|
||||||
|
buildCrystalMine: {
|
||||||
|
title: '建造晶体矿',
|
||||||
|
content: '晶体更稀有但对高级科技至关重要。建造晶体矿开始收集这种宝贵的资源。'
|
||||||
|
},
|
||||||
|
buildDeuterium: {
|
||||||
|
title: '建造重氢合成器',
|
||||||
|
content: '重氢是舰船燃料和高级研究的必需品。建造重氢合成器开始生产这种关键资源。'
|
||||||
|
},
|
||||||
|
upgradeMines: {
|
||||||
|
title: '升级资源矿',
|
||||||
|
content: '接下来,您需要升级三种资源矿(金属、晶体、重氢)到2级,以满足建造机器人工厂的要求。资源充足后,继续升级它们。'
|
||||||
|
},
|
||||||
|
buildRobotics: {
|
||||||
|
title: '建造机器人工厂',
|
||||||
|
content: '机器人工厂可以大幅加快建造速度。它需要金属矿、晶体矿和重氢合成器各达到2级。建造它来提升建造效率!'
|
||||||
|
},
|
||||||
|
upgradeMinesForLab: {
|
||||||
|
title: '继续升级资源矿',
|
||||||
|
content: '现在需要将三种资源矿升级到3级,以满足研究实验室的建造要求。继续发展您的资源产能。'
|
||||||
|
},
|
||||||
|
buildResearchLab: {
|
||||||
|
title: '建造研究实验室',
|
||||||
|
content: '研究实验室是技术进步的基础。它需要三种资源矿各达到3级。建造它以解锁科技研究!'
|
||||||
|
},
|
||||||
|
gotoResearch: {
|
||||||
|
title: '前往研究页面',
|
||||||
|
content: '既然您有了研究实验室,点击"研究"菜单查看可用的科技。'
|
||||||
|
},
|
||||||
|
researchEnergy: {
|
||||||
|
title: '研究能量科技',
|
||||||
|
content: '能量科技可以提高您的能量产出并解锁高级建筑。这是最基础也是最重要的科技之一。'
|
||||||
|
},
|
||||||
|
shipyardIntro: {
|
||||||
|
title: '舰队与船坞',
|
||||||
|
content: '舰船让您能够探索星系、运输资源并保卫您的帝国。要建造舰船,您需要船坞(需要机器人工厂2级)。'
|
||||||
|
},
|
||||||
|
gotoBuildingsForShipyard: {
|
||||||
|
title: '返回建筑页面',
|
||||||
|
content: '返回建筑页面来建造您的船坞。'
|
||||||
|
},
|
||||||
|
buildShipyard: {
|
||||||
|
title: '建造船坞',
|
||||||
|
content: '船坞允许您建造舰船和防御系统。这对舰队行动至关重要。'
|
||||||
|
},
|
||||||
|
fleetIntro: {
|
||||||
|
title: '舰队行动',
|
||||||
|
content: '一旦您拥有舰船,就可以派遣它们执行任务:运输资源、殖民星球、攻击敌人或探索废墟场。'
|
||||||
|
},
|
||||||
|
galaxyIntro: {
|
||||||
|
title: '探索星系',
|
||||||
|
content: '星系视图显示其他星球、废墟场和扩张机会。使用它来侦察目标并规划您的战略。'
|
||||||
|
},
|
||||||
|
complete: {
|
||||||
|
title: '教程完成!',
|
||||||
|
content:
|
||||||
|
'恭喜,指挥官!您现在了解了基础知识。继续建设您的帝国,研究科技,探索星系。记住:先发展能量,再建资源,然后是工厂和研究!祝您好运!'
|
||||||
|
},
|
||||||
|
// 移动端教程
|
||||||
|
mobile: {
|
||||||
|
welcome: {
|
||||||
|
title: '欢迎来到 OGame(移动版)',
|
||||||
|
content: '欢迎,指挥官!这是专为触摸屏设计的简化教程。我们将快速介绍核心功能,让您开始建设帝国。'
|
||||||
|
},
|
||||||
|
resources: {
|
||||||
|
title: '顶部资源栏',
|
||||||
|
content: '顶部显示您的资源:金属、晶体和重氢。点击可查看详细生产信息。'
|
||||||
|
},
|
||||||
|
menu: {
|
||||||
|
title: '打开导航菜单',
|
||||||
|
content: '点击这个菜单图标打开导航栏,您可以访问建筑、研究、舰队等所有功能。'
|
||||||
|
},
|
||||||
|
gotoBuildings: {
|
||||||
|
title: '前往建筑页面',
|
||||||
|
content: '菜单已打开!现在点击"建筑"选项,开始建造基础设施。'
|
||||||
|
},
|
||||||
|
buildSolarPlant: {
|
||||||
|
title: '建造太阳能电站',
|
||||||
|
content: '首先建造太阳能电站!向下滚动找到它,点击卡片进行建造。能量是一切的基础。'
|
||||||
|
},
|
||||||
|
waitBuild: {
|
||||||
|
title: '建造队列',
|
||||||
|
content: '点击右上角的队列图标可以查看建造进度。您可以继续浏览其他页面,建造会在后台进行。'
|
||||||
|
},
|
||||||
|
buildMetalMine: {
|
||||||
|
title: '建造金属矿',
|
||||||
|
content: '有了能量后,建造金属矿。向下滚动找到金属矿,点击建造。'
|
||||||
|
},
|
||||||
|
complete: {
|
||||||
|
title: '快速教程完成!',
|
||||||
|
content: '很好!您已经掌握了基础操作。继续建造晶体矿和重氢合成器,然后探索其他功能。记住:先能量,再资源!'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export default {
|
|||||||
close: '關閉',
|
close: '關閉',
|
||||||
back: '返回',
|
back: '返回',
|
||||||
next: '下一步',
|
next: '下一步',
|
||||||
|
gotIt: '',
|
||||||
previous: '上一步',
|
previous: '上一步',
|
||||||
submit: '提交',
|
submit: '提交',
|
||||||
reset: '重置',
|
reset: '重置',
|
||||||
@@ -33,13 +34,19 @@ export default {
|
|||||||
viewRequirements: '查看前置條件',
|
viewRequirements: '查看前置條件',
|
||||||
requirementsNotMet: '前置條件未滿足',
|
requirementsNotMet: '前置條件未滿足',
|
||||||
current: '當前',
|
current: '當前',
|
||||||
level: '等級'
|
level: '等級',
|
||||||
|
gmModeActivated: 'GM 模式已啟用!請查看導航選單。'
|
||||||
},
|
},
|
||||||
errors: {
|
errors: {
|
||||||
requirementsNotMet: '不滿足前置條件',
|
requirementsNotMet: '不滿足前置條件',
|
||||||
insufficientResources: '資源不足',
|
insufficientResources: '資源不足',
|
||||||
insufficientFleetStorage: '艦隊倉儲空間不足',
|
insufficientFleetStorage: '艦隊倉儲空間不足',
|
||||||
shieldDomeLimit: '護盾罩數量限制',
|
shieldDomeLimit: '護盾罩數量限制',
|
||||||
|
missileSiloLimit: '導彈發射井容量已滿',
|
||||||
|
insufficientMissiles: '星際導彈數量不足',
|
||||||
|
invalidMissileCount: '導彈數量無效',
|
||||||
|
targetOutOfRange: '目標超出射程',
|
||||||
|
cannotAttackOwnPlanet: '不能攻擊自己的星球',
|
||||||
fleetMissionsFull: '艦隊任務槽位已滿',
|
fleetMissionsFull: '艦隊任務槽位已滿',
|
||||||
insufficientFleet: '艦隊數量不足',
|
insufficientFleet: '艦隊數量不足',
|
||||||
insufficientFuel: '燃料不足',
|
insufficientFuel: '燃料不足',
|
||||||
@@ -119,6 +126,7 @@ export default {
|
|||||||
roboticsFactory: '機器人工廠',
|
roboticsFactory: '機器人工廠',
|
||||||
naniteFactory: '納米工廠',
|
naniteFactory: '納米工廠',
|
||||||
shipyard: '船塢',
|
shipyard: '船塢',
|
||||||
|
hangar: '機庫',
|
||||||
researchLab: '研究實驗室',
|
researchLab: '研究實驗室',
|
||||||
metalStorage: '金屬倉庫',
|
metalStorage: '金屬倉庫',
|
||||||
crystalStorage: '晶體倉庫',
|
crystalStorage: '晶體倉庫',
|
||||||
@@ -159,6 +167,7 @@ export default {
|
|||||||
roboticsFactory: '加快建造速度',
|
roboticsFactory: '加快建造速度',
|
||||||
naniteFactory: '增加建造佇列數量,每級+1佇列(最多10級)',
|
naniteFactory: '增加建造佇列數量,每級+1佇列(最多10級)',
|
||||||
shipyard: '建造艦船',
|
shipyard: '建造艦船',
|
||||||
|
hangar: '專門用於擴展艦隊儲存容量,支援行星專業化發展',
|
||||||
researchLab: '研究科技',
|
researchLab: '研究科技',
|
||||||
metalStorage: '增加金屬儲存上限',
|
metalStorage: '增加金屬儲存上限',
|
||||||
crystalStorage: '增加晶體儲存上限',
|
crystalStorage: '增加晶體儲存上限',
|
||||||
@@ -166,8 +175,8 @@ export default {
|
|||||||
darkMatterCollector: '收集稀有的暗物質資源',
|
darkMatterCollector: '收集稀有的暗物質資源',
|
||||||
darkMatterTank: '增加暗物質儲存上限',
|
darkMatterTank: '增加暗物質儲存上限',
|
||||||
missileSilo: '存儲和發射導彈,每級可存儲10枚導彈',
|
missileSilo: '存儲和發射導彈,每級可存儲10枚導彈',
|
||||||
terraformer: '改造行星地形,每級增加5個可用空間',
|
terraformer: '改造行星地形,每級增加30個可用空間',
|
||||||
lunarBase: '增加月球可用空間,每級+5空間',
|
lunarBase: '增加月球可用空間,每級+30空間',
|
||||||
sensorPhalanx: '偵測周圍星系的艦隊活動',
|
sensorPhalanx: '偵測周圍星系的艦隊活動',
|
||||||
jumpGate: '瞬間傳送艦隊到其他月球',
|
jumpGate: '瞬間傳送艦隊到其他月球',
|
||||||
planetDestroyerFactory: '建造能夠摧毀行星的終極武器'
|
planetDestroyerFactory: '建造能夠摧毀行星的終極武器'
|
||||||
@@ -193,10 +202,10 @@ export default {
|
|||||||
lightFighter: '基礎戰鬥單位',
|
lightFighter: '基礎戰鬥單位',
|
||||||
heavyFighter: '重裝戰鬥機',
|
heavyFighter: '重裝戰鬥機',
|
||||||
cruiser: '中型戰艦,攻守平衡',
|
cruiser: '中型戰艦,攻守平衡',
|
||||||
battleship: '強力戰艦',
|
battleship: '主力重型戰艦,擁有強大的火力和防護',
|
||||||
battlecruiser: '快速強大的戰鬥艦船,擅長攻擊戰列艦',
|
battlecruiser: '快速強大的戰鬥艦船,擅長攻擊戰列艦',
|
||||||
bomber: '專門對付防禦設施的轟炸艦',
|
bomber: '專門對付防禦設施的轟炸艦',
|
||||||
destroyer: '擅長摧毀大型艦船的獵殺者',
|
destroyer: '專業反大型艦船戰艦,高火力低防護',
|
||||||
smallCargo: '運輸少量資源',
|
smallCargo: '運輸少量資源',
|
||||||
largeCargo: '運輸大量資源',
|
largeCargo: '運輸大量資源',
|
||||||
colonyShip: '用於殖民新星球',
|
colonyShip: '用於殖民新星球',
|
||||||
@@ -285,7 +294,7 @@ export default {
|
|||||||
impulseDrive: '中級推進技術',
|
impulseDrive: '中級推進技術',
|
||||||
hyperspaceDrive: '高級推進技術',
|
hyperspaceDrive: '高級推進技術',
|
||||||
darkMatterTechnology: '研究暗物質的性質和應用',
|
darkMatterTechnology: '研究暗物質的性質和應用',
|
||||||
terraformingTechnology: '研究行星地形改造技術,每級為所有行星增加3個可用空間',
|
terraformingTechnology: '研究行星地形改造技術,每級為所有行星增加30個可用空間',
|
||||||
planetDestructionTech: '研究如何摧毀整個行星的恐怖技術'
|
planetDestructionTech: '研究如何摧毀整個行星的恐怖技術'
|
||||||
},
|
},
|
||||||
officers: {
|
officers: {
|
||||||
@@ -308,16 +317,20 @@ export default {
|
|||||||
darkMatterSpecialist: '提升暗物質採集效率'
|
darkMatterSpecialist: '提升暗物質採集效率'
|
||||||
},
|
},
|
||||||
queue: {
|
queue: {
|
||||||
|
title: '建造佇列',
|
||||||
|
empty: '當前沒有進行中的任務',
|
||||||
buildQueue: '建造佇列',
|
buildQueue: '建造佇列',
|
||||||
researchQueue: '研究佇列',
|
researchQueue: '研究佇列',
|
||||||
building: '建造中',
|
building: '建造中',
|
||||||
researching: '研究中',
|
researching: '研究中',
|
||||||
|
demolishing: '拆除中',
|
||||||
remaining: '剩餘時間',
|
remaining: '剩餘時間',
|
||||||
cancel: '取消',
|
cancel: '取消',
|
||||||
cancelBuild: '取消建造',
|
cancelBuild: '取消建造',
|
||||||
cancelResearch: '取消研究',
|
cancelResearch: '取消研究',
|
||||||
confirmCancel: '確定要取消嗎?將返還50%的資源。',
|
confirmCancel: '確定要取消嗎?將返還50%的資源。',
|
||||||
level: '等級',
|
level: '等級',
|
||||||
|
gmModeActivated: '',
|
||||||
upgradeToLevel: '升級到等級'
|
upgradeToLevel: '升級到等級'
|
||||||
},
|
},
|
||||||
overview: {
|
overview: {
|
||||||
@@ -338,6 +351,7 @@ export default {
|
|||||||
usedSpace: '已用空間',
|
usedSpace: '已用空間',
|
||||||
spaceUsage: '佔用空間',
|
spaceUsage: '佔用空間',
|
||||||
level: '等級',
|
level: '等級',
|
||||||
|
gmModeActivated: '',
|
||||||
upgradeCost: '升級消耗',
|
upgradeCost: '升級消耗',
|
||||||
buildTime: '建造時間',
|
buildTime: '建造時間',
|
||||||
upgrade: '升級',
|
upgrade: '升級',
|
||||||
@@ -349,8 +363,8 @@ export default {
|
|||||||
demolishRefund: '拆除返還',
|
demolishRefund: '拆除返還',
|
||||||
demolishFailed: '拆除失敗',
|
demolishFailed: '拆除失敗',
|
||||||
demolishFailedMessage: '無法拆除該建築,請檢查建造隊列是否已滿或建築等級是否為0。',
|
demolishFailedMessage: '無法拆除該建築,請檢查建造隊列是否已滿或建築等級是否為0。',
|
||||||
confirmDemolish: '',
|
confirmDemolish: '確認拆除',
|
||||||
confirmDemolishMessage: ''
|
confirmDemolishMessage: '確定要拆除以下建築嗎?'
|
||||||
},
|
},
|
||||||
researchView: {
|
researchView: {
|
||||||
title: '研究',
|
title: '研究',
|
||||||
@@ -362,6 +376,7 @@ export default {
|
|||||||
},
|
},
|
||||||
shipyard: {
|
shipyard: {
|
||||||
attack: '攻擊力',
|
attack: '攻擊力',
|
||||||
|
missileAttack: '導彈攻擊',
|
||||||
shield: '護盾',
|
shield: '護盾',
|
||||||
armor: '裝甲',
|
armor: '裝甲',
|
||||||
speed: '速度',
|
speed: '速度',
|
||||||
@@ -379,6 +394,7 @@ export default {
|
|||||||
title: '船塢',
|
title: '船塢',
|
||||||
fleetStorage: '艦隊倉儲',
|
fleetStorage: '艦隊倉儲',
|
||||||
attack: '攻擊力',
|
attack: '攻擊力',
|
||||||
|
missileAttack: '導彈攻擊',
|
||||||
shield: '護盾',
|
shield: '護盾',
|
||||||
speed: '速度',
|
speed: '速度',
|
||||||
cargoCapacity: '載貨量',
|
cargoCapacity: '載貨量',
|
||||||
@@ -393,6 +409,7 @@ export default {
|
|||||||
},
|
},
|
||||||
defense: {
|
defense: {
|
||||||
attack: '攻擊力',
|
attack: '攻擊力',
|
||||||
|
missileAttack: '導彈攻擊',
|
||||||
shield: '護盾',
|
shield: '護盾',
|
||||||
armor: '裝甲',
|
armor: '裝甲',
|
||||||
buildCost: '建造成本',
|
buildCost: '建造成本',
|
||||||
@@ -406,6 +423,7 @@ export default {
|
|||||||
defenseView: {
|
defenseView: {
|
||||||
title: '防禦設施',
|
title: '防禦設施',
|
||||||
attack: '攻擊力',
|
attack: '攻擊力',
|
||||||
|
missileAttack: '導彈攻擊',
|
||||||
shield: '護盾',
|
shield: '護盾',
|
||||||
armor: '裝甲',
|
armor: '裝甲',
|
||||||
buildTime: '建造時間',
|
buildTime: '建造時間',
|
||||||
@@ -415,6 +433,7 @@ export default {
|
|||||||
totalCost: '總成本',
|
totalCost: '總成本',
|
||||||
build: '建造',
|
build: '建造',
|
||||||
shieldDomeBuilt: '護盾罩已建造',
|
shieldDomeBuilt: '護盾罩已建造',
|
||||||
|
missileCapacity: '導彈容量',
|
||||||
inputError: '輸入錯誤',
|
inputError: '輸入錯誤',
|
||||||
inputErrorMessage: '請輸入建造數量!',
|
inputErrorMessage: '請輸入建造數量!',
|
||||||
buildFailed: '建造失敗',
|
buildFailed: '建造失敗',
|
||||||
@@ -427,6 +446,7 @@ export default {
|
|||||||
flightMissions: '飛行任務',
|
flightMissions: '飛行任務',
|
||||||
currentPlanetFleet: '當前星球艦隊',
|
currentPlanetFleet: '當前星球艦隊',
|
||||||
attack: '攻擊',
|
attack: '攻擊',
|
||||||
|
missileAttack: '導彈攻擊',
|
||||||
shield: '護盾',
|
shield: '護盾',
|
||||||
armor: '裝甲',
|
armor: '裝甲',
|
||||||
speed: '速度',
|
speed: '速度',
|
||||||
@@ -461,6 +481,11 @@ export default {
|
|||||||
arrivalTime: '到達時間',
|
arrivalTime: '到達時間',
|
||||||
returnTime: '返回時間',
|
returnTime: '返回時間',
|
||||||
recallFleet: '召回艦隊',
|
recallFleet: '召回艦隊',
|
||||||
|
abortMission: '',
|
||||||
|
abortMissionTitle: '',
|
||||||
|
abortMissionWarning: '',
|
||||||
|
abortMissionSuccess: '',
|
||||||
|
abortMissionSuccessMessage: '',
|
||||||
sendFailed: '派遣失敗',
|
sendFailed: '派遣失敗',
|
||||||
sendFailedMessage: '請檢查艦隊數量、燃料是否充足,或載貨量是否超出限制。',
|
sendFailedMessage: '請檢查艦隊數量、燃料是否充足,或載貨量是否超出限制。',
|
||||||
recallFailed: '召回失敗',
|
recallFailed: '召回失敗',
|
||||||
@@ -521,25 +546,36 @@ export default {
|
|||||||
selectSystem: '選擇星系',
|
selectSystem: '選擇星系',
|
||||||
view: '查看',
|
view: '查看',
|
||||||
myPlanet: '我的星球',
|
myPlanet: '我的星球',
|
||||||
myPlanets: '我的星球',
|
myPlanets: '查看我的星系',
|
||||||
npcPlanets: 'NPC星球',
|
npcPlanets: 'NPC星球',
|
||||||
selectPlanetToView: '選擇要查看的星球',
|
selectPlanetToView: '選擇星球以查看其所在星系',
|
||||||
totalPositions: '共10個星球位置',
|
totalPositions: '共10個星球位置',
|
||||||
mine: '我的',
|
mine: '我的',
|
||||||
hostile: '敵對',
|
hostile: '敵對',
|
||||||
emptySlot: '空位 - 可殖民',
|
emptySlot: '空位 - 可殖民',
|
||||||
scout: '偵察',
|
scout: '偵察',
|
||||||
attack: '攻擊',
|
attack: '攻擊',
|
||||||
|
missileAttack: '導彈攻擊',
|
||||||
colonize: '殖民',
|
colonize: '殖民',
|
||||||
switch: '切換',
|
switch: '切換',
|
||||||
recycle: '回收',
|
recycle: '回收',
|
||||||
debrisField: '殘骸場',
|
debrisField: '殘骸場',
|
||||||
scoutPlanetTitle: '偵察星球',
|
scoutPlanetTitle: '偵察星球',
|
||||||
attackPlanetTitle: '攻擊星球',
|
attackPlanetTitle: '攻擊星球',
|
||||||
|
missileAttackTitle: '導彈攻擊',
|
||||||
colonizePlanetTitle: '殖民星球',
|
colonizePlanetTitle: '殖民星球',
|
||||||
recyclePlanetTitle: '回收殘骸',
|
recyclePlanetTitle: '回收殘骸',
|
||||||
scoutPlanetMessage: '確定要派遣間諜探測器偵察星球 [{coordinates}] 嗎?\n\n請前往艦隊頁面選擇艦船並派遣。',
|
scoutPlanetMessage: '確定要派遣間諜探測器偵察星球 [{coordinates}] 嗎?\n\n請前往艦隊頁面選擇艦船並派遣。',
|
||||||
attackPlanetMessage: '確定要攻擊星球 [{coordinates}] 嗎?\n\n請前往艦隊頁面選擇艦船並派遣。',
|
attackPlanetMessage: '確定要攻擊星球 [{coordinates}] 嗎?\n\n請前往艦隊頁面選擇艦船並派遣。',
|
||||||
|
missileAttackMessage: '向星球 [{coordinates}] 發射星際導彈',
|
||||||
|
missileCount: '導彈數量',
|
||||||
|
availableMissiles: '可用導彈',
|
||||||
|
missileRange: '導彈射程',
|
||||||
|
systems: '星系',
|
||||||
|
distance: '距離',
|
||||||
|
flightTime: '飛行時間',
|
||||||
|
launchMissile: '發射',
|
||||||
|
cancel: '取消',
|
||||||
colonizePlanetMessage: '確定要殖民位置 [{coordinates}] 嗎?\n\n請前往艦隊頁面派遣殖民船。',
|
colonizePlanetMessage: '確定要殖民位置 [{coordinates}] 嗎?\n\n請前往艦隊頁面派遣殖民船。',
|
||||||
recyclePlanetMessage: '確定要回收位置 [{coordinates}] 的殘骸嗎?\n\n請前往艦隊頁面派遣回收船。',
|
recyclePlanetMessage: '確定要回收位置 [{coordinates}] 的殘骸嗎?\n\n請前往艦隊頁面派遣回收船。',
|
||||||
sendGift: '贈送禮物',
|
sendGift: '贈送禮物',
|
||||||
@@ -552,10 +588,12 @@ export default {
|
|||||||
battles: '戰鬥',
|
battles: '戰鬥',
|
||||||
spy: '偵查',
|
spy: '偵查',
|
||||||
npc: 'NPC',
|
npc: 'NPC',
|
||||||
|
diplomacy: '',
|
||||||
battleReports: '戰鬥報告',
|
battleReports: '戰鬥報告',
|
||||||
spyReports: '間諜報告',
|
spyReports: '間諜報告',
|
||||||
noBattleReports: '暫無戰鬥報告',
|
noBattleReports: '暫無戰鬥報告',
|
||||||
noSpyReports: '暫無間諜報告',
|
noSpyReports: '暫無間諜報告',
|
||||||
|
noDiplomaticReports: '',
|
||||||
battleReport: '戰鬥報告',
|
battleReport: '戰鬥報告',
|
||||||
spyReport: '間諜報告',
|
spyReport: '間諜報告',
|
||||||
victory: '勝利',
|
victory: '勝利',
|
||||||
@@ -611,7 +649,38 @@ export default {
|
|||||||
hostile: '對方對你有敵意,不接受禮物',
|
hostile: '對方對你有敵意,不接受禮物',
|
||||||
neutral_distrust: '對方對你缺乏信任',
|
neutral_distrust: '對方對你缺乏信任',
|
||||||
polite_decline: '對方禮貌地拒絕了'
|
polite_decline: '對方禮貌地拒絕了'
|
||||||
}
|
},
|
||||||
|
// Spied notification dialog
|
||||||
|
spiedNotificationDetails: '',
|
||||||
|
spyDetected: '',
|
||||||
|
detectionResult: '',
|
||||||
|
detectionSuccess: '',
|
||||||
|
spiedNotificationMessage: '',
|
||||||
|
spiedNotificationTip: '',
|
||||||
|
viewInGalaxy: '',
|
||||||
|
// Mission report dialog
|
||||||
|
missionReportDetails: '',
|
||||||
|
missionSuccess: '',
|
||||||
|
missionFailed: '',
|
||||||
|
origin: '',
|
||||||
|
destination: '',
|
||||||
|
missionDetails: '',
|
||||||
|
transportedResources: '',
|
||||||
|
recycledResources: '',
|
||||||
|
remainingDebris: '',
|
||||||
|
newPlanet: '',
|
||||||
|
// NPC activity dialog
|
||||||
|
npcActivityDetails: '',
|
||||||
|
activityType: {
|
||||||
|
recycle: ''
|
||||||
|
},
|
||||||
|
activityLocation: '',
|
||||||
|
position: '',
|
||||||
|
nearPlanet: '',
|
||||||
|
activityDescription: '',
|
||||||
|
npcActivityMessage: '',
|
||||||
|
arrivalTime: '',
|
||||||
|
npcActivityTip: ''
|
||||||
},
|
},
|
||||||
missionReports: {
|
missionReports: {
|
||||||
transportSuccess: '運輸任務成功完成',
|
transportSuccess: '運輸任務成功完成',
|
||||||
@@ -692,10 +761,24 @@ export default {
|
|||||||
gamePaused: '遊戲已暫停',
|
gamePaused: '遊戲已暫停',
|
||||||
gameResumed: '遊戲已恢復',
|
gameResumed: '遊戲已恢復',
|
||||||
playerName: '玩家名稱',
|
playerName: '玩家名稱',
|
||||||
gameSpeed: '遊戲速度',
|
gameSpeed: '資源產出速度',
|
||||||
gameSpeedDesc: '目前遊戲速度倍率',
|
gameSpeedDesc: '目前資源產出速度倍率',
|
||||||
|
speedChanged: '資源產出速度已更改為 {speed}x',
|
||||||
|
speedReset: '資源產出速度已重置為 1x',
|
||||||
|
reset: '重置',
|
||||||
about: '關於',
|
about: '關於',
|
||||||
version: '版本',
|
version: '版本',
|
||||||
|
latestVersion: '最新版本',
|
||||||
|
checkUpdate: '檢查更新',
|
||||||
|
checking: '檢查中...',
|
||||||
|
newVersionAvailable: '發現新版本 {version}',
|
||||||
|
upToDate: '已是最新版本',
|
||||||
|
checkUpdateCooldown: '請稍後再試(5分鐘冷卻時間)',
|
||||||
|
checkUpdateFailed: '檢查更新失敗,請檢查網路連線',
|
||||||
|
viewUpdate: '查看更新',
|
||||||
|
updateAvailable: '有新版本可用。點擊查看更新內容。',
|
||||||
|
download: '下載',
|
||||||
|
goToDownload: '前往下載',
|
||||||
buildDate: '建置日期',
|
buildDate: '建置日期',
|
||||||
community: '社群',
|
community: '社群',
|
||||||
github: 'GitHub 儲存庫',
|
github: 'GitHub 儲存庫',
|
||||||
@@ -714,6 +797,8 @@ export default {
|
|||||||
officers: '軍官',
|
officers: '軍官',
|
||||||
modifyResources: '修改資源',
|
modifyResources: '修改資源',
|
||||||
resourcesDesc: '快速修改星球資源數量',
|
resourcesDesc: '快速修改星球資源數量',
|
||||||
|
maxAllResources: '',
|
||||||
|
maxAllResourcesSuccess: '',
|
||||||
modifyBuildings: '修改建築',
|
modifyBuildings: '修改建築',
|
||||||
buildingsDesc: '快速設定建築等級',
|
buildingsDesc: '快速設定建築等級',
|
||||||
modifyResearch: '修改科技',
|
modifyResearch: '修改科技',
|
||||||
@@ -734,16 +819,30 @@ export default {
|
|||||||
testSpy: '測試偵查',
|
testSpy: '測試偵查',
|
||||||
testAttack: '測試攻擊',
|
testAttack: '測試攻擊',
|
||||||
testSpyAndAttack: '測試偵查&攻擊',
|
testSpyAndAttack: '測試偵查&攻擊',
|
||||||
|
testSpyMessage: '點擊確認以加速偵查任務',
|
||||||
|
testAttackMessage: '點擊確認以加速攻擊任務',
|
||||||
|
testSpyAndAttackMessage: '點擊確認以加速任務執行',
|
||||||
initializeFleet: '初始化NPC艦隊',
|
initializeFleet: '初始化NPC艦隊',
|
||||||
accelerateMissions: '加速所有任務(5秒)',
|
accelerateMissions: '加速所有任務(5秒)',
|
||||||
selectNPCFirst: '請先選擇一個NPC',
|
selectNPCFirst: '請先選擇一個NPC',
|
||||||
npcNoProbes: 'NPC沒有間諜探測器',
|
npcNoProbes: 'NPC沒有間諜探測器',
|
||||||
npcNoSpyReport: 'NPC需要先偵查',
|
npcNoSpyReport: 'NPC需要先偵查',
|
||||||
npcMissionFailed: '創建任務失敗',
|
npcMissionFailed: '創建任務失敗',
|
||||||
|
npcNoPlanets: 'NPC沒有星球',
|
||||||
|
npcWillSpyIn5s: '{npcName}將在5秒後偵查',
|
||||||
|
npcWillAttackIn5s: '{npcName}將在5秒後攻擊',
|
||||||
|
npcWillSpyAndAttack: '{npcName}將在5秒後偵查,10秒後攻擊',
|
||||||
|
acceleratedMissions: '已加速{count}個任務至5秒後',
|
||||||
|
npcFleetInitialized: '{npcName}艦隊已初始化',
|
||||||
|
npcFleetDetails: '100 間諜探測器\n500 輕型戰機\n300 重型戰機\n200 巡洋艦\n100 戰列艦\n50 轟炸機\n30 毀滅者\n20 戰列巡洋艦',
|
||||||
dangerZone: '危險區域',
|
dangerZone: '危險區域',
|
||||||
dangerZoneDesc: '以下操作不可撤銷,請謹慎操作',
|
dangerZoneDesc: '以下操作不可撤銷,請謹慎操作',
|
||||||
resetGame: '重置遊戲',
|
resetGame: '重置遊戲',
|
||||||
resetGameConfirm: '確定要重置遊戲嗎?這將刪除所有資料!'
|
resetGameConfirm: '確定要重置遊戲嗎?這將刪除所有資料!',
|
||||||
|
completeAllQueues: '',
|
||||||
|
completeAllQueuesDesc: '',
|
||||||
|
completeQueues: '',
|
||||||
|
completeQueuesSuccess: ''
|
||||||
},
|
},
|
||||||
alerts: {
|
alerts: {
|
||||||
npcSpyIncoming: 'NPC偵查即將到達',
|
npcSpyIncoming: 'NPC偵查即將到達',
|
||||||
@@ -773,6 +872,10 @@ export default {
|
|||||||
recentEvents: '最近事件',
|
recentEvents: '最近事件',
|
||||||
recentEventsDescription: '最近的外交活動記錄',
|
recentEventsDescription: '最近的外交活動記錄',
|
||||||
ago: '前',
|
ago: '前',
|
||||||
|
notifications: '',
|
||||||
|
markAllRead: '',
|
||||||
|
noReports: '',
|
||||||
|
viewAll: '',
|
||||||
status: {
|
status: {
|
||||||
friendly: '友好',
|
friendly: '友好',
|
||||||
neutral: '中立',
|
neutral: '中立',
|
||||||
@@ -788,19 +891,93 @@ export default {
|
|||||||
viewPlanets: '查看星球'
|
viewPlanets: '查看星球'
|
||||||
},
|
},
|
||||||
lastEvent: '最近事件',
|
lastEvent: '最近事件',
|
||||||
|
reportDetails: '外交報告詳情',
|
||||||
|
eventDescription: '事件描述',
|
||||||
|
reputationChange: '好感度變化',
|
||||||
|
before: '之前',
|
||||||
|
after: '之後',
|
||||||
|
statusChange: '關係狀態變化',
|
||||||
|
viewDiplomacy: '查看外交頁面',
|
||||||
events: {
|
events: {
|
||||||
gift: '已贈送禮物',
|
gift: '已贈送禮物',
|
||||||
attack: '攻擊',
|
attack: '攻擊',
|
||||||
|
missileAttack: '導彈攻擊',
|
||||||
allyAttacked: '盟友被攻擊',
|
allyAttacked: '盟友被攻擊',
|
||||||
spy: '間諜活動',
|
spy: '間諜活動',
|
||||||
stealDebris: '掠奪殘骸'
|
stealDebris: '掠奪殘骸'
|
||||||
|
},
|
||||||
|
reports: {
|
||||||
|
giftedResources: '贈送了 {metal}金屬 {crystal}晶體 {deuterium}氘',
|
||||||
|
receivedGiftFromPlayer: '收到玩家的禮物',
|
||||||
|
giftedToNpc: '你向{npcName}贈送了資源。好感度+{reputation}',
|
||||||
|
rejectedPlayerGift: '拒絕了玩家的禮物',
|
||||||
|
npcRejectedGift: '{npcName}拒絕了你的禮物。好感度{reputation}',
|
||||||
|
attackedNpc: '攻擊了{npcName}',
|
||||||
|
wasAttackedByPlayer: '被玩家攻擊',
|
||||||
|
youAttackedNpc: '你攻擊了{npcName}',
|
||||||
|
playerAttackedAlly: '玩家攻擊了盟友{allyName}',
|
||||||
|
allyDispleased: '{allyName}對你攻擊盟友{targetName}感到不滿',
|
||||||
|
wasSpiedByPlayer: '被玩家偵查(被發現:{detected})',
|
||||||
|
spyDetected: '你的偵查被{npcName}發現了',
|
||||||
|
stoleDebrisFromTerritory: '從{npcName}的領地掠奪了殘骸',
|
||||||
|
playerStoleDebris: '玩家從領地掠奪了殘骸',
|
||||||
|
recycledDebrisNearNpc: '你在{npcName}的星球附近回收了殘骸。他們很不高興。',
|
||||||
|
giftedResourcesToPlayer: '向玩家贈送了資源',
|
||||||
|
receivedGiftFromNpc: '收到了{npcName}的禮物',
|
||||||
|
acceptedGiftFromNpc: '你接受了{npcName}的禮物:{metal}金屬 {crystal}晶體 {deuterium}氘',
|
||||||
|
playerRejectedGift: '玩家拒絕了禮物',
|
||||||
|
rejectedGiftFromNpc: '你拒絕了{npcName}的禮物。好感度{reputation}',
|
||||||
|
destroyedNpcPlanet: '摧毀了{npcName}的{planetName}',
|
||||||
|
playerDestroyedPlanet: '玩家摧毀了{planetName}',
|
||||||
|
youDestroyedNpcPlanet: '你摧毀了{npcName}的{planetName}。好感度{reputation}',
|
||||||
|
playerDestroyedAllyPlanet: '玩家摧毀了盟友{allyName}的{planetName}',
|
||||||
|
allyOutraged: '{allyName}對你摧毀盟友{targetName}的{planetName}感到憤怒',
|
||||||
|
npcEliminated: 'NPC {npcName}已被徹底消滅',
|
||||||
|
npcEliminatedMessage: '你消滅了{npcName}的所有星球!該勢力已被徹底摧毀。'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pagination: {
|
pagination: {
|
||||||
previous: '上一頁',
|
previous: '上一頁',
|
||||||
next: '下一頁',
|
next: '下一頁',
|
||||||
|
gotIt: '',
|
||||||
first: '首頁',
|
first: '首頁',
|
||||||
last: '末頁',
|
last: '末頁',
|
||||||
page: '第 {page} 頁'
|
page: '第 {page} 頁'
|
||||||
|
},
|
||||||
|
notFound: {
|
||||||
|
title: '找不到頁面',
|
||||||
|
description: '抱歉,您訪問的頁面不存在',
|
||||||
|
goHome: '返回首頁'
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
days: '天',
|
||||||
|
hours: '小時',
|
||||||
|
minutes: '分鐘',
|
||||||
|
seconds: '秒'
|
||||||
|
},
|
||||||
|
tutorial: {
|
||||||
|
welcome: {
|
||||||
|
title: '歡迎來到 OGame',
|
||||||
|
content: '歡迎,指揮官!讓我們從基礎開始,建立您的宇宙帝國。'
|
||||||
|
},
|
||||||
|
buildSolarPlant: {
|
||||||
|
title: '建造太陽能電站',
|
||||||
|
content: '首先建造太陽能電站!它為您的星球提供能量。沒有能量,其他資源建築無法運作。這是最重要的第一步。'
|
||||||
|
},
|
||||||
|
waitBuild: {
|
||||||
|
title: '建造佇列',
|
||||||
|
content:
|
||||||
|
'您的建築現在在建造佇列中。點擊右上角的佇列圖示可以查看所有正在進行的建造和研究任務。建築需要時間完成,但您可以在等待時繼續操作。'
|
||||||
|
},
|
||||||
|
mobile: {
|
||||||
|
welcome: {
|
||||||
|
title: '歡迎來到 OGame(移動版)',
|
||||||
|
content: '歡迎,指揮官!這是專為觸控螢幕設計的簡化教程。我們將快速介紹核心功能,讓您開始建設帝國。'
|
||||||
|
},
|
||||||
|
waitBuild: {
|
||||||
|
title: '建造佇列',
|
||||||
|
content: '點擊右上角的佇列圖示可以查看建造進度。您可以繼續瀏覽其他頁面,建造會在背景進行。'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import type { Fleet, Resources, BattleResult, Officer, TechnologyType } from '@/types/game'
|
import type { Fleet, Resources, BattleResult, Officer, TechnologyType } from '@/types/game'
|
||||||
import { DefenseType, OfficerType } from '@/types/game'
|
import { DefenseType, OfficerType } from '@/types/game'
|
||||||
import { workerManager } from '@/workers/workerManager'
|
import { workerManager } from '@/workers/workerManager'
|
||||||
|
import { MOON_CONFIG } from '@/config/gameConfig'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行战斗模拟
|
* 执行战斗模拟
|
||||||
@@ -60,7 +61,7 @@ export const simulateBattle = async (
|
|||||||
|
|
||||||
// 计算月球生成概率(根据残骸场总量)
|
// 计算月球生成概率(根据残骸场总量)
|
||||||
const totalDebris = debrisField.metal + debrisField.crystal
|
const totalDebris = debrisField.metal + debrisField.crystal
|
||||||
const moonChance = Math.min(totalDebris / 100000, 0.2) // 最高20%概率
|
const moonChance = Math.min(MOON_CONFIG.baseChance + Math.floor(totalDebris / MOON_CONFIG.chancePerDebris), MOON_CONFIG.maxChance) / 100 // 转换为0-1的概率
|
||||||
|
|
||||||
// 生成战斗报告
|
// 生成战斗报告
|
||||||
const battleResult: BattleResult = {
|
const battleResult: BattleResult = {
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ import { BuildingType, TechnologyType, ShipType, DefenseType } from '@/types/gam
|
|||||||
import { BUILDINGS } from '@/config/gameConfig'
|
import { BUILDINGS } from '@/config/gameConfig'
|
||||||
import * as pointsLogic from './pointsLogic'
|
import * as pointsLogic from './pointsLogic'
|
||||||
|
|
||||||
|
// 用于生成唯一ID的计数器
|
||||||
|
let queueIdCounter = 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算建筑升级成本
|
* 计算建筑升级成本
|
||||||
*/
|
*/
|
||||||
@@ -102,8 +105,9 @@ export const checkSpaceAvailable = (planet: Planet, buildingType: BuildingType):
|
|||||||
*/
|
*/
|
||||||
export const createBuildQueueItem = (buildingType: BuildingType, targetLevel: number, buildTime: number): BuildQueueItem => {
|
export const createBuildQueueItem = (buildingType: BuildingType, targetLevel: number, buildTime: number): BuildQueueItem => {
|
||||||
const now = Date.now()
|
const now = Date.now()
|
||||||
|
queueIdCounter++
|
||||||
return {
|
return {
|
||||||
id: `build_${now}`,
|
id: `build_${now}_${queueIdCounter}`,
|
||||||
type: 'building',
|
type: 'building',
|
||||||
itemType: buildingType,
|
itemType: buildingType,
|
||||||
targetLevel,
|
targetLevel,
|
||||||
@@ -212,8 +216,9 @@ export const calculateDemolishTime = (
|
|||||||
*/
|
*/
|
||||||
export const createDemolishQueueItem = (buildingType: BuildingType, currentLevel: number, demolishTime: number): BuildQueueItem => {
|
export const createDemolishQueueItem = (buildingType: BuildingType, currentLevel: number, demolishTime: number): BuildQueueItem => {
|
||||||
const now = Date.now()
|
const now = Date.now()
|
||||||
|
queueIdCounter++
|
||||||
return {
|
return {
|
||||||
id: `demolish_${now}`,
|
id: `demolish_${now}_${queueIdCounter}`,
|
||||||
type: 'demolish',
|
type: 'demolish',
|
||||||
itemType: buildingType,
|
itemType: buildingType,
|
||||||
targetLevel: currentLevel - 1, // 目标等级为当前等级-1
|
targetLevel: currentLevel - 1, // 目标等级为当前等级-1
|
||||||
|
|||||||
@@ -23,6 +23,14 @@ export const validateBuildingUpgrade = (
|
|||||||
const cost = buildingLogic.calculateBuildingCost(buildingType, targetLevel)
|
const cost = buildingLogic.calculateBuildingCost(buildingType, targetLevel)
|
||||||
const buildingConfig = BUILDINGS[buildingType]
|
const buildingConfig = BUILDINGS[buildingType]
|
||||||
|
|
||||||
|
// 检查队列中是否已存在该建筑的升级或拆除任务
|
||||||
|
const existingQueueItem = planet.buildQueue.find(
|
||||||
|
item => (item.type === 'building' || item.type === 'demolish') && item.itemType === buildingType
|
||||||
|
)
|
||||||
|
if (existingQueueItem) {
|
||||||
|
return { valid: false, reason: 'errors.buildingAlreadyInQueue' }
|
||||||
|
}
|
||||||
|
|
||||||
// 检查星球/月球限制
|
// 检查星球/月球限制
|
||||||
if (buildingConfig.planetOnly && planet.isMoon) {
|
if (buildingConfig.planetOnly && planet.isMoon) {
|
||||||
return { valid: false, reason: 'errors.planetOnly' }
|
return { valid: false, reason: 'errors.planetOnly' }
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { DIPLOMATIC_CONFIG } from '@/config/gameConfig'
|
import { DIPLOMATIC_CONFIG } from '@/config/gameConfig'
|
||||||
|
import { locales, type Locale } from '@/locales'
|
||||||
import type {
|
import type {
|
||||||
DiplomaticRelation,
|
DiplomaticRelation,
|
||||||
RelationStatus,
|
RelationStatus,
|
||||||
@@ -13,6 +14,7 @@ import type {
|
|||||||
Resources,
|
Resources,
|
||||||
Player,
|
Player,
|
||||||
NPC,
|
NPC,
|
||||||
|
Planet,
|
||||||
FleetMission,
|
FleetMission,
|
||||||
BattleResult,
|
BattleResult,
|
||||||
Position,
|
Position,
|
||||||
@@ -21,6 +23,37 @@ import type {
|
|||||||
} from '@/types/game'
|
} from '@/types/game'
|
||||||
import { RelationStatus as RS, DiplomaticEventType as DET } from '@/types/game'
|
import { RelationStatus as RS, DiplomaticEventType as DET } from '@/types/game'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取翻译文本的辅助函数
|
||||||
|
* @param key 翻译键
|
||||||
|
* @param locale 语言代码
|
||||||
|
* @param params 参数
|
||||||
|
* @returns 翻译后的文本
|
||||||
|
*/
|
||||||
|
const t = (key: string, locale: Locale, params?: Record<string, string | number>): string => {
|
||||||
|
const keys = key.split('.')
|
||||||
|
let value: any = locales[locale]
|
||||||
|
|
||||||
|
for (const k of keys) {
|
||||||
|
if (value && typeof value === 'object' && k in value) {
|
||||||
|
value = value[k]
|
||||||
|
} else {
|
||||||
|
return key // 如果找不到翻译,返回原始 key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = typeof value === 'string' ? value : key
|
||||||
|
|
||||||
|
// 替换参数占位符
|
||||||
|
if (params) {
|
||||||
|
Object.entries(params).forEach(([paramKey, paramValue]) => {
|
||||||
|
result = result.replace(new RegExp(`\\{${paramKey}\\}`, 'g'), String(paramValue))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据好感度值计算关系状态
|
* 根据好感度值计算关系状态
|
||||||
* @param reputation 好感度值 (-100 到 +100)
|
* @param reputation 好感度值 (-100 到 +100)
|
||||||
@@ -118,8 +151,11 @@ export const calculateGiftReputationGain = (resources: Resources): number => {
|
|||||||
const baseGain = REPUTATION_CHANGES.GIFT_BASE
|
const baseGain = REPUTATION_CHANGES.GIFT_BASE
|
||||||
const valueGain = Math.floor(totalValue / 1000) * REPUTATION_CHANGES.GIFT_PER_1K_RESOURCES
|
const valueGain = Math.floor(totalValue / 1000) * REPUTATION_CHANGES.GIFT_PER_1K_RESOURCES
|
||||||
|
|
||||||
|
// 确保达到门槛的礼物至少获得1点好感度
|
||||||
|
const totalGain = Math.max(baseGain + valueGain, 1)
|
||||||
|
|
||||||
// 限制在最大值范围内
|
// 限制在最大值范围内
|
||||||
return Math.min(baseGain + valueGain, REPUTATION_CHANGES.GIFT_MAX_SINGLE)
|
return Math.min(totalGain, REPUTATION_CHANGES.GIFT_MAX_SINGLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -173,16 +209,22 @@ export const calculateNPCRejectionProbability = (npc: NPC, player: Player): numb
|
|||||||
* @param mission 舰队任务
|
* @param mission 舰队任务
|
||||||
* @param player 玩家
|
* @param player 玩家
|
||||||
* @param targetNpc 目标NPC
|
* @param targetNpc 目标NPC
|
||||||
|
* @param locale 语言代码
|
||||||
* @returns { accepted: boolean, reputationGain?: number }
|
* @returns { accepted: boolean, reputationGain?: number }
|
||||||
*/
|
*/
|
||||||
export const handleGiftArrival = (mission: FleetMission, player: Player, targetNpc: NPC): { accepted: boolean; reputationGain?: number } => {
|
export const handleGiftArrival = (
|
||||||
|
mission: FleetMission,
|
||||||
|
player: Player,
|
||||||
|
targetNpc: NPC,
|
||||||
|
locale: Locale
|
||||||
|
): { accepted: boolean; reputationGain?: number } => {
|
||||||
// 计算NPC拒绝概率
|
// 计算NPC拒绝概率
|
||||||
const rejectionProb = calculateNPCRejectionProbability(targetNpc, player)
|
const rejectionProb = calculateNPCRejectionProbability(targetNpc, player)
|
||||||
const isRejected = Math.random() < rejectionProb
|
const isRejected = Math.random() < rejectionProb
|
||||||
|
|
||||||
if (isRejected) {
|
if (isRejected) {
|
||||||
// NPC拒绝礼物
|
// NPC拒绝礼物
|
||||||
handleGiftRejection(player, targetNpc, mission.cargo)
|
handleGiftRejection(player, targetNpc, mission.cargo, locale)
|
||||||
return { accepted: false }
|
return { accepted: false }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,7 +242,11 @@ export const handleGiftArrival = (mission: FleetMission, player: Player, targetN
|
|||||||
relation,
|
relation,
|
||||||
reputationGain,
|
reputationGain,
|
||||||
DET.GiftResources,
|
DET.GiftResources,
|
||||||
`Gifted ${mission.cargo.metal}M ${mission.cargo.crystal}C ${mission.cargo.deuterium}D`
|
t('diplomacy.reports.giftedResources', locale, {
|
||||||
|
metal: mission.cargo.metal.toString(),
|
||||||
|
crystal: mission.cargo.crystal.toString(),
|
||||||
|
deuterium: mission.cargo.deuterium.toString()
|
||||||
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
// 也更新NPC对玩家的关系(双向好感度)
|
// 也更新NPC对玩家的关系(双向好感度)
|
||||||
@@ -209,7 +255,12 @@ export const handleGiftArrival = (mission: FleetMission, player: Player, targetN
|
|||||||
}
|
}
|
||||||
|
|
||||||
const npcRelation = getOrCreateRelation(targetNpc.relations, targetNpc.id, player.id)
|
const npcRelation = getOrCreateRelation(targetNpc.relations, targetNpc.id, player.id)
|
||||||
targetNpc.relations[player.id] = updateReputation(npcRelation, reputationGain, DET.GiftResources, `Received gift from player`)
|
targetNpc.relations[player.id] = updateReputation(
|
||||||
|
npcRelation,
|
||||||
|
reputationGain,
|
||||||
|
DET.GiftResources,
|
||||||
|
t('diplomacy.reports.receivedGiftFromPlayer', locale)
|
||||||
|
)
|
||||||
|
|
||||||
// 生成外交报告
|
// 生成外交报告
|
||||||
generateDiplomaticReport(
|
generateDiplomaticReport(
|
||||||
@@ -217,7 +268,7 @@ export const handleGiftArrival = (mission: FleetMission, player: Player, targetN
|
|||||||
targetNpc,
|
targetNpc,
|
||||||
DET.GiftResources,
|
DET.GiftResources,
|
||||||
reputationGain,
|
reputationGain,
|
||||||
`You gifted resources to ${targetNpc.name}. Reputation +${reputationGain}`
|
t('diplomacy.reports.giftedToNpc', locale, { npcName: targetNpc.name, reputation: reputationGain.toString() })
|
||||||
)
|
)
|
||||||
|
|
||||||
return { accepted: true, reputationGain }
|
return { accepted: true, reputationGain }
|
||||||
@@ -228,8 +279,9 @@ export const handleGiftArrival = (mission: FleetMission, player: Player, targetN
|
|||||||
* @param player 玩家
|
* @param player 玩家
|
||||||
* @param npc NPC
|
* @param npc NPC
|
||||||
* @param rejectedResources 被拒绝的资源
|
* @param rejectedResources 被拒绝的资源
|
||||||
|
* @param locale 语言代码
|
||||||
*/
|
*/
|
||||||
const handleGiftRejection = (player: Player, npc: NPC, rejectedResources: Resources): void => {
|
const handleGiftRejection = (player: Player, npc: NPC, rejectedResources: Resources, locale: Locale): void => {
|
||||||
const { GIFT_ACCEPTANCE_CONFIG } = DIPLOMATIC_CONFIG
|
const { GIFT_ACCEPTANCE_CONFIG } = DIPLOMATIC_CONFIG
|
||||||
|
|
||||||
// 创建拒绝通知
|
// 创建拒绝通知
|
||||||
@@ -268,7 +320,7 @@ const handleGiftRejection = (player: Player, npc: NPC, rejectedResources: Resour
|
|||||||
npcRelation,
|
npcRelation,
|
||||||
GIFT_ACCEPTANCE_CONFIG.REJECTION_REPUTATION_PENALTY,
|
GIFT_ACCEPTANCE_CONFIG.REJECTION_REPUTATION_PENALTY,
|
||||||
DET.GiftResources,
|
DET.GiftResources,
|
||||||
`Rejected player's gift`
|
t('diplomacy.reports.rejectedPlayerGift', locale)
|
||||||
)
|
)
|
||||||
|
|
||||||
// 生成外交报告
|
// 生成外交报告
|
||||||
@@ -277,7 +329,10 @@ const handleGiftRejection = (player: Player, npc: NPC, rejectedResources: Resour
|
|||||||
npc,
|
npc,
|
||||||
DET.GiftResources,
|
DET.GiftResources,
|
||||||
GIFT_ACCEPTANCE_CONFIG.REJECTION_REPUTATION_PENALTY,
|
GIFT_ACCEPTANCE_CONFIG.REJECTION_REPUTATION_PENALTY,
|
||||||
`${npc.name} rejected your gift. Reputation ${GIFT_ACCEPTANCE_CONFIG.REJECTION_REPUTATION_PENALTY}`
|
t('diplomacy.reports.npcRejectedGift', locale, {
|
||||||
|
npcName: npc.name,
|
||||||
|
reputation: GIFT_ACCEPTANCE_CONFIG.REJECTION_REPUTATION_PENALTY.toString()
|
||||||
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,8 +342,15 @@ const handleGiftRejection = (player: Player, npc: NPC, rejectedResources: Resour
|
|||||||
* @param defender 防御者(NPC)
|
* @param defender 防御者(NPC)
|
||||||
* @param battleResult 战斗结果
|
* @param battleResult 战斗结果
|
||||||
* @param allNpcs 所有NPC列表
|
* @param allNpcs 所有NPC列表
|
||||||
|
* @param locale 语言代码
|
||||||
*/
|
*/
|
||||||
export const handleAttackReputation = (attacker: Player, defender: NPC, battleResult: BattleResult, allNpcs: NPC[]): void => {
|
export const handleAttackReputation = (
|
||||||
|
attacker: Player,
|
||||||
|
defender: NPC,
|
||||||
|
battleResult: BattleResult,
|
||||||
|
allNpcs: NPC[],
|
||||||
|
locale: Locale
|
||||||
|
): void => {
|
||||||
const { REPUTATION_CHANGES } = DIPLOMATIC_CONFIG
|
const { REPUTATION_CHANGES } = DIPLOMATIC_CONFIG
|
||||||
|
|
||||||
// 计算好感度降低值
|
// 计算好感度降低值
|
||||||
@@ -304,7 +366,12 @@ export const handleAttackReputation = (attacker: Player, defender: NPC, battleRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
const relation = getOrCreateRelation(attacker.diplomaticRelations, attacker.id, defender.id)
|
const relation = getOrCreateRelation(attacker.diplomaticRelations, attacker.id, defender.id)
|
||||||
attacker.diplomaticRelations[defender.id] = updateReputation(relation, -reputationLoss, DET.Attack, `Attacked ${defender.name}`)
|
attacker.diplomaticRelations[defender.id] = updateReputation(
|
||||||
|
relation,
|
||||||
|
reputationLoss,
|
||||||
|
DET.Attack,
|
||||||
|
t('diplomacy.reports.attackedNpc', locale, { npcName: defender.name })
|
||||||
|
)
|
||||||
|
|
||||||
// 更新被攻击NPC对玩家的关系
|
// 更新被攻击NPC对玩家的关系
|
||||||
if (!defender.relations) {
|
if (!defender.relations) {
|
||||||
@@ -312,15 +379,26 @@ export const handleAttackReputation = (attacker: Player, defender: NPC, battleRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
const defenderRelation = getOrCreateRelation(defender.relations, defender.id, attacker.id)
|
const defenderRelation = getOrCreateRelation(defender.relations, defender.id, attacker.id)
|
||||||
defender.relations[attacker.id] = updateReputation(defenderRelation, -reputationLoss, DET.Attack, `Was attacked by player`)
|
defender.relations[attacker.id] = updateReputation(
|
||||||
|
defenderRelation,
|
||||||
|
reputationLoss,
|
||||||
|
DET.Attack,
|
||||||
|
t('diplomacy.reports.wasAttackedByPlayer', locale)
|
||||||
|
)
|
||||||
|
|
||||||
// 检查盟友关系网络
|
// 检查盟友关系网络
|
||||||
if (defender.allies && defender.allies.length > 0) {
|
if (defender.allies && defender.allies.length > 0) {
|
||||||
handleAllyAttackedReputation(attacker, defender, allNpcs)
|
handleAllyAttackedReputation(attacker, defender, allNpcs, locale)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成外交报告
|
// 生成外交报告
|
||||||
generateDiplomaticReport(attacker, defender, DET.Attack, -reputationLoss, `You attacked ${defender.name}`)
|
generateDiplomaticReport(
|
||||||
|
attacker,
|
||||||
|
defender,
|
||||||
|
DET.Attack,
|
||||||
|
-reputationLoss,
|
||||||
|
t('diplomacy.reports.youAttackedNpc', locale, { npcName: defender.name })
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -328,8 +406,9 @@ export const handleAttackReputation = (attacker: Player, defender: NPC, battleRe
|
|||||||
* @param attacker 攻击者(玩家)
|
* @param attacker 攻击者(玩家)
|
||||||
* @param attackedNpc 被攻击的NPC
|
* @param attackedNpc 被攻击的NPC
|
||||||
* @param allNpcs 所有NPC列表
|
* @param allNpcs 所有NPC列表
|
||||||
|
* @param locale 语言代码
|
||||||
*/
|
*/
|
||||||
export const handleAllyAttackedReputation = (attacker: Player, attackedNpc: NPC, allNpcs: NPC[]): void => {
|
export const handleAllyAttackedReputation = (attacker: Player, attackedNpc: NPC, allNpcs: NPC[], locale: Locale): void => {
|
||||||
const { REPUTATION_CHANGES } = DIPLOMATIC_CONFIG
|
const { REPUTATION_CHANGES } = DIPLOMATIC_CONFIG
|
||||||
|
|
||||||
// 找到所有盟友
|
// 找到所有盟友
|
||||||
@@ -344,9 +423,9 @@ export const handleAllyAttackedReputation = (attacker: Player, attackedNpc: NPC,
|
|||||||
const allyRelation = getOrCreateRelation(ally.relations, ally.id, attacker.id)
|
const allyRelation = getOrCreateRelation(ally.relations, ally.id, attacker.id)
|
||||||
ally.relations[attacker.id] = updateReputation(
|
ally.relations[attacker.id] = updateReputation(
|
||||||
allyRelation,
|
allyRelation,
|
||||||
-REPUTATION_CHANGES.ALLY_ATTACKED,
|
REPUTATION_CHANGES.ALLY_ATTACKED,
|
||||||
DET.AllyAttacked,
|
DET.AllyAttacked,
|
||||||
`Player attacked ally ${attackedNpc.name}`
|
t('diplomacy.reports.playerAttackedAlly', locale, { allyName: attackedNpc.name })
|
||||||
)
|
)
|
||||||
|
|
||||||
// 生成外交报告
|
// 生成外交报告
|
||||||
@@ -354,8 +433,8 @@ export const handleAllyAttackedReputation = (attacker: Player, attackedNpc: NPC,
|
|||||||
attacker,
|
attacker,
|
||||||
ally,
|
ally,
|
||||||
DET.AllyAttacked,
|
DET.AllyAttacked,
|
||||||
-REPUTATION_CHANGES.ALLY_ATTACKED,
|
REPUTATION_CHANGES.ALLY_ATTACKED,
|
||||||
`${ally.name} is displeased that you attacked their ally ${attackedNpc.name}`
|
t('diplomacy.reports.allyDispleased', locale, { allyName: ally.name, targetName: attackedNpc.name })
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -365,8 +444,9 @@ export const handleAllyAttackedReputation = (attacker: Player, attackedNpc: NPC,
|
|||||||
* @param spy 侦查者(玩家)
|
* @param spy 侦查者(玩家)
|
||||||
* @param target 侦查目标(NPC)
|
* @param target 侦查目标(NPC)
|
||||||
* @param wasDetected 是否被发现
|
* @param wasDetected 是否被发现
|
||||||
|
* @param locale 语言代码
|
||||||
*/
|
*/
|
||||||
export const handleSpyReputation = (spy: Player, target: NPC, wasDetected: boolean): void => {
|
export const handleSpyReputation = (spy: Player, target: NPC, wasDetected: boolean, locale: Locale): void => {
|
||||||
const { REPUTATION_CHANGES } = DIPLOMATIC_CONFIG
|
const { REPUTATION_CHANGES } = DIPLOMATIC_CONFIG
|
||||||
|
|
||||||
const reputationLoss = wasDetected ? REPUTATION_CHANGES.SPY_DETECTED : REPUTATION_CHANGES.SPY_UNDETECTED
|
const reputationLoss = wasDetected ? REPUTATION_CHANGES.SPY_DETECTED : REPUTATION_CHANGES.SPY_UNDETECTED
|
||||||
@@ -377,11 +457,16 @@ export const handleSpyReputation = (spy: Player, target: NPC, wasDetected: boole
|
|||||||
}
|
}
|
||||||
|
|
||||||
const targetRelation = getOrCreateRelation(target.relations, target.id, spy.id)
|
const targetRelation = getOrCreateRelation(target.relations, target.id, spy.id)
|
||||||
target.relations[spy.id] = updateReputation(targetRelation, -reputationLoss, DET.Spy, `Was spied by player (detected: ${wasDetected})`)
|
target.relations[spy.id] = updateReputation(
|
||||||
|
targetRelation,
|
||||||
|
reputationLoss,
|
||||||
|
DET.Spy,
|
||||||
|
t('diplomacy.reports.wasSpiedByPlayer', locale, { detected: wasDetected ? 'true' : 'false' })
|
||||||
|
)
|
||||||
|
|
||||||
// 如果被发现,生成外交报告
|
// 如果被发现,生成外交报告
|
||||||
if (wasDetected) {
|
if (wasDetected) {
|
||||||
generateDiplomaticReport(spy, target, DET.Spy, -reputationLoss, `Your espionage was detected by ${target.name}`)
|
generateDiplomaticReport(spy, target, DET.Spy, reputationLoss, t('diplomacy.reports.spyDetected', locale, { npcName: target.name }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,8 +476,9 @@ export const handleSpyReputation = (spy: Player, target: NPC, wasDetected: boole
|
|||||||
* @param player 玩家
|
* @param player 玩家
|
||||||
* @param debrisPosition 残骸位置
|
* @param debrisPosition 残骸位置
|
||||||
* @param allNpcs 所有NPC列表
|
* @param allNpcs 所有NPC列表
|
||||||
|
* @param locale 语言代码
|
||||||
*/
|
*/
|
||||||
export const handleDebrisRecycleReputation = (player: Player, debrisPosition: Position, allNpcs: NPC[]): void => {
|
export const handleDebrisRecycleReputation = (player: Player, debrisPosition: Position, allNpcs: NPC[], locale: Locale): void => {
|
||||||
const { REPUTATION_CHANGES } = DIPLOMATIC_CONFIG
|
const { REPUTATION_CHANGES } = DIPLOMATIC_CONFIG
|
||||||
|
|
||||||
// 找到该位置的NPC星球所有者
|
// 找到该位置的NPC星球所有者
|
||||||
@@ -414,9 +500,9 @@ export const handleDebrisRecycleReputation = (player: Player, debrisPosition: Po
|
|||||||
const relation = getOrCreateRelation(player.diplomaticRelations, player.id, npcOwner.id)
|
const relation = getOrCreateRelation(player.diplomaticRelations, player.id, npcOwner.id)
|
||||||
player.diplomaticRelations[npcOwner.id] = updateReputation(
|
player.diplomaticRelations[npcOwner.id] = updateReputation(
|
||||||
relation,
|
relation,
|
||||||
-REPUTATION_CHANGES.STEAL_DEBRIS,
|
REPUTATION_CHANGES.STEAL_DEBRIS,
|
||||||
DET.StealDebris,
|
DET.StealDebris,
|
||||||
`Stole debris from ${npcOwner.name}'s territory`
|
t('diplomacy.reports.stoleDebrisFromTerritory', locale, { npcName: npcOwner.name })
|
||||||
)
|
)
|
||||||
|
|
||||||
// 更新NPC对玩家的关系
|
// 更新NPC对玩家的关系
|
||||||
@@ -427,9 +513,9 @@ export const handleDebrisRecycleReputation = (player: Player, debrisPosition: Po
|
|||||||
const npcRelation = getOrCreateRelation(npcOwner.relations, npcOwner.id, player.id)
|
const npcRelation = getOrCreateRelation(npcOwner.relations, npcOwner.id, player.id)
|
||||||
npcOwner.relations[player.id] = updateReputation(
|
npcOwner.relations[player.id] = updateReputation(
|
||||||
npcRelation,
|
npcRelation,
|
||||||
-REPUTATION_CHANGES.STEAL_DEBRIS,
|
REPUTATION_CHANGES.STEAL_DEBRIS,
|
||||||
DET.StealDebris,
|
DET.StealDebris,
|
||||||
`Player stole debris from territory`
|
t('diplomacy.reports.playerStoleDebris', locale)
|
||||||
)
|
)
|
||||||
|
|
||||||
// 生成外交报告
|
// 生成外交报告
|
||||||
@@ -437,26 +523,179 @@ export const handleDebrisRecycleReputation = (player: Player, debrisPosition: Po
|
|||||||
player,
|
player,
|
||||||
npcOwner,
|
npcOwner,
|
||||||
DET.StealDebris,
|
DET.StealDebris,
|
||||||
-REPUTATION_CHANGES.STEAL_DEBRIS,
|
REPUTATION_CHANGES.STEAL_DEBRIS,
|
||||||
`You recycled debris near ${npcOwner.name}'s planet. They are displeased.`
|
t('diplomacy.reports.recycledDebrisNearNpc', locale, { npcName: npcOwner.name })
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理星球摧毁事件的好感度变化
|
||||||
|
* 摧毁星球是最严重的行为,直接导致敌对关系
|
||||||
|
* @param attacker 攻击者(玩家)
|
||||||
|
* @param destroyedPlanet 被摧毁的星球
|
||||||
|
* @param planetOwner 星球所有者(NPC)
|
||||||
|
* @param allNpcs 所有NPC列表
|
||||||
|
* @param locale 语言代码
|
||||||
|
*/
|
||||||
|
export const handlePlanetDestructionReputation = (
|
||||||
|
attacker: Player,
|
||||||
|
destroyedPlanet: Planet,
|
||||||
|
planetOwner: NPC,
|
||||||
|
allNpcs: NPC[],
|
||||||
|
locale: Locale
|
||||||
|
): void => {
|
||||||
|
const { HOSTILE_THRESHOLD } = DIPLOMATIC_CONFIG
|
||||||
|
const now = Date.now()
|
||||||
|
|
||||||
|
// 更新玩家对被摧毁星球所有者的关系 - 直接设为敌对
|
||||||
|
if (!attacker.diplomaticRelations) {
|
||||||
|
attacker.diplomaticRelations = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
const relation = getOrCreateRelation(attacker.diplomaticRelations, attacker.id, planetOwner.id)
|
||||||
|
const eventDescription = t('diplomacy.reports.destroyedNpcPlanet', locale, {
|
||||||
|
npcName: planetOwner.name,
|
||||||
|
planetName: destroyedPlanet.name
|
||||||
|
})
|
||||||
|
|
||||||
|
attacker.diplomaticRelations[planetOwner.id] = {
|
||||||
|
...relation,
|
||||||
|
reputation: HOSTILE_THRESHOLD, // 直接设为敌对阈值
|
||||||
|
status: RS.Hostile,
|
||||||
|
lastUpdated: now,
|
||||||
|
history: [
|
||||||
|
...(relation.history || []),
|
||||||
|
{
|
||||||
|
timestamp: now,
|
||||||
|
change: HOSTILE_THRESHOLD - relation.reputation,
|
||||||
|
reason: DET.DestroyPlanet,
|
||||||
|
details: eventDescription
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新星球所有者对玩家的关系 - 直接设为敌对
|
||||||
|
if (!planetOwner.relations) {
|
||||||
|
planetOwner.relations = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ownerRelation = getOrCreateRelation(planetOwner.relations, planetOwner.id, attacker.id)
|
||||||
|
const ownerEventDescription = t('diplomacy.reports.playerDestroyedPlanet', locale, {
|
||||||
|
planetName: destroyedPlanet.name
|
||||||
|
})
|
||||||
|
|
||||||
|
planetOwner.relations[attacker.id] = {
|
||||||
|
...ownerRelation,
|
||||||
|
reputation: HOSTILE_THRESHOLD, // 直接设为敌对阈值
|
||||||
|
status: RS.Hostile,
|
||||||
|
lastUpdated: now,
|
||||||
|
history: [
|
||||||
|
...(ownerRelation.history || []),
|
||||||
|
{
|
||||||
|
timestamp: now,
|
||||||
|
change: HOSTILE_THRESHOLD - ownerRelation.reputation,
|
||||||
|
reason: DET.DestroyPlanet,
|
||||||
|
details: ownerEventDescription
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成外交报告
|
||||||
|
generateDiplomaticReport(
|
||||||
|
attacker,
|
||||||
|
planetOwner,
|
||||||
|
DET.DestroyPlanet,
|
||||||
|
HOSTILE_THRESHOLD,
|
||||||
|
t('diplomacy.reports.youDestroyedNpcPlanet', locale, {
|
||||||
|
npcName: planetOwner.name,
|
||||||
|
planetName: destroyedPlanet.name,
|
||||||
|
reputation: HOSTILE_THRESHOLD
|
||||||
|
}),
|
||||||
|
'diplomacy.reports.youDestroyedNpcPlanet',
|
||||||
|
{ npcName: planetOwner.name, planetName: destroyedPlanet.name, reputation: HOSTILE_THRESHOLD }
|
||||||
|
)
|
||||||
|
|
||||||
|
// 检查盟友关系网络 - 摧毁星球对盟友的影响更严重
|
||||||
|
if (planetOwner.allies && planetOwner.allies.length > 0) {
|
||||||
|
handleAllyPlanetDestroyedReputation(attacker, planetOwner, destroyedPlanet, allNpcs, locale)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理盟友星球被摧毁的好感度变化
|
||||||
|
* @param attacker 攻击者(玩家)
|
||||||
|
* @param attackedNpc 星球被摧毁的NPC
|
||||||
|
* @param destroyedPlanet 被摧毁的星球
|
||||||
|
* @param allNpcs 所有NPC列表
|
||||||
|
* @param locale 语言代码
|
||||||
|
*/
|
||||||
|
export const handleAllyPlanetDestroyedReputation = (
|
||||||
|
attacker: Player,
|
||||||
|
attackedNpc: NPC,
|
||||||
|
destroyedPlanet: Planet,
|
||||||
|
allNpcs: NPC[],
|
||||||
|
locale: Locale
|
||||||
|
): void => {
|
||||||
|
const { REPUTATION_CHANGES } = DIPLOMATIC_CONFIG
|
||||||
|
|
||||||
|
// 找到所有盟友
|
||||||
|
const allies = allNpcs.filter(npc => attackedNpc.allies?.includes(npc.id))
|
||||||
|
|
||||||
|
allies.forEach(ally => {
|
||||||
|
// 更新盟友对玩家的关系 - 摧毁盟友星球的惩罚是攻击的两倍
|
||||||
|
if (!ally.relations) {
|
||||||
|
ally.relations = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
const allyRelation = getOrCreateRelation(ally.relations, ally.id, attacker.id)
|
||||||
|
const reputationLoss = REPUTATION_CHANGES.ALLY_ATTACKED * 2 // 双倍惩罚
|
||||||
|
ally.relations[attacker.id] = updateReputation(
|
||||||
|
allyRelation,
|
||||||
|
reputationLoss,
|
||||||
|
DET.DestroyPlanet,
|
||||||
|
t('diplomacy.reports.playerDestroyedAllyPlanet', locale, { allyName: attackedNpc.name, planetName: destroyedPlanet.name })
|
||||||
|
)
|
||||||
|
|
||||||
|
// 生成外交报告
|
||||||
|
generateDiplomaticReport(
|
||||||
|
attacker,
|
||||||
|
ally,
|
||||||
|
DET.DestroyPlanet,
|
||||||
|
reputationLoss,
|
||||||
|
t('diplomacy.reports.allyOutraged', locale, {
|
||||||
|
allyName: ally.name,
|
||||||
|
targetName: attackedNpc.name,
|
||||||
|
planetName: destroyedPlanet.name
|
||||||
|
}),
|
||||||
|
'diplomacy.reports.allyOutraged',
|
||||||
|
{
|
||||||
|
allyName: ally.name,
|
||||||
|
targetName: attackedNpc.name,
|
||||||
|
planetName: destroyedPlanet.name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成外交报告
|
* 生成外交报告
|
||||||
* @param player 玩家
|
* @param player 玩家
|
||||||
* @param npc NPC
|
* @param npc NPC
|
||||||
* @param eventType 事件类型
|
* @param eventType 事件类型
|
||||||
* @param reputationChange 好感度变化值
|
* @param reputationChange 好感度变化值
|
||||||
* @param message 消息内容
|
* @param message 消息内容(已弃用,用于向后兼容)
|
||||||
|
* @param messageKey 翻译键(可选)
|
||||||
|
* @param messageParams 翻译参数(可选)
|
||||||
*/
|
*/
|
||||||
const generateDiplomaticReport = (
|
const generateDiplomaticReport = (
|
||||||
player: Player,
|
player: Player,
|
||||||
npc: NPC,
|
npc: NPC,
|
||||||
eventType: DiplomaticEventType,
|
eventType: DiplomaticEventType,
|
||||||
reputationChange: number,
|
reputationChange: number,
|
||||||
message: string
|
message: string,
|
||||||
|
messageKey?: string,
|
||||||
|
messageParams?: Record<string, string | number>
|
||||||
): void => {
|
): void => {
|
||||||
if (!player.diplomaticReports) {
|
if (!player.diplomaticReports) {
|
||||||
player.diplomaticReports = []
|
player.diplomaticReports = []
|
||||||
@@ -485,6 +724,8 @@ const generateDiplomaticReport = (
|
|||||||
oldStatus,
|
oldStatus,
|
||||||
newStatus,
|
newStatus,
|
||||||
message,
|
message,
|
||||||
|
messageKey,
|
||||||
|
messageParams,
|
||||||
read: false
|
read: false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,8 +780,9 @@ export const handleNPCGiftToPlayer = (npc: NPC, player: Player, giftResources: R
|
|||||||
* @param player 玩家
|
* @param player 玩家
|
||||||
* @param npc NPC
|
* @param npc NPC
|
||||||
* @param giftNotification 礼物通知
|
* @param giftNotification 礼物通知
|
||||||
|
* @param locale 语言代码
|
||||||
*/
|
*/
|
||||||
export const acceptNPCGift = (player: Player, npc: NPC, giftNotification: GiftNotification): void => {
|
export const acceptNPCGift = (player: Player, npc: NPC, giftNotification: GiftNotification, locale: Locale): void => {
|
||||||
// 将资源添加到玩家主星球
|
// 将资源添加到玩家主星球
|
||||||
if (player.planets && player.planets.length > 0) {
|
if (player.planets && player.planets.length > 0) {
|
||||||
const mainPlanet = player.planets[0]
|
const mainPlanet = player.planets[0]
|
||||||
@@ -558,7 +800,12 @@ export const acceptNPCGift = (player: Player, npc: NPC, giftNotification: GiftNo
|
|||||||
}
|
}
|
||||||
|
|
||||||
const npcRelation = getOrCreateRelation(npc.relations, npc.id, player.id)
|
const npcRelation = getOrCreateRelation(npc.relations, npc.id, player.id)
|
||||||
npc.relations[player.id] = updateReputation(npcRelation, giftNotification.expectedReputationGain, DET.GiftResources, `Gifted resources to player`)
|
npc.relations[player.id] = updateReputation(
|
||||||
|
npcRelation,
|
||||||
|
giftNotification.expectedReputationGain,
|
||||||
|
DET.GiftResources,
|
||||||
|
t('diplomacy.reports.giftedResourcesToPlayer', locale)
|
||||||
|
)
|
||||||
|
|
||||||
// 也更新玩家对NPC的关系(收到礼物会增加好感)
|
// 也更新玩家对NPC的关系(收到礼物会增加好感)
|
||||||
if (!player.diplomaticRelations) {
|
if (!player.diplomaticRelations) {
|
||||||
@@ -570,7 +817,7 @@ export const acceptNPCGift = (player: Player, npc: NPC, giftNotification: GiftNo
|
|||||||
playerRelation,
|
playerRelation,
|
||||||
giftNotification.expectedReputationGain,
|
giftNotification.expectedReputationGain,
|
||||||
DET.GiftResources,
|
DET.GiftResources,
|
||||||
`Received gift from ${npc.name}`
|
t('diplomacy.reports.receivedGiftFromNpc', locale, { npcName: npc.name })
|
||||||
)
|
)
|
||||||
|
|
||||||
// 生成外交报告
|
// 生成外交报告
|
||||||
@@ -579,7 +826,12 @@ export const acceptNPCGift = (player: Player, npc: NPC, giftNotification: GiftNo
|
|||||||
npc,
|
npc,
|
||||||
DET.GiftResources,
|
DET.GiftResources,
|
||||||
giftNotification.expectedReputationGain,
|
giftNotification.expectedReputationGain,
|
||||||
`You accepted a gift from ${npc.name}: ${giftNotification.resources.metal}M ${giftNotification.resources.crystal}C ${giftNotification.resources.deuterium}D`
|
t('diplomacy.reports.acceptedGiftFromNpc', locale, {
|
||||||
|
npcName: npc.name,
|
||||||
|
metal: giftNotification.resources.metal.toString(),
|
||||||
|
crystal: giftNotification.resources.crystal.toString(),
|
||||||
|
deuterium: giftNotification.resources.deuterium.toString()
|
||||||
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
// 移除礼物通知
|
// 移除礼物通知
|
||||||
@@ -593,8 +845,9 @@ export const acceptNPCGift = (player: Player, npc: NPC, giftNotification: GiftNo
|
|||||||
* @param player 玩家
|
* @param player 玩家
|
||||||
* @param npc NPC
|
* @param npc NPC
|
||||||
* @param giftNotification 礼物通知
|
* @param giftNotification 礼物通知
|
||||||
|
* @param locale 语言代码
|
||||||
*/
|
*/
|
||||||
export const rejectNPCGift = (player: Player, npc: NPC, giftNotification: GiftNotification): void => {
|
export const rejectNPCGift = (player: Player, npc: NPC, giftNotification: GiftNotification, locale: Locale): void => {
|
||||||
const { GIFT_ACCEPTANCE_CONFIG } = DIPLOMATIC_CONFIG
|
const { GIFT_ACCEPTANCE_CONFIG } = DIPLOMATIC_CONFIG
|
||||||
|
|
||||||
// 拒绝礼物会降低好感度
|
// 拒绝礼物会降低好感度
|
||||||
@@ -607,7 +860,7 @@ export const rejectNPCGift = (player: Player, npc: NPC, giftNotification: GiftNo
|
|||||||
npcRelation,
|
npcRelation,
|
||||||
GIFT_ACCEPTANCE_CONFIG.REJECTION_REPUTATION_PENALTY,
|
GIFT_ACCEPTANCE_CONFIG.REJECTION_REPUTATION_PENALTY,
|
||||||
DET.GiftResources,
|
DET.GiftResources,
|
||||||
`Player rejected gift`
|
t('diplomacy.reports.playerRejectedGift', locale)
|
||||||
)
|
)
|
||||||
|
|
||||||
// 生成外交报告
|
// 生成外交报告
|
||||||
@@ -616,7 +869,10 @@ export const rejectNPCGift = (player: Player, npc: NPC, giftNotification: GiftNo
|
|||||||
npc,
|
npc,
|
||||||
DET.GiftResources,
|
DET.GiftResources,
|
||||||
GIFT_ACCEPTANCE_CONFIG.REJECTION_REPUTATION_PENALTY,
|
GIFT_ACCEPTANCE_CONFIG.REJECTION_REPUTATION_PENALTY,
|
||||||
`You rejected a gift from ${npc.name}. Reputation ${GIFT_ACCEPTANCE_CONFIG.REJECTION_REPUTATION_PENALTY}`
|
t('diplomacy.reports.rejectedGiftFromNpc', locale, {
|
||||||
|
npcName: npc.name,
|
||||||
|
reputation: GIFT_ACCEPTANCE_CONFIG.REJECTION_REPUTATION_PENALTY.toString()
|
||||||
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
// 移除礼物通知
|
// 移除礼物通知
|
||||||
@@ -624,3 +880,78 @@ export const rejectNPCGift = (player: Player, npc: NPC, giftNotification: GiftNo
|
|||||||
player.giftNotifications = player.giftNotifications.filter(n => n.id !== giftNotification.id)
|
player.giftNotifications = player.giftNotifications.filter(n => n.id !== giftNotification.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理NPC被彻底消灭(所有星球被摧毁)
|
||||||
|
* @param eliminatedNpc 被消灭的NPC
|
||||||
|
* @param player 玩家
|
||||||
|
* @param allNpcs 所有NPC列表
|
||||||
|
* @param locale 语言代码
|
||||||
|
*/
|
||||||
|
export const handleNPCElimination = (eliminatedNpc: NPC, player: Player, allNpcs: NPC[], locale: Locale): void => {
|
||||||
|
const { HOSTILE_THRESHOLD } = DIPLOMATIC_CONFIG
|
||||||
|
|
||||||
|
// 1. 将玩家对该NPC的关系设为最低(敌对状态)
|
||||||
|
if (!player.diplomaticRelations) {
|
||||||
|
player.diplomaticRelations = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
const relation = getOrCreateRelation(player.diplomaticRelations, player.id, eliminatedNpc.id)
|
||||||
|
const now = Date.now()
|
||||||
|
|
||||||
|
player.diplomaticRelations[eliminatedNpc.id] = {
|
||||||
|
...relation,
|
||||||
|
reputation: HOSTILE_THRESHOLD, // 设为敌对阈值
|
||||||
|
status: RS.Hostile,
|
||||||
|
lastUpdated: now,
|
||||||
|
history: [
|
||||||
|
...(relation.history || []),
|
||||||
|
{
|
||||||
|
timestamp: now,
|
||||||
|
change: HOSTILE_THRESHOLD - relation.reputation,
|
||||||
|
reason: DET.DestroyPlanet,
|
||||||
|
details: t('diplomacy.reports.npcEliminated', locale, { npcName: eliminatedNpc.name })
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 生成外交报告
|
||||||
|
generateDiplomaticReport(
|
||||||
|
player,
|
||||||
|
eliminatedNpc,
|
||||||
|
DET.DestroyPlanet,
|
||||||
|
HOSTILE_THRESHOLD,
|
||||||
|
t('diplomacy.reports.npcEliminatedMessage', locale, { npcName: eliminatedNpc.name }),
|
||||||
|
'diplomacy.reports.npcEliminatedMessage',
|
||||||
|
{ npcName: eliminatedNpc.name }
|
||||||
|
)
|
||||||
|
|
||||||
|
// 3. 从所有其他NPC的盟友列表中移除被消灭的NPC
|
||||||
|
allNpcs.forEach(npc => {
|
||||||
|
if (npc.id !== eliminatedNpc.id && npc.allies && npc.allies.includes(eliminatedNpc.id)) {
|
||||||
|
npc.allies = npc.allies.filter(allyId => allyId !== eliminatedNpc.id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查并处理被消灭的NPC(所有星球都被摧毁的NPC)
|
||||||
|
* @param allNpcs 所有NPC列表
|
||||||
|
* @param player 玩家
|
||||||
|
* @param locale 语言代码
|
||||||
|
* @returns 被消灭的NPC ID列表
|
||||||
|
*/
|
||||||
|
export const checkAndHandleEliminatedNPCs = (allNpcs: NPC[], player: Player, locale: Locale): string[] => {
|
||||||
|
const eliminatedNpcIds: string[] = []
|
||||||
|
|
||||||
|
allNpcs.forEach(npc => {
|
||||||
|
// 检查NPC是否还有星球
|
||||||
|
if (!npc.planets || npc.planets.length === 0) {
|
||||||
|
// NPC被彻底消灭
|
||||||
|
handleNPCElimination(npc, player, allNpcs, locale)
|
||||||
|
eliminatedNpcIds.push(npc.id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return eliminatedNpcIds
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { FleetMission, Planet, Resources, Fleet, BattleResult, SpyReport, Player, Officer, DebrisField, NPC } from '@/types/game'
|
import type { FleetMission, Planet, Resources, Fleet, BattleResult, SpyReport, Player, Officer, DebrisField, NPC } from '@/types/game'
|
||||||
|
import type { Locale } from '@/locales'
|
||||||
import { ShipType, DefenseType, MissionType, BuildingType, OfficerType, TechnologyType } from '@/types/game'
|
import { ShipType, DefenseType, MissionType, BuildingType, OfficerType, TechnologyType } from '@/types/game'
|
||||||
import { FLEET_STORAGE_CONFIG } from '@/config/gameConfig'
|
import { FLEET_STORAGE_CONFIG } from '@/config/gameConfig'
|
||||||
import * as battleLogic from './battleLogic'
|
import * as battleLogic from './battleLogic'
|
||||||
@@ -35,9 +36,10 @@ export const calculateDistance = (
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算飞行时间
|
* 计算飞行时间
|
||||||
|
* 平衡后的时间倍率,确保游戏节奏合理
|
||||||
*/
|
*/
|
||||||
export const calculateFlightTime = (distance: number, minSpeed: number): number => {
|
export const calculateFlightTime = (distance: number, minSpeed: number): number => {
|
||||||
return Math.max(10, Math.floor((distance * 10000) / minSpeed)) // 至少10秒
|
return Math.max(10, Math.floor((distance * 50) / minSpeed)) // 至少10秒
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,13 +77,14 @@ export const processTransportArrival = (
|
|||||||
mission: FleetMission,
|
mission: FleetMission,
|
||||||
targetPlanet: Planet | undefined,
|
targetPlanet: Planet | undefined,
|
||||||
player?: Player,
|
player?: Player,
|
||||||
allNpcs?: NPC[]
|
allNpcs?: NPC[],
|
||||||
|
locale: Locale = 'zh-CN'
|
||||||
): { success: boolean; reputationGain?: number } => {
|
): { success: boolean; reputationGain?: number } => {
|
||||||
// 检查是否是赠送任务
|
// 检查是否是赠送任务
|
||||||
if (mission.isGift && mission.giftTargetNpcId && player && allNpcs) {
|
if (mission.isGift && mission.giftTargetNpcId && player && allNpcs) {
|
||||||
const targetNpc = allNpcs.find(n => n.id === mission.giftTargetNpcId)
|
const targetNpc = allNpcs.find(n => n.id === mission.giftTargetNpcId)
|
||||||
if (targetNpc) {
|
if (targetNpc) {
|
||||||
const giftResult = diplomaticLogic.handleGiftArrival(mission, player, targetNpc)
|
const giftResult = diplomaticLogic.handleGiftArrival(mission, player, targetNpc, locale)
|
||||||
mission.status = 'returning'
|
mission.status = 'returning'
|
||||||
|
|
||||||
// 如果礼物被拒绝,资源返还给玩家
|
// 如果礼物被拒绝,资源返还给玩家
|
||||||
@@ -316,8 +319,8 @@ export const processNPCAttackArrival = async (
|
|||||||
* 基于天体物理学技术等级
|
* 基于天体物理学技术等级
|
||||||
*/
|
*/
|
||||||
export const calculateMaxPlanets = (astrophysicsLevel: number): number => {
|
export const calculateMaxPlanets = (astrophysicsLevel: number): number => {
|
||||||
// 基础1个星球 + 每2级天体物理学增加1个殖民地槽位
|
// 基础1个星球(主星) + 每级天体物理学增加1个殖民地槽位
|
||||||
return 1 + Math.floor(astrophysicsLevel / 2)
|
return 1 + astrophysicsLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -463,7 +466,8 @@ export const processSpyArrival = (
|
|||||||
targetPlanet: Planet | undefined,
|
targetPlanet: Planet | undefined,
|
||||||
attacker: Player,
|
attacker: Player,
|
||||||
defender: Player | null,
|
defender: Player | null,
|
||||||
allNpcs?: NPC[]
|
allNpcs?: NPC[],
|
||||||
|
locale: Locale = 'zh-CN'
|
||||||
): SpyReport | null => {
|
): SpyReport | null => {
|
||||||
if (!targetPlanet) {
|
if (!targetPlanet) {
|
||||||
mission.status = 'returning'
|
mission.status = 'returning'
|
||||||
@@ -504,7 +508,7 @@ export const processSpyArrival = (
|
|||||||
if (allNpcs && targetPlanet.ownerId) {
|
if (allNpcs && targetPlanet.ownerId) {
|
||||||
const targetNpc = allNpcs.find(npc => npc.planets.some(p => p.id === targetPlanet.id))
|
const targetNpc = allNpcs.find(npc => npc.planets.some(p => p.id === targetPlanet.id))
|
||||||
if (targetNpc) {
|
if (targetNpc) {
|
||||||
diplomaticLogic.handleSpyReputation(attacker, targetNpc, wasDetected)
|
diplomaticLogic.handleSpyReputation(attacker, targetNpc, wasDetected, locale)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,7 +540,8 @@ export const processRecycleArrival = (
|
|||||||
mission: FleetMission,
|
mission: FleetMission,
|
||||||
debrisField: DebrisField | undefined,
|
debrisField: DebrisField | undefined,
|
||||||
player?: Player,
|
player?: Player,
|
||||||
allNpcs?: NPC[]
|
allNpcs?: NPC[],
|
||||||
|
locale: Locale = 'zh-CN'
|
||||||
): { collectedResources: Pick<Resources, 'metal' | 'crystal'>; remainingDebris: Pick<Resources, 'metal' | 'crystal'> | null } | null => {
|
): { collectedResources: Pick<Resources, 'metal' | 'crystal'>; remainingDebris: Pick<Resources, 'metal' | 'crystal'> | null } | null => {
|
||||||
if (!debrisField) {
|
if (!debrisField) {
|
||||||
mission.status = 'returning'
|
mission.status = 'returning'
|
||||||
@@ -558,6 +563,12 @@ export const processRecycleArrival = (
|
|||||||
const totalDebris = debrisField.resources.metal + debrisField.resources.crystal
|
const totalDebris = debrisField.resources.metal + debrisField.resources.crystal
|
||||||
const collectedAmount = Math.min(totalDebris, availableCapacity)
|
const collectedAmount = Math.min(totalDebris, availableCapacity)
|
||||||
|
|
||||||
|
// 防止除零:如果残骸为0,直接返回
|
||||||
|
if (totalDebris === 0) {
|
||||||
|
mission.status = 'returning'
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
// 按比例收集金属和晶体
|
// 按比例收集金属和晶体
|
||||||
const metalRatio = debrisField.resources.metal / totalDebris
|
const metalRatio = debrisField.resources.metal / totalDebris
|
||||||
const crystalRatio = debrisField.resources.crystal / totalDebris
|
const crystalRatio = debrisField.resources.crystal / totalDebris
|
||||||
@@ -577,7 +588,7 @@ export const processRecycleArrival = (
|
|||||||
|
|
||||||
// 检查是否在NPC星球位置回收残骸,如果是则降低好感度
|
// 检查是否在NPC星球位置回收残骸,如果是则降低好感度
|
||||||
if (player && allNpcs && collectedAmount > 0) {
|
if (player && allNpcs && collectedAmount > 0) {
|
||||||
diplomaticLogic.handleDebrisRecycleReputation(player, debrisField.position, allNpcs)
|
diplomaticLogic.handleDebrisRecycleReputation(player, debrisField.position, allNpcs, locale)
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -707,7 +718,8 @@ export const updateFleetMissions = async (
|
|||||||
attacker: Player,
|
attacker: Player,
|
||||||
defender: Player | null,
|
defender: Player | null,
|
||||||
now: number,
|
now: number,
|
||||||
allNpcs?: NPC[]
|
allNpcs?: NPC[],
|
||||||
|
locale?: Locale
|
||||||
): Promise<{
|
): Promise<{
|
||||||
completedMissions: string[]
|
completedMissions: string[]
|
||||||
battleReports: BattleResult[]
|
battleReports: BattleResult[]
|
||||||
@@ -757,7 +769,24 @@ export const updateFleetMissions = async (
|
|||||||
planets.set(moonKey, attackResult.moon)
|
planets.set(moonKey, attackResult.moon)
|
||||||
}
|
}
|
||||||
if (attackResult.debrisField) {
|
if (attackResult.debrisField) {
|
||||||
newDebrisFields.push(attackResult.debrisField)
|
// 检查该位置是否已存在残骸场
|
||||||
|
const existingDebris = debrisFields.get(attackResult.debrisField.id)
|
||||||
|
if (existingDebris) {
|
||||||
|
// 累加残骸资源
|
||||||
|
const updatedDebris: DebrisField = {
|
||||||
|
...existingDebris,
|
||||||
|
resources: {
|
||||||
|
metal: existingDebris.resources.metal + attackResult.debrisField.resources.metal,
|
||||||
|
crystal: existingDebris.resources.crystal + attackResult.debrisField.resources.crystal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debrisFields.set(attackResult.debrisField.id, updatedDebris)
|
||||||
|
updatedDebrisFields.push(updatedDebris)
|
||||||
|
} else {
|
||||||
|
// 新建残骸场
|
||||||
|
debrisFields.set(attackResult.debrisField.id, attackResult.debrisField)
|
||||||
|
newDebrisFields.push(attackResult.debrisField)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
@@ -811,6 +840,15 @@ export const updateFleetMissions = async (
|
|||||||
if (destroyResult && destroyResult.success && destroyResult.planetId) {
|
if (destroyResult && destroyResult.success && destroyResult.planetId) {
|
||||||
// 星球被摧毁
|
// 星球被摧毁
|
||||||
destroyedPlanetIds.push(destroyResult.planetId)
|
destroyedPlanetIds.push(destroyResult.planetId)
|
||||||
|
|
||||||
|
// 处理外交关系(如果目标是NPC星球)
|
||||||
|
if (targetPlanet && targetPlanet.ownerId && allNpcs && locale) {
|
||||||
|
const planetOwner = allNpcs.find(npc => npc.id === targetPlanet.ownerId)
|
||||||
|
if (planetOwner) {
|
||||||
|
diplomaticLogic.handlePlanetDestructionReputation(attacker, targetPlanet, planetOwner, allNpcs, locale)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
planets.delete(targetKey)
|
planets.delete(targetKey)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -39,7 +39,12 @@ export const calculateMaxFleetStorage = (planet: Planet, technologies: Record<Te
|
|||||||
const shipyardBonus = BUILDINGS[BuildingType.Shipyard].fleetStorageBonus || 0
|
const shipyardBonus = BUILDINGS[BuildingType.Shipyard].fleetStorageBonus || 0
|
||||||
maxStorage += shipyardLevel * shipyardBonus
|
maxStorage += shipyardLevel * shipyardBonus
|
||||||
|
|
||||||
// 3. 计算机技术全局加成
|
// 3. 机库建筑加成(每个星球独立)
|
||||||
|
const hangarLevel = planet.buildings[BuildingType.Hangar] || 0
|
||||||
|
const hangarBonus = BUILDINGS[BuildingType.Hangar].fleetStorageBonus || 0
|
||||||
|
maxStorage += hangarLevel * hangarBonus
|
||||||
|
|
||||||
|
// 4. 计算机技术全局加成
|
||||||
const computerTechLevel = technologies[TechnologyType.ComputerTechnology] || 0
|
const computerTechLevel = technologies[TechnologyType.ComputerTechnology] || 0
|
||||||
const computerTechBonus = TECHNOLOGIES[TechnologyType.ComputerTechnology].fleetStorageBonus || 0
|
const computerTechBonus = TECHNOLOGIES[TechnologyType.ComputerTechnology].fleetStorageBonus || 0
|
||||||
maxStorage += computerTechLevel * computerTechBonus
|
maxStorage += computerTechLevel * computerTechBonus
|
||||||
@@ -82,5 +87,9 @@ export const getMaxBuildableShips = (planet: Planet, shipType: ShipType, technol
|
|||||||
const shipStorageUsage = SHIPS[shipType].storageUsage
|
const shipStorageUsage = SHIPS[shipType].storageUsage
|
||||||
|
|
||||||
if (shipStorageUsage === 0) return Number.MAX_SAFE_INTEGER
|
if (shipStorageUsage === 0) return Number.MAX_SAFE_INTEGER
|
||||||
|
|
||||||
|
// 如果当前已经超限(舰队返回等情况),则不允许建造新舰船
|
||||||
|
if (availableStorage <= 0) return 0
|
||||||
|
|
||||||
return Math.floor(availableStorage / shipStorageUsage)
|
return Math.floor(availableStorage / shipStorageUsage)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ export const initializePlayer = (playerId: string, playerName: string = 'Command
|
|||||||
officers: {} as Record<OfficerType, Officer>,
|
officers: {} as Record<OfficerType, Officer>,
|
||||||
researchQueue: [],
|
researchQueue: [],
|
||||||
fleetMissions: [],
|
fleetMissions: [],
|
||||||
|
missileAttacks: [],
|
||||||
battleReports: [],
|
battleReports: [],
|
||||||
spyReports: [],
|
spyReports: [],
|
||||||
spiedNotifications: [],
|
spiedNotifications: [],
|
||||||
@@ -99,7 +100,8 @@ export const generatePositionKey = (galaxy: number, system: number, position: nu
|
|||||||
*/
|
*/
|
||||||
export const processGameUpdate = (
|
export const processGameUpdate = (
|
||||||
player: Player,
|
player: Player,
|
||||||
now: number
|
now: number,
|
||||||
|
gameSpeed: number = 1
|
||||||
): {
|
): {
|
||||||
updatedResearchQueue: BuildQueueItem[]
|
updatedResearchQueue: BuildQueueItem[]
|
||||||
} => {
|
} => {
|
||||||
@@ -113,7 +115,7 @@ export const processGameUpdate = (
|
|||||||
|
|
||||||
// 更新所有星球资源(直接同步计算,避免 Worker 通信开销)
|
// 更新所有星球资源(直接同步计算,避免 Worker 通信开销)
|
||||||
player.planets.forEach(planet => {
|
player.planets.forEach(planet => {
|
||||||
resourceLogic.updatePlanetResources(planet, now, bonuses)
|
resourceLogic.updatePlanetResources(planet, now, bonuses, gameSpeed)
|
||||||
})
|
})
|
||||||
|
|
||||||
// 更新所有星球其他状态
|
// 更新所有星球其他状态
|
||||||
|
|||||||
196
src/logic/missileLogic.ts
Normal file
196
src/logic/missileLogic.ts
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
/**
|
||||||
|
* 导弹系统逻辑
|
||||||
|
* 处理星际导弹攻击、射程计算、拦截等
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { Planet, MissileAttack, DefenseType, TechnologyType, Position } from '@/types/game'
|
||||||
|
import { DefenseType as DefenseTypes } from '@/types/game'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算导弹射程(基于脉冲引擎等级)
|
||||||
|
* 射程 = 5 * impulseDriveLevel - 1(系统距离)
|
||||||
|
*/
|
||||||
|
export const calculateMissileRange = (impulseDriveLevel: number): number => {
|
||||||
|
if (impulseDriveLevel === 0) return 0
|
||||||
|
return 5 * impulseDriveLevel - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算两个位置之间的系统距离
|
||||||
|
*/
|
||||||
|
export const calculateSystemDistance = (from: Position, to: Position): number => {
|
||||||
|
// 如果在不同银河系,距离无限大
|
||||||
|
if (from.galaxy !== to.galaxy) {
|
||||||
|
return Infinity
|
||||||
|
}
|
||||||
|
|
||||||
|
// 同一银河系内的系统距离
|
||||||
|
return Math.abs(from.system - to.system)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查目标是否在射程内
|
||||||
|
*/
|
||||||
|
export const isTargetInRange = (originPosition: Position, targetPosition: Position, impulseDriveLevel: number): boolean => {
|
||||||
|
const range = calculateMissileRange(impulseDriveLevel)
|
||||||
|
const distance = calculateSystemDistance(originPosition, targetPosition)
|
||||||
|
return distance <= range
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算导弹飞行时间(秒)
|
||||||
|
* 基础飞行时间: 30秒 + 60秒/系统距离
|
||||||
|
*/
|
||||||
|
export const calculateMissileFlightTime = (distance: number): number => {
|
||||||
|
return 30 + distance * 60
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建导弹攻击任务
|
||||||
|
*/
|
||||||
|
export const createMissileAttack = (
|
||||||
|
playerId: string,
|
||||||
|
originPlanet: Planet,
|
||||||
|
targetPosition: Position,
|
||||||
|
targetPlanetId: string | undefined,
|
||||||
|
missileCount: number
|
||||||
|
): MissileAttack => {
|
||||||
|
const now = Date.now()
|
||||||
|
const distance = calculateSystemDistance(originPlanet.position, targetPosition)
|
||||||
|
const flightTime = calculateMissileFlightTime(distance) * 1000 // 转换为毫秒
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: `missile_${now}_${playerId}`,
|
||||||
|
playerId,
|
||||||
|
originPlanetId: originPlanet.id,
|
||||||
|
targetPosition,
|
||||||
|
targetPlanetId,
|
||||||
|
missileCount,
|
||||||
|
launchTime: now,
|
||||||
|
arrivalTime: now + flightTime,
|
||||||
|
status: 'flying'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证导弹发射条件
|
||||||
|
*/
|
||||||
|
export const validateMissileLaunch = (
|
||||||
|
originPlanet: Planet,
|
||||||
|
targetPosition: Position,
|
||||||
|
missileCount: number,
|
||||||
|
technologies: Partial<Record<TechnologyType, number>>
|
||||||
|
): {
|
||||||
|
valid: boolean
|
||||||
|
reason?: string
|
||||||
|
} => {
|
||||||
|
// 检查是否有足够的星际导弹
|
||||||
|
const availableMissiles = originPlanet.defense[DefenseTypes.InterplanetaryMissile] || 0
|
||||||
|
if (availableMissiles < missileCount) {
|
||||||
|
return { valid: false, reason: 'errors.insufficientMissiles' }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查发射数量
|
||||||
|
if (missileCount <= 0) {
|
||||||
|
return { valid: false, reason: 'errors.invalidMissileCount' }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查射程
|
||||||
|
const impulseDriveLevel = technologies['impulseDrive'] || 0
|
||||||
|
if (!isTargetInRange(originPlanet.position, targetPosition, impulseDriveLevel)) {
|
||||||
|
return { valid: false, reason: 'errors.targetOutOfRange' }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不能攻击自己的星球
|
||||||
|
if (
|
||||||
|
originPlanet.position.galaxy === targetPosition.galaxy &&
|
||||||
|
originPlanet.position.system === targetPosition.system &&
|
||||||
|
originPlanet.position.position === targetPosition.position
|
||||||
|
) {
|
||||||
|
return { valid: false, reason: 'errors.cannotAttackOwnPlanet' }
|
||||||
|
}
|
||||||
|
|
||||||
|
return { valid: true }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行导弹发射(扣除导弹)
|
||||||
|
*/
|
||||||
|
export const executeMissileLaunch = (planet: Planet, missileCount: number): void => {
|
||||||
|
const currentMissiles = planet.defense[DefenseTypes.InterplanetaryMissile] || 0
|
||||||
|
planet.defense[DefenseTypes.InterplanetaryMissile] = currentMissiles - missileCount
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算导弹攻击结果(考虑拦截)
|
||||||
|
* @returns 实际命中的导弹数量
|
||||||
|
*/
|
||||||
|
export const calculateMissileImpact = (
|
||||||
|
attackingMissiles: number,
|
||||||
|
defenderPlanet: Planet
|
||||||
|
): {
|
||||||
|
missileHits: number
|
||||||
|
missileIntercepted: number
|
||||||
|
defenseLosses: Partial<Record<DefenseType, number>>
|
||||||
|
} => {
|
||||||
|
const antiBallisticMissiles = defenderPlanet.defense[DefenseTypes.AntiBallisticMissile] || 0
|
||||||
|
|
||||||
|
// 反弹道导弹拦截(1:1)
|
||||||
|
const intercepted = Math.min(attackingMissiles, antiBallisticMissiles)
|
||||||
|
const missileHits = attackingMissiles - intercepted
|
||||||
|
|
||||||
|
// 计算防御损失
|
||||||
|
const defenseLosses: Partial<Record<DefenseType, number>> = {}
|
||||||
|
|
||||||
|
// 消耗的反弹道导弹
|
||||||
|
if (intercepted > 0) {
|
||||||
|
defenseLosses[DefenseTypes.AntiBallisticMissile] = intercepted
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有导弹命中,随机摧毁防御设施
|
||||||
|
if (missileHits > 0) {
|
||||||
|
const defenseTypes = Object.keys(defenderPlanet.defense) as DefenseType[]
|
||||||
|
const availableDefenses = defenseTypes.filter(type => {
|
||||||
|
// 不能摧毁护盾罩和行星护盾
|
||||||
|
if (type === DefenseTypes.SmallShieldDome || type === DefenseTypes.LargeShieldDome || type === DefenseTypes.PlanetaryShield) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return (defenderPlanet.defense[type] || 0) > 0
|
||||||
|
})
|
||||||
|
|
||||||
|
// 每枚导弹可以摧毁一个防御设施
|
||||||
|
for (let i = 0; i < missileHits && availableDefenses.length > 0; i++) {
|
||||||
|
const randomIndex = Math.floor(Math.random() * availableDefenses.length)
|
||||||
|
const targetDefense = availableDefenses[randomIndex]
|
||||||
|
|
||||||
|
if (targetDefense) {
|
||||||
|
if (!defenseLosses[targetDefense]) {
|
||||||
|
defenseLosses[targetDefense] = 0
|
||||||
|
}
|
||||||
|
defenseLosses[targetDefense]!++
|
||||||
|
|
||||||
|
// 如果该类型防御全部摧毁,从可用列表中移除
|
||||||
|
const remaining = (defenderPlanet.defense[targetDefense] || 0) - (defenseLosses[targetDefense] || 0)
|
||||||
|
if (remaining <= 0) {
|
||||||
|
availableDefenses.splice(randomIndex, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
missileHits,
|
||||||
|
missileIntercepted: intercepted,
|
||||||
|
defenseLosses
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用导弹攻击结果到星球
|
||||||
|
*/
|
||||||
|
export const applyMissileAttackResult = (planet: Planet, defenseLosses: Partial<Record<DefenseType, number>>): void => {
|
||||||
|
for (const [defenseType, lossCount] of Object.entries(defenseLosses)) {
|
||||||
|
const currentCount = planet.defense[defenseType as DefenseType] || 0
|
||||||
|
planet.defense[defenseType as DefenseType] = Math.max(0, currentCount - lossCount)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -97,8 +97,8 @@ export const shouldNPCSpyPlayer = (npc: NPC, player: Player, currentTime: number
|
|||||||
return Math.random() < 0.5
|
return Math.random() < 0.5
|
||||||
}
|
}
|
||||||
if (relation.status === RelationStatus.Hostile) {
|
if (relation.status === RelationStatus.Hostile) {
|
||||||
// 敌对NPC侦查频率提高50%
|
// 敌对NPC必定侦查
|
||||||
return Math.random() < 1.5
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -695,7 +695,7 @@ export const forceNPCSpyAndAttack = (
|
|||||||
return { spyMission, attackMission: null }
|
return { spyMission, attackMission: null }
|
||||||
}
|
}
|
||||||
|
|
||||||
const { spyReport } = processNPCSpyArrival(npc, spyMission, targetPlanet, player)
|
const { spyReport, spiedNotification } = processNPCSpyArrival(npc, spyMission, targetPlanet, player)
|
||||||
|
|
||||||
// 保存侦查报告到NPC
|
// 保存侦查报告到NPC
|
||||||
if (!npc.playerSpyReports) {
|
if (!npc.playerSpyReports) {
|
||||||
@@ -703,6 +703,12 @@ export const forceNPCSpyAndAttack = (
|
|||||||
}
|
}
|
||||||
npc.playerSpyReports[targetPlanet.id] = spyReport
|
npc.playerSpyReports[targetPlanet.id] = spyReport
|
||||||
|
|
||||||
|
// 添加被侦查通知给玩家
|
||||||
|
if (!player.spiedNotifications) {
|
||||||
|
player.spiedNotifications = []
|
||||||
|
}
|
||||||
|
player.spiedNotifications.push(spiedNotification)
|
||||||
|
|
||||||
// 3. 立即发起攻击
|
// 3. 立即发起攻击
|
||||||
const attackMission = forceNPCAttackPlayer(npc, player, allPlanets, targetPlanetIndex)
|
const attackMission = forceNPCAttackPlayer(npc, player, allPlanets, targetPlanetIndex)
|
||||||
|
|
||||||
@@ -713,7 +719,7 @@ export const forceNPCSpyAndAttack = (
|
|||||||
* 测试函数:加速舰队任务到达时间
|
* 测试函数:加速舰队任务到达时间
|
||||||
* 将任务的到达时间设置为现在+指定秒数
|
* 将任务的到达时间设置为现在+指定秒数
|
||||||
*/
|
*/
|
||||||
export const accelerateNPCMission = (npc: NPC, missionId: string, arriveInSeconds = 5): boolean => {
|
export const accelerateNPCMission = (npc: NPC, missionId: string, arriveInSeconds = 5, player?: Player): boolean => {
|
||||||
if (!npc.fleetMissions) {
|
if (!npc.fleetMissions) {
|
||||||
console.error('[Test] NPC has no fleet missions')
|
console.error('[Test] NPC has no fleet missions')
|
||||||
return false
|
return false
|
||||||
@@ -726,7 +732,19 @@ export const accelerateNPCMission = (npc: NPC, missionId: string, arriveInSecond
|
|||||||
}
|
}
|
||||||
|
|
||||||
const now = Date.now()
|
const now = Date.now()
|
||||||
mission.arrivalTime = now + arriveInSeconds * 1000
|
const flightTime = arriveInSeconds * 1000 // 飞行时间(毫秒)
|
||||||
|
|
||||||
|
// 同时修改 departureTime 和 arrivalTime,保持飞行时间为指定秒数
|
||||||
|
mission.departureTime = now
|
||||||
|
mission.arrivalTime = now + flightTime
|
||||||
|
|
||||||
|
// 同时更新对应的 IncomingFleetAlert
|
||||||
|
if (player && player.incomingFleetAlerts) {
|
||||||
|
const alert = player.incomingFleetAlerts.find(a => a.id === missionId)
|
||||||
|
if (alert) {
|
||||||
|
alert.arrivalTime = mission.arrivalTime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -734,21 +752,34 @@ export const accelerateNPCMission = (npc: NPC, missionId: string, arriveInSecond
|
|||||||
/**
|
/**
|
||||||
* 测试函数:加速所有NPC舰队任务
|
* 测试函数:加速所有NPC舰队任务
|
||||||
*/
|
*/
|
||||||
export const accelerateAllNPCMissions = (npc: NPC, arriveInSeconds = 5): number => {
|
export const accelerateAllNPCMissions = (npc: NPC, arriveInSeconds = 5, player?: Player): number => {
|
||||||
if (!npc.fleetMissions) {
|
if (!npc.fleetMissions) {
|
||||||
console.error('[Test] NPC has no fleet missions')
|
console.error('[Test] NPC has no fleet missions')
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
const now = Date.now()
|
const now = Date.now()
|
||||||
|
const flightTime = arriveInSeconds * 1000
|
||||||
let count = 0
|
let count = 0
|
||||||
|
|
||||||
npc.fleetMissions.forEach(mission => {
|
npc.fleetMissions.forEach(mission => {
|
||||||
if (mission.status === 'outbound') {
|
if (mission.status === 'outbound') {
|
||||||
mission.arrivalTime = now + arriveInSeconds * 1000
|
// 同时修改 departureTime 和 arrivalTime
|
||||||
|
mission.departureTime = now
|
||||||
|
mission.arrivalTime = now + flightTime
|
||||||
|
|
||||||
|
// 同时更新对应的 IncomingFleetAlert
|
||||||
|
if (player && player.incomingFleetAlerts) {
|
||||||
|
const alert = player.incomingFleetAlerts.find(a => a.id === mission.id)
|
||||||
|
if (alert) {
|
||||||
|
alert.arrivalTime = mission.arrivalTime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
count++
|
count++
|
||||||
} else if (mission.status === 'returning' && mission.returnTime) {
|
} else if (mission.status === 'returning' && mission.returnTime) {
|
||||||
mission.returnTime = now + arriveInSeconds * 1000
|
// 对于返回任务,保持原来的逻辑
|
||||||
|
mission.returnTime = now + flightTime
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -61,14 +61,14 @@ export const calculateDynamicDifficulty = (playerPoints: number): DynamicDifficu
|
|||||||
// 积分区间和对应的难度参数
|
// 积分区间和对应的难度参数
|
||||||
if (playerPoints < 1000) {
|
if (playerPoints < 1000) {
|
||||||
// 新手期:0-1,000分
|
// 新手期:0-1,000分
|
||||||
// NPC保持30-50%实力,给予充分发展空间
|
// NPC保持30-50%实力,给予充分发展空间,但资源增长速度加快
|
||||||
const ratio = 0.3 + (playerPoints / 1000) * 0.2
|
const ratio = 0.3 + (playerPoints / 1000) * 0.2
|
||||||
return {
|
return {
|
||||||
powerRatio: ratio,
|
powerRatio: ratio,
|
||||||
checkInterval: 300, // 5分钟
|
checkInterval: 300, // 5分钟
|
||||||
resourceGrowthRate: 0.4,
|
resourceGrowthRate: 0.8, // 从0.4提升到0.8,确保NPC有足够资源发育
|
||||||
buildingGrowthSpeed: 0.4,
|
buildingGrowthSpeed: 0.6, // 从0.4提升到0.6
|
||||||
techGrowthSpeed: 0.4
|
techGrowthSpeed: 0.6 // 从0.4提升到0.6
|
||||||
}
|
}
|
||||||
} else if (playerPoints < 5000) {
|
} else if (playerPoints < 5000) {
|
||||||
// 初级期:1,000-5,000分
|
// 初级期:1,000-5,000分
|
||||||
@@ -77,9 +77,9 @@ export const calculateDynamicDifficulty = (playerPoints: number): DynamicDifficu
|
|||||||
return {
|
return {
|
||||||
powerRatio: ratio,
|
powerRatio: ratio,
|
||||||
checkInterval: 240, // 4分钟
|
checkInterval: 240, // 4分钟
|
||||||
resourceGrowthRate: 0.6,
|
resourceGrowthRate: 1.0, // 从0.6提升到1.0,与玩家资源产出相当
|
||||||
buildingGrowthSpeed: 0.6,
|
buildingGrowthSpeed: 0.8, // 从0.6提升到0.8
|
||||||
techGrowthSpeed: 0.6
|
techGrowthSpeed: 0.8 // 从0.6提升到0.8
|
||||||
}
|
}
|
||||||
} else if (playerPoints < 20000) {
|
} else if (playerPoints < 20000) {
|
||||||
// 中级期:5,000-20,000分
|
// 中级期:5,000-20,000分
|
||||||
@@ -559,9 +559,7 @@ export const initializeNPCDiplomacy = (npcs: NPC[]): void => {
|
|||||||
// 为每个NPC随机分配1-2个盟友
|
// 为每个NPC随机分配1-2个盟友
|
||||||
npcs.forEach(npc => {
|
npcs.forEach(npc => {
|
||||||
// 获取还未建立关系的潜在盟友
|
// 获取还未建立关系的潜在盟友
|
||||||
const potentialAllies = npcs.filter(
|
const potentialAllies = npcs.filter(n => n.id !== npc.id && !npc.allies!.includes(n.id) && !n.allies!.includes(npc.id))
|
||||||
n => n.id !== npc.id && !npc.allies!.includes(n.id) && !n.allies!.includes(npc.id)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (potentialAllies.length === 0) return
|
if (potentialAllies.length === 0) return
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ import { TechnologyType, BuildingType } from '@/types/game'
|
|||||||
import { TECHNOLOGIES } from '@/config/gameConfig'
|
import { TECHNOLOGIES } from '@/config/gameConfig'
|
||||||
import * as pointsLogic from './pointsLogic'
|
import * as pointsLogic from './pointsLogic'
|
||||||
|
|
||||||
|
// 用于生成唯一ID的计数器
|
||||||
|
let researchQueueIdCounter = 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算科技研究成本
|
* 计算科技研究成本
|
||||||
*/
|
*/
|
||||||
@@ -77,8 +80,9 @@ export const checkTechnologyRequirements = (
|
|||||||
*/
|
*/
|
||||||
export const createResearchQueueItem = (techType: TechnologyType, targetLevel: number, researchTime: number): BuildQueueItem => {
|
export const createResearchQueueItem = (techType: TechnologyType, targetLevel: number, researchTime: number): BuildQueueItem => {
|
||||||
const now = Date.now()
|
const now = Date.now()
|
||||||
|
researchQueueIdCounter++
|
||||||
return {
|
return {
|
||||||
id: `research_${now}`,
|
id: `research_${now}_${researchQueueIdCounter}`,
|
||||||
type: 'technology',
|
type: 'technology',
|
||||||
itemType: techType,
|
itemType: techType,
|
||||||
targetLevel,
|
targetLevel,
|
||||||
|
|||||||
@@ -21,6 +21,12 @@ export const validateTechnologyResearch = (
|
|||||||
const targetLevel = currentLevel + 1
|
const targetLevel = currentLevel + 1
|
||||||
const cost = researchLogic.calculateTechnologyCost(techType, targetLevel)
|
const cost = researchLogic.calculateTechnologyCost(techType, targetLevel)
|
||||||
|
|
||||||
|
// 检查队列中是否已存在该科技的研究任务
|
||||||
|
const existingQueueItem = researchQueue.find(item => item.type === 'technology' && item.itemType === techType)
|
||||||
|
if (existingQueueItem) {
|
||||||
|
return { valid: false, reason: 'errors.technologyAlreadyInQueue' }
|
||||||
|
}
|
||||||
|
|
||||||
// 检查研究队列是否已满
|
// 检查研究队列是否已满
|
||||||
const maxQueue = publicLogic.getMaxResearchQueue(technologies)
|
const maxQueue = publicLogic.getMaxResearchQueue(technologies)
|
||||||
if (researchQueue.length >= maxQueue) {
|
if (researchQueue.length >= maxQueue) {
|
||||||
|
|||||||
@@ -115,23 +115,27 @@ export const updatePlanetResources = (
|
|||||||
darkMatterProductionBonus: number
|
darkMatterProductionBonus: number
|
||||||
energyProductionBonus: number
|
energyProductionBonus: number
|
||||||
storageCapacityBonus: number
|
storageCapacityBonus: number
|
||||||
}
|
},
|
||||||
|
gameSpeed: number = 1
|
||||||
): void => {
|
): void => {
|
||||||
const timeDiff = (now - planet.lastUpdate) / 1000 // 转换为秒
|
const timeDiff = (now - planet.lastUpdate) / 1000 // 转换为秒
|
||||||
|
|
||||||
|
// 应用游戏速度到时间差(游戏速度影响资源产出速率)
|
||||||
|
const effectiveTimeDiff = timeDiff * gameSpeed
|
||||||
|
|
||||||
// 计算能量消耗(每小时)
|
// 计算能量消耗(每小时)
|
||||||
const energyConsumption = calculateEnergyConsumption(planet)
|
const energyConsumption = calculateEnergyConsumption(planet)
|
||||||
|
|
||||||
// 先增加能量产出
|
// 先增加能量产出
|
||||||
const energyProduction = calculateEnergyProduction(planet, { energyProductionBonus: bonuses.energyProductionBonus })
|
const energyProduction = calculateEnergyProduction(planet, { energyProductionBonus: bonuses.energyProductionBonus })
|
||||||
planet.resources.energy += (energyProduction * timeDiff) / 3600
|
planet.resources.energy += (energyProduction * effectiveTimeDiff) / 3600
|
||||||
|
|
||||||
// 限制能量上限
|
// 限制能量上限
|
||||||
const capacity = calculateResourceCapacity(planet, bonuses.storageCapacityBonus)
|
const capacity = calculateResourceCapacity(planet, bonuses.storageCapacityBonus)
|
||||||
planet.resources.energy = Math.min(planet.resources.energy, capacity.energy)
|
planet.resources.energy = Math.min(planet.resources.energy, capacity.energy)
|
||||||
|
|
||||||
// 扣除能量消耗
|
// 扣除能量消耗
|
||||||
planet.resources.energy -= (energyConsumption * timeDiff) / 3600
|
planet.resources.energy -= (energyConsumption * effectiveTimeDiff) / 3600
|
||||||
|
|
||||||
// 能量不能为负数,最低为0
|
// 能量不能为负数,最低为0
|
||||||
planet.resources.energy = Math.max(0, planet.resources.energy)
|
planet.resources.energy = Math.max(0, planet.resources.energy)
|
||||||
@@ -143,11 +147,11 @@ export const updatePlanetResources = (
|
|||||||
energyProductionBonus: bonuses.energyProductionBonus
|
energyProductionBonus: bonuses.energyProductionBonus
|
||||||
})
|
})
|
||||||
|
|
||||||
// 更新资源(转换为每秒产量)
|
// 更新资源(转换为每秒产量,应用游戏速度)
|
||||||
planet.resources.metal += (production.metal * timeDiff) / 3600
|
planet.resources.metal += (production.metal * effectiveTimeDiff) / 3600
|
||||||
planet.resources.crystal += (production.crystal * timeDiff) / 3600
|
planet.resources.crystal += (production.crystal * effectiveTimeDiff) / 3600
|
||||||
planet.resources.deuterium += (production.deuterium * timeDiff) / 3600
|
planet.resources.deuterium += (production.deuterium * effectiveTimeDiff) / 3600
|
||||||
planet.resources.darkMatter += (production.darkMatter * timeDiff) / 3600
|
planet.resources.darkMatter += (production.darkMatter * effectiveTimeDiff) / 3600
|
||||||
|
|
||||||
// 限制资源上限
|
// 限制资源上限
|
||||||
planet.resources.metal = Math.min(planet.resources.metal, capacity.metal)
|
planet.resources.metal = Math.min(planet.resources.metal, capacity.metal)
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ import type { Resources, BuildQueueItem, Fleet } from '@/types/game'
|
|||||||
import { ShipType, DefenseType, BuildingType, TechnologyType } from '@/types/game'
|
import { ShipType, DefenseType, BuildingType, TechnologyType } from '@/types/game'
|
||||||
import { SHIPS, DEFENSES } from '@/config/gameConfig'
|
import { SHIPS, DEFENSES } from '@/config/gameConfig'
|
||||||
|
|
||||||
|
// 用于生成唯一ID的计数器
|
||||||
|
let shipQueueIdCounter = 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算舰船建造成本
|
* 计算舰船建造成本
|
||||||
*/
|
*/
|
||||||
@@ -153,13 +156,52 @@ export const checkShieldDomeLimit = (
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算导弹发射井容量
|
||||||
|
*/
|
||||||
|
export const calculateMissileSiloCapacity = (buildings: Partial<Record<BuildingType, number>>): number => {
|
||||||
|
const siloLevel = buildings[BuildingType.MissileSilo] || 0
|
||||||
|
return siloLevel * 10 // 每级存储10枚导弹
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算当前导弹总数
|
||||||
|
*/
|
||||||
|
export const calculateCurrentMissileCount = (defense: Partial<Record<DefenseType, number>>): number => {
|
||||||
|
const interplanetaryMissiles = defense[DefenseType.InterplanetaryMissile] || 0
|
||||||
|
const antiBallisticMissiles = defense[DefenseType.AntiBallisticMissile] || 0
|
||||||
|
return interplanetaryMissiles + antiBallisticMissiles
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查导弹容量限制
|
||||||
|
*/
|
||||||
|
export const checkMissileSiloLimit = (
|
||||||
|
defenseType: DefenseType,
|
||||||
|
currentDefense: Partial<Record<DefenseType, number>>,
|
||||||
|
buildings: Partial<Record<BuildingType, number>>,
|
||||||
|
quantity: number
|
||||||
|
): boolean => {
|
||||||
|
// 只对导弹类型进行检查
|
||||||
|
if (defenseType !== DefenseType.InterplanetaryMissile && defenseType !== DefenseType.AntiBallisticMissile) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const maxCapacity = calculateMissileSiloCapacity(buildings)
|
||||||
|
const currentCount = calculateCurrentMissileCount(currentDefense)
|
||||||
|
const newCount = currentCount + quantity
|
||||||
|
|
||||||
|
return newCount <= maxCapacity
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建舰船建造队列项
|
* 创建舰船建造队列项
|
||||||
*/
|
*/
|
||||||
export const createShipQueueItem = (shipType: ShipType, quantity: number, buildTime: number): BuildQueueItem => {
|
export const createShipQueueItem = (shipType: ShipType, quantity: number, buildTime: number): BuildQueueItem => {
|
||||||
const now = Date.now()
|
const now = Date.now()
|
||||||
|
shipQueueIdCounter++
|
||||||
return {
|
return {
|
||||||
id: `ship_${now}`,
|
id: `ship_${now}_${shipQueueIdCounter}`,
|
||||||
type: 'ship',
|
type: 'ship',
|
||||||
itemType: shipType,
|
itemType: shipType,
|
||||||
quantity,
|
quantity,
|
||||||
@@ -173,8 +215,9 @@ export const createShipQueueItem = (shipType: ShipType, quantity: number, buildT
|
|||||||
*/
|
*/
|
||||||
export const createDefenseQueueItem = (defenseType: DefenseType, quantity: number, buildTime: number): BuildQueueItem => {
|
export const createDefenseQueueItem = (defenseType: DefenseType, quantity: number, buildTime: number): BuildQueueItem => {
|
||||||
const now = Date.now()
|
const now = Date.now()
|
||||||
|
shipQueueIdCounter++
|
||||||
return {
|
return {
|
||||||
id: `defense_${now}`,
|
id: `defense_${now}_${shipQueueIdCounter}`,
|
||||||
type: 'defense',
|
type: 'defense',
|
||||||
itemType: defenseType,
|
itemType: defenseType,
|
||||||
quantity,
|
quantity,
|
||||||
|
|||||||
@@ -100,6 +100,11 @@ export const validateDefenseBuild = (
|
|||||||
return { valid: false, reason: 'errors.shieldDomeLimit' }
|
return { valid: false, reason: 'errors.shieldDomeLimit' }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 导弹发射井容量限制
|
||||||
|
if (!shipLogic.checkMissileSiloLimit(defenseType, planet.defense, planet.buildings, quantity)) {
|
||||||
|
return { valid: false, reason: 'errors.missileSiloLimit' }
|
||||||
|
}
|
||||||
|
|
||||||
return { valid: true }
|
return { valid: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user