Commit 740e86b2 authored by 陈冲's avatar 陈冲

feat: 后端接口优化

parent aebc5dc7
...@@ -34,8 +34,6 @@ const GAME_RUNNING_SECS: u64 = 60; ...@@ -34,8 +34,6 @@ const GAME_RUNNING_SECS: u64 = 60;
struct RoomPlayer { struct RoomPlayer {
/// 成绩分数,具体含义由前端和游戏逻辑自行定义,后端只负责存储和排序。 /// 成绩分数,具体含义由前端和游戏逻辑自行定义,后端只负责存储和排序。
score: i64, score: i64,
/// 客户端上一次提交的累计分数,用于重连后继续累计而不是覆盖旧分数。
last_client_score: i64,
// /// wechat原始token用于记录 // /// wechat原始token用于记录
// wechat: String, // wechat: String,
/// 是否在线,离线的玩家不允许提交分数,但保留在排行榜里。 /// 是否在线,离线的玩家不允许提交分数,但保留在排行榜里。
...@@ -474,6 +472,7 @@ async fn handle_room_command( ...@@ -474,6 +472,7 @@ async fn handle_room_command(
} }
} }
state.reset(); state.reset();
state.current_game_id = Some(format!("game{index}"));
state.status = RoomStatus::Start; state.status = RoomStatus::Start;
// let snapshot = state.snapshot(); // let snapshot = state.snapshot();
drop(state); drop(state);
...@@ -493,8 +492,14 @@ async fn handle_room_command( ...@@ -493,8 +492,14 @@ async fn handle_room_command(
//超过300人的情况 //超过300人的情况
if get_player_count() > 300 { if get_player_count() > 300 {
emit_msgpack(&socket, evt, &err_resp("本场游戏人员已满", Some(json!(3)))); emit_msgpack(&socket, evt, &err_resp("本场游戏人员已满", Some(json!(3))));
_ = socket.clone().disconnect();
return; return;
} }
let gameId = data
.get("gameId")
.and_then(|v| v.as_str())
.unwrap_or("")
.to_string();
let nickname = data let nickname = data
.get("nickname") .get("nickname")
.and_then(|value| value.as_str()) .and_then(|value| value.as_str())
...@@ -507,6 +512,22 @@ async fn handle_room_command( ...@@ -507,6 +512,22 @@ async fn handle_room_command(
.to_string(); .to_string();
if let Ok(mut state) = ROOM_STATE.lock() { if let Ok(mut state) = ROOM_STATE.lock() {
let Some(current_game_id) = state.current_game_id.clone() else {
drop(state);
return;
};
// 当前h5进入的不是大屏开启的游戏房间
if current_game_id != gameId {
drop(state);
emit_msgpack(
&socket,
evt,
&err_resp("当前游戏房间还未开启", Some(json!(2))),
);
_ = socket.clone().disconnect();
return;
}
let already_joined = state.players.contains_key(userid); let already_joined = state.players.contains_key(userid);
if already_joined { if already_joined {
if let Some(player) = state.players.get_mut(userid) { if let Some(player) = state.players.get_mut(userid) {
...@@ -532,7 +553,11 @@ async fn handle_room_command( ...@@ -532,7 +553,11 @@ async fn handle_room_command(
.and_then(|payload| payload.get("gameId")) .and_then(|payload| payload.get("gameId"))
.and_then(|value| value.as_str()) .and_then(|value| value.as_str())
{ {
emit_msgpack(&socket, "game_start_result", &ok_resp(Some(json!(game_id)))); emit_msgpack(
&socket,
"game_start_result",
&ok_resp(Some(json!(game_id))),
);
} }
} }
return; return;
...@@ -547,6 +572,7 @@ async fn handle_room_command( ...@@ -547,6 +572,7 @@ async fn handle_room_command(
Some(json!(2)), Some(json!(2)),
), ),
); );
_ = socket.clone().disconnect();
return; return;
} }
let entry_order = state.next_entry_order; let entry_order = state.next_entry_order;
...@@ -562,7 +588,6 @@ async fn handle_room_command( ...@@ -562,7 +588,6 @@ async fn handle_room_command(
}) })
.or_insert(RoomPlayer { .or_insert(RoomPlayer {
score: 0, score: 0,
last_client_score: 0,
online: true, online: true,
entry_order, entry_order,
nickname: nickname.to_string(), nickname: nickname.to_string(),
...@@ -576,7 +601,7 @@ async fn handle_room_command( ...@@ -576,7 +601,7 @@ async fn handle_room_command(
if let Some(mut player) = CLIENT_PLAYER_MAP.get_mut(userid) { if let Some(mut player) = CLIENT_PLAYER_MAP.get_mut(userid) {
player.0 = 1; player.0 = 1;
} }
emit_msgpack(&socket, evt, &ok_resp(None)); emit_msgpack(&socket, evt, &ok_resp(Some(json!(current_game_id))));
// 给所有管理员广播房间状态更新 // 给所有管理员广播房间状态更新
broadcast_msgpack_all_admin( broadcast_msgpack_all_admin(
evt, evt,
...@@ -630,9 +655,12 @@ async fn handle_room_command( ...@@ -630,9 +655,12 @@ async fn handle_room_command(
if !state.players.contains_key(userid) { if !state.players.contains_key(userid) {
drop(state); drop(state);
emit_msgpack(&socket, evt, &err_resp("您不在房间中", None)); emit_msgpack(&socket, evt, &err_resp("您不在房间中", None));
_ = socket.clone().disconnect();
return;
} else if !matches!(state.status, RoomStatus::Running) { } else if !matches!(state.status, RoomStatus::Running) {
drop(state); drop(state);
emit_msgpack(&socket, evt, &err_resp("游戏还未开始", None)); emit_msgpack(&socket, evt, &err_resp("游戏还未开始", None));
return;
} }
/* else if !state /* else if !state
.players .players
...@@ -645,16 +673,11 @@ async fn handle_room_command( ...@@ -645,16 +673,11 @@ async fn handle_room_command(
}*/ }*/
else if state.players.contains_key(userid) { else if state.players.contains_key(userid) {
let player = state.players.get_mut(userid).unwrap(); let player = state.players.get_mut(userid).unwrap();
let score_delta = if score >= player.last_client_score { player.score = score;
score - player.last_client_score
} else {
score
};
player.score += score_delta.max(0);
player.last_client_score = score;
// player.wechat = wechat.to_string(); // player.wechat = wechat.to_string();
player.online = true; player.online = true;
drop(state); drop(state);
return;
// 方案1:每有一名玩家提交时发送给所有玩家跟管理员,玩家过多时发送太频繁, // 方案1:每有一名玩家提交时发送给所有玩家跟管理员,玩家过多时发送太频繁,
// 这里会选第2种方案, 游戏中时每秒发给所有玩家跟管理员 (push_room_score_ranking) // 这里会选第2种方案, 游戏中时每秒发给所有玩家跟管理员 (push_room_score_ranking)
...@@ -667,6 +690,7 @@ async fn handle_room_command( ...@@ -667,6 +690,7 @@ async fn handle_room_command(
} else { } else {
drop(state); drop(state);
emit_msgpack(&socket, evt, &err_resp("提交异常", None)); emit_msgpack(&socket, evt, &err_resp("提交异常", None));
return;
} }
} }
} }
...@@ -683,25 +707,34 @@ async fn handle_room_command( ...@@ -683,25 +707,34 @@ async fn handle_room_command(
if wechat.is_empty() { if wechat.is_empty() {
return; return;
} }
let (score, rank) = if let Ok(state) = ROOM_STATE.lock() { let (score, rank, ranking) = if let Ok(state) = ROOM_STATE.lock() {
//防止客户端提交的状态还在Running中 //防止客户端提交的状态还在Running中
if !matches!(state.status, RoomStatus::Submit | RoomStatus::Running) { if !matches!(state.status, RoomStatus::Submit | RoomStatus::Running) {
drop(state); drop(state);
return; return;
} }
let full_ranking = state.full_score_ranking();
let ranking = RoomState::ranking_payload(
&full_ranking
.iter()
.take(ROOM_SCORE_RANK_LIMIT)
.cloned()
.collect::<Vec<_>>(),
);
let server_score = state let server_score = state
.players .players
.get(userid) .get(userid)
.map(|player| player.score) .map(|player| player.score)
.unwrap_or(score); .unwrap_or(score);
let server_rank = state let server_rank = full_ranking
.player_rank(userid) .iter()
.map(|rank| rank as i64) .position(|player| player.wechat == userid)
.map(|index| (index + 1) as i64)
.unwrap_or(rank); .unwrap_or(rank);
drop(state); drop(state);
(server_score, server_rank) (server_score, server_rank, ranking)
} else { } else {
(score, rank) (score, rank, Vec::new())
}; };
let game = Game { let game = Game {
wechat_id: wechat.to_string(), wechat_id: wechat.to_string(),
...@@ -713,7 +746,14 @@ async fn handle_room_command( ...@@ -713,7 +746,14 @@ async fn handle_room_command(
create_date: None, create_date: None,
}; };
if game.insert().await { if game.insert().await {
emit_msgpack(&socket, evt, &ok_resp(None)); emit_msgpack(
&socket,
evt,
&ok_resp(Some(json!({
"list": ranking,
"rank": rank
}))),
);
} else { } else {
emit_msgpack(&socket, evt, &err_resp("提交异常", None)); emit_msgpack(&socket, evt, &err_resp("提交异常", None));
} }
...@@ -926,7 +966,6 @@ pub async fn login(req: &mut Request, res: &mut Response) { ...@@ -926,7 +966,6 @@ pub async fn login(req: &mut Request, res: &mut Response) {
let params = match req.parse_body::<HashMap<String, String>>().await { let params = match req.parse_body::<HashMap<String, String>>().await {
Ok(params) => params, Ok(params) => params,
Err(_) => { Err(_) => {
res.status_code(StatusCode::BAD_REQUEST);
res.render(Json(err_resp("参数格式错误", None))); res.render(Json(err_resp("参数格式错误", None)));
return; return;
} }
...@@ -942,7 +981,6 @@ pub async fn login(req: &mut Request, res: &mut Response) { ...@@ -942,7 +981,6 @@ pub async fn login(req: &mut Request, res: &mut Response) {
.unwrap_or_default(); .unwrap_or_default();
if username.is_empty() || password.is_empty() { if username.is_empty() || password.is_empty() {
res.status_code(StatusCode::BAD_REQUEST);
res.render(Json(err_resp("username 和 password 不能为空", None))); res.render(Json(err_resp("username 和 password 不能为空", None)));
return; return;
} }
...@@ -963,9 +1001,15 @@ pub async fn login(req: &mut Request, res: &mut Response) { ...@@ -963,9 +1001,15 @@ pub async fn login(req: &mut Request, res: &mut Response) {
let passphrase = utils::get_aes_passphrase(); let passphrase = utils::get_aes_passphrase();
if passphrase.is_none() { if passphrase.is_none() {
res.status_code(StatusCode::BAD_REQUEST);
res.render(Json(err_resp("username 和 password 不能为空", None))); res.render(Json(err_resp("username 和 password 不能为空", None)));
return;
} }
//当前管理员已登录,不能重复登录
if (CLIENT_ADMIN_MAP.contains_key(&manager.token)) {
res.render(Json(err_resp("当前管理员已登录,不能重复登录", None)));
return;
}
res.render(Json(ok_resp(Some(json!({ res.render(Json(ok_resp(Some(json!({
"passphrase": passphrase, "passphrase": passphrase,
"token": manager.token, "token": manager.token,
......
...@@ -12,12 +12,14 @@ ...@@ -12,12 +12,14 @@
"crypto-js": "^4.2.0", "crypto-js": "^4.2.0",
"msgpack": "^1.0.3", "msgpack": "^1.0.3",
"socket.io-client": "^4.8.3", "socket.io-client": "^4.8.3",
"vconsole": "^3.15.1",
"vue": "^3.5.32", "vue": "^3.5.32",
"vue-router": "^4.6.4" "vue-router": "^4.6.4"
}, },
"devDependencies": { "devDependencies": {
"@tsconfig/node24": "^24.0.4", "@tsconfig/node24": "^24.0.4",
"@types/node": "^24.12.2", "@types/node": "^24.12.2",
"@vitejs/plugin-basic-ssl": "^2.3.0",
"@vitejs/plugin-vue": "^6.0.6", "@vitejs/plugin-vue": "^6.0.6",
"@vue/tsconfig": "^0.9.1", "@vue/tsconfig": "^0.9.1",
"npm-run-all2": "^8.0.4", "npm-run-all2": "^8.0.4",
...@@ -438,6 +440,15 @@ ...@@ -438,6 +440,15 @@
"@babel/core": "^7.0.0-0" "@babel/core": "^7.0.0-0"
} }
}, },
"node_modules/@babel/runtime": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz",
"integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/template": { "node_modules/@babel/template": {
"version": "7.29.7", "version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz",
...@@ -929,6 +940,19 @@ ...@@ -929,6 +940,19 @@
"undici-types": "~7.16.0" "undici-types": "~7.16.0"
} }
}, },
"node_modules/@vitejs/plugin-basic-ssl": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-2.3.0.tgz",
"integrity": "sha512-bdyo8rB3NnQbikdMpHaML9Z1OZPBu6fFOBo+OtxsBlvMJtysWskmBcnbIDhUqgC8tcxNv/a+BcV5U+2nQMm1OQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.0.0 || ^20.0.0 || >=22.0.0"
},
"peerDependencies": {
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
"node_modules/@vitejs/plugin-vue": { "node_modules/@vitejs/plugin-vue": {
"version": "6.0.7", "version": "6.0.7",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.7.tgz", "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.7.tgz",
...@@ -1334,6 +1358,29 @@ ...@@ -1334,6 +1358,29 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/copy-text-to-clipboard": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.2.tgz",
"integrity": "sha512-T6SqyLd1iLuqPA90J5N4cTalrtovCySh58iiZDGJ6FGznbclKh4UI+FGacQSgFzwKG77W7XT5gwbVEbd9cIH1A==",
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/core-js": {
"version": "3.49.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.49.0.tgz",
"integrity": "sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==",
"hasInstallScript": true,
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/core-js"
}
},
"node_modules/cross-spawn": { "node_modules/cross-spawn": {
"version": "7.0.6", "version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
...@@ -2035,6 +2082,11 @@ ...@@ -2035,6 +2082,11 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/mutation-observer": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/mutation-observer/-/mutation-observer-1.0.3.tgz",
"integrity": "sha512-M/O/4rF2h776hV7qGMZUH3utZLO/jK7p8rnNgGkjKUw8zCGjRQPxB8z6+5l8+VjRUQ3dNYu4vjqXYLr+U8ZVNA=="
},
"node_modules/nan": { "node_modules/nan": {
"version": "2.27.0", "version": "2.27.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.27.0.tgz", "resolved": "https://registry.npmjs.org/nan/-/nan-2.27.0.tgz",
...@@ -2512,6 +2564,18 @@ ...@@ -2512,6 +2564,18 @@
"browserslist": ">= 4.21.0" "browserslist": ">= 4.21.0"
} }
}, },
"node_modules/vconsole": {
"version": "3.15.1",
"resolved": "https://registry.npmjs.org/vconsole/-/vconsole-3.15.1.tgz",
"integrity": "sha512-KH8XLdrq9T5YHJO/ixrjivHfmF2PC2CdVoK6RWZB4yftMykYIaXY1mxZYAic70vADM54kpMQF+dYmvl5NRNy1g==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.17.2",
"copy-text-to-clipboard": "^3.0.1",
"core-js": "^3.11.0",
"mutation-observer": "^1.0.3"
}
},
"node_modules/vite": { "node_modules/vite": {
"version": "8.0.14", "version": "8.0.14",
"resolved": "https://registry.npmjs.org/vite/-/vite-8.0.14.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.14.tgz",
......
...@@ -8,13 +8,15 @@ const props = withDefaults(defineProps<{ ...@@ -8,13 +8,15 @@ const props = withDefaults(defineProps<{
mode?: 'contain' | 'cover' mode?: 'contain' | 'cover'
backgroundMode?: 'contain' | 'cover', backgroundMode?: 'contain' | 'cover',
showGameRule?: boolean, showGameRule?: boolean,
showGameRank?: boolean,
}>(), { }>(), {
background: 'linear-gradient(180deg, #fbf7ef 0%, #ffe7dc 100%)', background: 'linear-gradient(180deg, #fbf7ef 0%, #ffe7dc 100%)',
width: 750, width: 750,
height: 1624, height: 1624,
mode: 'contain', mode: 'contain',
backgroundMode: 'cover', backgroundMode: 'cover',
showGameRule: false showGameRule: false,
showGameRank: false
}) })
const emit = defineEmits<{ const emit = defineEmits<{
...@@ -156,6 +158,11 @@ defineExpose({ ...@@ -156,6 +158,11 @@ defineExpose({
<slot name="gameRule"></slot> <slot name="gameRule"></slot>
</div> </div>
</Transition> </Transition>
<Transition name="game-rule-fade">
<div v-if="!countdownVisible && showGameRank" class="modal-container">
<slot name="gameRank"></slot>
</div>
</Transition>
</main> </main>
</template> </template>
......
...@@ -22,6 +22,8 @@ type GameSocketOptions = { ...@@ -22,6 +22,8 @@ type GameSocketOptions = {
onRoomBack?: (data: any) => void onRoomBack?: (data: any) => void
} }
let gameId = '';
function getGameIndex(data: any) { function getGameIndex(data: any) {
if (typeof data === 'object' && data !== null) { if (typeof data === 'object' && data !== null) {
return Number(data.game ?? data.game_id ?? data.gameId ?? data.id) return Number(data.game ?? data.game_id ?? data.gameId ?? data.id)
...@@ -41,7 +43,7 @@ function getGameHomePath(data: any) { ...@@ -41,7 +43,7 @@ function getGameHomePath(data: any) {
} }
export function joinSharedRoom(nickname: string, token: string, avatar: string) { export function joinSharedRoom(nickname: string, token: string, avatar: string) {
return sendSocketMessage('room_join', { nickname: nickname, token, avatar }) return sendSocketMessage('room_join', { nickname: nickname, token, avatar, gameId: gameId })
} }
export function sendGameMessage(cmd: string, data: any = {}) { export function sendGameMessage(cmd: string, data: any = {}) {
...@@ -50,6 +52,7 @@ export function sendGameMessage(cmd: string, data: any = {}) { ...@@ -50,6 +52,7 @@ export function sendGameMessage(cmd: string, data: any = {}) {
export const userJoinStatus = ref(false) export const userJoinStatus = ref(false)
export function useGameSocket(options: GameSocketOptions) { export function useGameSocket(options: GameSocketOptions) {
gameId = options.gameId;
const router = useRouter() const router = useRouter()
let socket: Socket | null = null let socket: Socket | null = null
let offSocketMessage: (() => void) | undefined let offSocketMessage: (() => void) | undefined
...@@ -76,7 +79,10 @@ export function useGameSocket(options: GameSocketOptions) { ...@@ -76,7 +79,10 @@ export function useGameSocket(options: GameSocketOptions) {
if (evt === 'room_join_result') { if (evt === 'room_join_result') {
switch (data) { switch (data) {
case 1: userJoinStatus.value = true; break; case 1: userJoinStatus.value = true; break;
case 3: alert(msg); break; case 2:
case 3:
alert(msg);
break;
} }
} else if (evt == 'submit_score_save') { } else if (evt == 'submit_score_save') {
//提交分数的情况下有问题的情况下,只重试3次 //提交分数的情况下有问题的情况下,只重试3次
...@@ -106,6 +112,10 @@ export function useGameSocket(options: GameSocketOptions) { ...@@ -106,6 +112,10 @@ export function useGameSocket(options: GameSocketOptions) {
break break
} }
case 'room_join_result': { case 'room_join_result': {
if (data != options.gameId) {
alert('当前游戏房间还未开启');
return;
}
userJoinStatus.value = true userJoinStatus.value = true
break break
} }
......
<script setup lang="ts"> <script setup lang="ts">
import { onBeforeUnmount, onMounted, ref } from 'vue' import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
import { cssAssetUrl } from '@/commons/assets.ts' import { cssAssetUrl } from '@/commons/assets.ts'
import MobileStage from '@/components/MobileStage.vue' import MobileStage from '@/components/MobileStage.vue'
import { useGameSocket, joinSharedRoom, sendGameMessage, userJoinStatus } from '@/composables/useGameSocket' import { useGameSocket, joinSharedRoom, sendGameMessage, userJoinStatus } from '@/composables/useGameSocket'
import LoadingView from './views/LoadingView.vue' import LoadingView from './views/LoadingView.vue'
import PlayingView from './views/PlayingView.vue' import PlayingView from './views/PlayingView.vue'
import ScoreView from './views/ScoreView.vue'
import { $getWechat } from '@/commons/utils.ts' import { $getWechat } from '@/commons/utils.ts'
import { playGame1Music } from '@/commons/music' import { playGame1Music } from '@/commons/music'
type GameView = 'loading' | 'playing' | 'score' type GameView = 'loading' | 'playing'
type RankPlayer = {
rank: number
nickname: string
avatar: string
score: number | string
}
const imageUrls: Record<string, string> = { const imageUrls: Record<string, string> = {
bg: cssAssetUrl('game6/bg.png'), bg: cssAssetUrl('game6/bg.png'),
...@@ -29,6 +34,8 @@ const imageUrls: Record<string, string> = { ...@@ -29,6 +34,8 @@ const imageUrls: Record<string, string> = {
rabbitshowprite: cssAssetUrl('game6/rabbit_show.png'), rabbitshowprite: cssAssetUrl('game6/rabbit_show.png'),
land: cssAssetUrl('game6/land.png'), land: cssAssetUrl('game6/land.png'),
hammer: cssAssetUrl('game6/hammer.png'), hammer: cssAssetUrl('game6/hammer.png'),
ranklist: cssAssetUrl('game6/ranklist.png'),
rule: cssAssetUrl('game1/rule.png')
} }
const wechat = $getWechat() const wechat = $getWechat()
...@@ -37,6 +44,19 @@ const countdownInterval = ref(60) ...@@ -37,6 +44,19 @@ const countdownInterval = ref(60)
const isDivDescVisible = ref(false) const isDivDescVisible = ref(false)
const score = ref(0) const score = ref(0)
const rank = ref(0) //排名 const rank = ref(0) //排名
const rankList = ref<RankPlayer[]>([])
const displayRankList = computed<RankPlayer[]>(() => {
const list = rankList.value.slice(0, 10)
return Array.from({ length: 10 }, (_, index) => {
return list[index] ?? {
rank: index + 1,
nickname: '-',
avatar: '',
score: '-',
}
})
})
// const guFrames: [string, string, string] = [imageUrls.gu01, imageUrls.gu02, imageUrls.gu03] // const guFrames: [string, string, string] = [imageUrls.gu01, imageUrls.gu02, imageUrls.gu03]
// const currentGu = ref(imageUrls.gu01) // const currentGu = ref(imageUrls.gu01)
const isGuPlaying = ref(false) const isGuPlaying = ref(false)
...@@ -44,6 +64,7 @@ const token = ref(wechat?.token ?? '') ...@@ -44,6 +64,7 @@ const token = ref(wechat?.token ?? '')
const nickname = ref(wechat?.nickname ?? '') const nickname = ref(wechat?.nickname ?? '')
const avatar = ref(wechat?.avatar ?? '') const avatar = ref(wechat?.avatar ?? '')
const showGameRule = ref(false) const showGameRule = ref(false)
const showGameRank = ref(false)
const mobileStageRef = ref<InstanceType<typeof MobileStage> | null>(null) const mobileStageRef = ref<InstanceType<typeof MobileStage> | null>(null)
const _offSocketMessage = ref<(() => void) | undefined>() const _offSocketMessage = ref<(() => void) | undefined>()
...@@ -66,21 +87,21 @@ function stopGameCountdown() { ...@@ -66,21 +87,21 @@ function stopGameCountdown() {
} }
} }
function submitScore(save: boolean = false) { function submitScore(save: boolean = false, currentTick = score.value) {
//最后提交保存在数据库中 //最后提交保存在数据库中
if (save) { if (save) {
//item_num 游戏项目(1到6) //item_num 游戏项目(1到6)
//wechat 原始token //wechat 原始token
sendGameMessage('submit_score_save', { sendGameMessage('submit_score_save', {
score: score.value, score: currentTick,
wechat: wechat.token_origin, wechat: wechat.token_origin,
item_num: 1, item_num: 6,
nickname: wechat.nickname, nickname: wechat.nickname,
avatar: wechat.avatar, avatar: wechat.avatar,
rank: rank.value, rank: rank.value,
}) })
} else { } else {
sendGameMessage('submit_score', { score: score.value }) sendGameMessage('submit_score', { score: currentTick })
} }
} }
...@@ -97,7 +118,7 @@ function startGameCountdown(seconds = 60) { ...@@ -97,7 +118,7 @@ function startGameCountdown(seconds = 60) {
gameCountdownTimer = undefined gameCountdownTimer = undefined
setDivDescVisible(false) setDivDescVisible(false)
submitScore(true) submitScore(true)
showScoreView() showGameOverRank()
return return
} }
...@@ -121,10 +142,12 @@ function resetToLoadingView() { ...@@ -121,10 +142,12 @@ function resetToLoadingView() {
} }
score.value = 0 score.value = 0
rank.value = 0 rank.value = 0
rankList.value = []
countdownInterval.value = 60 countdownInterval.value = 60
// currentGu.value = guFrames[0] // currentGu.value = guFrames[0]
isGuPlaying.value = false isGuPlaying.value = false
userJoinStatus.value = false userJoinStatus.value = false
showGameRank.value = false
currentView.value = 'loading' currentView.value = 'loading'
setDivDescVisible(false) setDivDescVisible(false)
} }
...@@ -132,24 +155,19 @@ function resetToLoadingView() { ...@@ -132,24 +155,19 @@ function resetToLoadingView() {
function startGameView() { function startGameView() {
stopGameCountdown() stopGameCountdown()
score.value = 0 score.value = 0
rank.value = 0
rankList.value = []
// currentGu.value = guFrames[0] // currentGu.value = guFrames[0]
showGameRank.value = false
currentView.value = 'playing' currentView.value = 'playing'
startGameCountdown() startGameCountdown()
} }
function showScoreView() { function showGameOverRank() {
stopGameCountdown() stopGameCountdown()
setDivDescVisible(false) setDivDescVisible(false)
currentView.value = 'score' currentView.value = 'loading'
} showGameRank.value = true
function replayGame() {
startGameView()
}
function backToWaiting() {
resetToLoadingView()
joinSharedRoom(nickname.value, token.value, avatar.value)
} }
function handleRoomBack() { function handleRoomBack() {
...@@ -160,8 +178,9 @@ function handleRoomBack() { ...@@ -160,8 +178,9 @@ function handleRoomBack() {
} }
const touchHandler = (scoreDelta: number) => { const touchHandler = (scoreDelta: number) => {
score.value += scoreDelta const nextTick = score.value + scoreDelta
submitScore() score.value = nextTick
submitScore(false, nextTick)
playGame1Music(); playGame1Music();
} }
...@@ -187,6 +206,20 @@ if (wechat) { ...@@ -187,6 +206,20 @@ if (wechat) {
if (Number.isFinite(nextRank) && nextRank > 0) { if (Number.isFinite(nextRank) && nextRank > 0) {
rank.value = nextRank rank.value = nextRank
} }
} else if (typeof data === 'object' && data) {
if (Array.isArray(data.list)) {
rankList.value = data.list.map((item: any, index: number) => ({
rank: Number(item?.rank ?? index + 1),
nickname: String(item?.nickname ?? ''),
avatar: String(item?.avatar ?? ''),
score: Number(item?.score ?? 0),
}))
}
const nextRank = Number(data.rank)
if (Number.isFinite(nextRank) && nextRank > 0) {
rank.value = nextRank
}
} }
}, },
onRescoreSubmitted: (_recount) => { onRescoreSubmitted: (_recount) => {
...@@ -221,34 +254,73 @@ const showGameRuleHandler = () => { ...@@ -221,34 +254,73 @@ const showGameRuleHandler = () => {
} }
const renderBG = () => { const renderBG = () => {
if (currentView.value === 'loading') { if (currentView.value == 'playing') {
return `${imageUrls.bg} center/cover`;
}
return `${imageUrls.bg2} center/cover` return `${imageUrls.bg2} center/cover`
}
return `${imageUrls.bg} center/cover`;
}
const rankCloseHandler = () => {
showGameRank.value = false
} }
</script> </script>
<template> <template>
<MobileStage v-if="token" :showGameRule="showGameRule" ref="mobileStageRef" :background="`${renderBG()}`"> <MobileStage v-if="token" :showGameRule="showGameRule" :showGameRank="showGameRank" ref="mobileStageRef"
:background="`${renderBG()}`">
<template #gameRule> <template #gameRule>
<div class="rule-container"> <div class="rule-container">
<div class="rule-txt-container"> <div class="rule-txt-container">
<div class="rule-title">游戏规则</div> <div class="rule-title">游戏规则</div>
<div class="rule-txt"> <div class="rule-txt">
微信用户通过扫描大屏幕二维码参与,可容纳多人同时进行且比拼打地鼠,谁打的最多即为获胜,游戏结束按分值高低先后排名,有机会获得新疆福彩定制周边礼品一份。 1. 主持人开赛点击敲击,打中地鼠 + 5 分、误击白兔-3分;<br />
2. 限时比拼反应速度,结束后按积分排名;<br />
3. 高分用户有机会领取新疆福彩定制周边;<br />
4. 禁止外挂作弊,违规账号取消成绩与领奖资格;<br /><br />
祝您游戏愉快!
</div>
</div>
<div class="rule-close" @click="showGameRuleHandler"></div>
</div>
</template>
<template #gameRank>
<div class="ranklist-container">
<div class="txt-title">排行</div>
<div class="list-container">
<div class="row row-1">
<div class="col-1">排名</div>
<div class="col-2">用户</div>
<div class="col-3">成绩</div>
</div>
<div class="row-2">
<div class="row rank-row" v-for="(item, index) in displayRankList"
:key="`${item.rank}-${index}`">
<div class="col-1">
<div>{{ item.rank }}</div>
</div>
<div class="col-2">
<div class="avatar"
:style="item.avatar ? { backgroundImage: `url(${item.avatar})` } : {}"></div>
<div>{{ item.nickname }}</div>
</div>
<div class="col-3">{{ item.score }}</div>
</div>
</div>
<div class="row row-3">
<div class="col-1">{{ rank > 0 ? rank : '未上榜' }}</div>
<div class="col-2">
<div class="avatar" :style="{ backgroundImage: `url(${avatar})` }"></div>
<div>{{ nickname }}</div>
</div> </div>
<div class="col-3">{{ score }}</div>
</div> </div>
<div class="rule-close">
<div @click="showGameRuleHandler"></div>
</div> </div>
</div> </div>
<div class="img-close" @click="rankCloseHandler"></div>
</template> </template>
<LoadingView v-if="currentView === 'loading'" :image-urls="imageUrls" :user-join-status="userJoinStatus" <LoadingView v-if="currentView === 'loading'" :image-urls="imageUrls" :user-join-status="userJoinStatus"
@touchGameRule="showGameRuleHandler" /> @touchGameRule="showGameRuleHandler" />
<PlayingView v-else-if="currentView === 'playing'" :image-urls="imageUrls" :tick="score" :rank="rank" <PlayingView v-else :image-urls="imageUrls" :tick="score" :rank="rank" :countdown-interval="countdownInterval"
:countdown-interval="countdownInterval" :is-div-desc-visible="isDivDescVisible" @touch="touchHandler" /> :is-div-desc-visible="isDivDescVisible" @touch="touchHandler" />
<ScoreView v-else :image-urls="imageUrls" :rank="rank" :tick="score" @replay="replayGame"
@back="backToWaiting" />
</MobileStage> </MobileStage>
<div v-else style="text-align: center; width: 100vw; height: 100vh; line-height: 30; font-size: 20px;"> <div v-else style="text-align: center; width: 100vw; height: 100vh; line-height: 30; font-size: 20px;">
请使用微信扫码进入游戏 请使用微信扫码进入游戏
...@@ -257,41 +329,130 @@ const renderBG = () => { ...@@ -257,41 +329,130 @@ const renderBG = () => {
<style scoped> <style scoped>
.rule-container { .rule-container {
.rule-txt-container { .rule-txt-container {
background: #FFF9E4; position: absolute;
margin: 0 40px; background: v-bind('imageUrls.rule') center / cover no-repeat;
border-radius: 5px; width: 692px;
padding-top: 20px; height: 797px;
padding-bottom: 10px; left: -157px;
top: -75px;
transform: scale(0.5);
.rule-title { .rule-title {
text-align: center; text-align: center;
color: #850000; color: white;
font-weight: bold; font-weight: bold;
font-size: 15pt; font-size: 22pt;
margin-top: 10px;
letter-spacing: 4px;
} }
.rule-txt { .rule-txt {
font-size: 12pt; font-size: 26pt;
padding: 10px; padding: 40px;
margin-top: 10px; margin-top: 10px;
color: #AA0000;
} }
} }
.rule-close { .rule-close {
width: 32px; width: 57px;
height: 130px; height: 57px;
margin: 0 auto; margin: 0 auto;
margin-top: 450px;
background: v-bind('imageUrls.close') center/cover; background: v-bind('imageUrls.close') center/cover;
position: relative; position: relative;
transform: scale(0.8);
}
}
.ranklist-container {
width: 747px;
height: 1084px;
background: v-bind('imageUrls.ranklist');
transform: translate(-50%, -50%) scale(0.45);
left: 50%;
top: 50%;
position: absolute;
.txt-title {
width: 100%;
text-align: center;
font-size: 50px;
margin-top: 35px;
font-weight: bold;
color: #AA0000;
letter-spacing: 2px;
}
>div { .list-container {
width: calc(100% - 90px);
height: calc(100% - 210px);
position: absolute; position: absolute;
bottom: 0; left: 40px;
width: 32px; top: 140px;
height: 32px; text-align: center;
border-radius: 16px; height: 73px;
line-height: 73px;
font-size: 32px;
.row {
display: grid;
grid-template-columns: 150px auto 150px;
align-items: center;
} }
.row-1 {
color: #AA0000;
font-weight: bold;
background: linear-gradient(-84deg, #FFD396 0%, #FFF3D1 53%, #FFD59C 100%);
border-radius: 20px 20px 0px 0px;
} }
.row-2 {
color: #633911;
.rank-row:nth-child(odd) {
background: #F2E2AE;
}
.rank-row:nth-child(even) {
background: #FCEEBF;
}
.col-1 {
position: relative;
}
}
.row-3 {
background: linear-gradient(0deg, #F4B64C 0%, #F7C96F 100%);
border-radius: 0px 0px 20px 20px;
}
.col-2 {
display: flex;
align-items: center;
justify-content: center;
gap: 18px;
.avatar {
width: 48px;
height: 48px;
flex: 0 0 auto;
border-radius: 50%;
background-position: center;
background-size: cover;
}
}
}
}
.img-close {
width: 57px;
height: 57px;
border-radius: 29px;
background: v-bind('imageUrls.close')center/cover;
transform: scale(0.7);
margin-top: 500px;
} }
</style> </style>
...@@ -28,6 +28,7 @@ type TargetItem = { ...@@ -28,6 +28,7 @@ type TargetItem = {
} }
const list = ref<TargetItem[]>([]); const list = ref<TargetItem[]>([]);
const moleContainerRef = ref<HTMLElement | null>(null)
for (let i = 0; i < 9; i++) { for (let i = 0; i < 9; i++) {
list.value.push({ list.value.push({
id: i, id: i,
...@@ -129,6 +130,45 @@ function handleTargetTouch(index: number) { ...@@ -129,6 +130,45 @@ function handleTargetTouch(index: number) {
}, item.hitMs) }, item.hitMs)
} }
function handleBoardTouch(event: MouseEvent) {
const container = moleContainerRef.value
if (!container) {
return
}
const rect = container.getBoundingClientRect()
const x = ((event.clientX - rect.left) / rect.width) * 750
const y = ((event.clientY - rect.top) / rect.height) * 600
const colWidth = 250
const rowGap = 70
const rowHeight = (600 - rowGap * 2) / 3
const hitRadius = 225
let targetIndex = -1
let targetDistance = Number.POSITIVE_INFINITY
list.value.forEach((item, index) => {
if (!item.kind || item.state === 'idle' || item.state === 'hit') {
return
}
const col = index % 3
const row = Math.floor(index / 3)
const centerX = col * colWidth + colWidth / 2
const centerY = row * (rowHeight + rowGap) + rowHeight / 2
const distance = Math.hypot(x - centerX, y - centerY)
if (distance <= hitRadius && distance < targetDistance) {
targetIndex = index
targetDistance = distance
}
})
if (targetIndex >= 0) {
handleTargetTouch(targetIndex)
}
}
onMounted(() => { onMounted(() => {
scheduleRandomTargets() scheduleRandomTargets()
}) })
...@@ -165,16 +205,14 @@ onBeforeUnmount(() => { ...@@ -165,16 +205,14 @@ onBeforeUnmount(() => {
</div> </div>
</div> </div>
<div class="mole-container"> <div ref="moleContainerRef" class="mole-container" @click="handleBoardTouch">
<div v-for="(item, index) in list" :key="item.id"> <div v-for="(item, index) in list" :key="item.id">
<div class="img-land"></div> <div class="img-land"></div>
<button v-if="item.kind" class="mole-hit-area" type="button" @click="handleTargetTouch(index)"> <span v-if="item.kind" class="img-mole" :class="[`is-${item.kind}`, `is-${item.state}`]" :style="{
<span class="img-mole" :class="[`is-${item.kind}`, `is-${item.state}`]" :style="{
'--show-duration': `${item.showMs}ms`, '--show-duration': `${item.showMs}ms`,
'--hide-duration': `${item.hideMs}ms`, '--hide-duration': `${item.hideMs}ms`,
'--hit-duration': `${item.hitMs}ms`, '--hit-duration': `${item.hitMs}ms`,
}"></span> }"></span>
</button>
</div> </div>
</div> </div>
<div class="img-hammer"></div> <div class="img-hammer"></div>
...@@ -266,18 +304,6 @@ onBeforeUnmount(() => { ...@@ -266,18 +304,6 @@ onBeforeUnmount(() => {
} }
} }
.mole-hit-area {
position: absolute;
inset: 0;
}
.mole-hit-area {
z-index: 2;
padding: 0;
border: 0;
background: transparent;
}
.img-land, .img-land,
.img-mole { .img-mole {
position: absolute; position: absolute;
......
...@@ -9,6 +9,7 @@ defineProps<{ ...@@ -9,6 +9,7 @@ defineProps<{
}>() }>()
defineEmits<{ defineEmits<{
showRank: []
replay: [] replay: []
back: [] back: []
}>() }>()
...@@ -24,23 +25,6 @@ onMounted(() => { ...@@ -24,23 +25,6 @@ onMounted(() => {
<template> <template>
<div class="h5-page game-stage"> <div class="h5-page game-stage">
<div class="img-logo"></div> <div class="img-logo"></div>
<div class="bg-bottom"></div>
<!-- <div class="img-score">
<div class="score-avatar"
:style="`background: url(${avatar});border-radius:66px;width:132px;height:132px;`"></div>
<div class="score-content">
<div>{{ nickname }}</div>
<div>您的成绩</div>
<div>击鼓次数(次)</div>
<div>{{ tick }}</div>
<div>最终排名</div>
<div><label>{{ rank }}</label></div>
</div>
</div>
<div class="btn-group">
<div class="btn-replay" @click="$emit('replay')"></div>
<div class="btn-back" @click="$emit('back')"></div>
</div> -->
</div> </div>
</template> </template>
...@@ -52,16 +36,6 @@ onMounted(() => { ...@@ -52,16 +36,6 @@ onMounted(() => {
padding: 0; padding: 0;
} }
.bg-bottom {
position: absolute;
bottom: 0;
left: var(--stage-viewport-left, 0);
width: var(--stage-viewport-width, 750px);
height: 479px;
background: v-bind('imageUrls.bg') center/cover;
opacity: 0.6;
}
.img-logo { .img-logo {
position: absolute; position: absolute;
top: 66px; top: 66px;
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
"dependencies": { "dependencies": {
"@msgpack/msgpack": "^3.1.3", "@msgpack/msgpack": "^3.1.3",
"crypto-js": "^4.2.0", "crypto-js": "^4.2.0",
"msgpack": "^1.0.3",
"socket.io-client": "^4.8.3", "socket.io-client": "^4.8.3",
"vue": "^3.5.32", "vue": "^3.5.32",
"vue-router": "^4.6.4" "vue-router": "^4.6.4"
...@@ -597,9 +596,9 @@ ...@@ -597,9 +596,9 @@
} }
}, },
"node_modules/@oxc-project/types": { "node_modules/@oxc-project/types": {
"version": "0.132.0", "version": "0.133.0",
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.132.0.tgz", "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz",
"integrity": "sha512-FESMOxil5Se014ui/Eq8fT5uHJo6nIRwH0PfJrZJXs6Gek3ZVFOrpUv3YIZT20m+extU98Hg1Ym72U58rlsxUQ==", "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"funding": { "funding": {
...@@ -614,9 +613,9 @@ ...@@ -614,9 +613,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@rolldown/binding-android-arm64": { "node_modules/@rolldown/binding-android-arm64": {
"version": "1.0.2", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.2.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz",
"integrity": "sha512-ZS4D1JPGn/MYQN/SYDWftIE/nVsM8j/AFOYEzAoOE2O3NktQOZru+/vYXGbR/qtdLdIfGCP0lcoJiYVzsEz+iQ==", "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
...@@ -631,9 +630,9 @@ ...@@ -631,9 +630,9 @@
} }
}, },
"node_modules/@rolldown/binding-darwin-arm64": { "node_modules/@rolldown/binding-darwin-arm64": {
"version": "1.0.2", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.2.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz",
"integrity": "sha512-vdFA9+C/rekyGce7WqHs/xoT0ioZEWaOFyZLIV1mEeNFaFDUQrPIo8Vs2GvJ6eetb3rzDUtUBgzto3ExpXJB3w==", "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
...@@ -648,9 +647,9 @@ ...@@ -648,9 +647,9 @@
} }
}, },
"node_modules/@rolldown/binding-darwin-x64": { "node_modules/@rolldown/binding-darwin-x64": {
"version": "1.0.2", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.2.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz",
"integrity": "sha512-BewSOwTHazv77DTYiAZXSqqKZ4KP/KonFisDMVU7PImxoWfB2aepnPhd2E4SWz3zDzYgDNbs6jBmTdgNnF02GA==", "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
...@@ -665,9 +664,9 @@ ...@@ -665,9 +664,9 @@
} }
}, },
"node_modules/@rolldown/binding-freebsd-x64": { "node_modules/@rolldown/binding-freebsd-x64": {
"version": "1.0.2", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.2.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz",
"integrity": "sha512-m41o7M0YWtUdqk61Tb+jnKb2rN++iRdIASlExkUoKfIAH30DOHCB8fVLzSUpbWHHU8esmEioY62PxzexE8MBuA==", "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
...@@ -682,9 +681,9 @@ ...@@ -682,9 +681,9 @@
} }
}, },
"node_modules/@rolldown/binding-linux-arm-gnueabihf": { "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
"version": "1.0.2", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.2.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz",
"integrity": "sha512-jcojB9H7W/jS29pMKWAK1N+fU99vXodHDTatS3b3y/XSOCiHo0kkA74pL3jJmkoQtYpOCxDvaKs1fo2Ij/1X5w==", "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
...@@ -699,9 +698,9 @@ ...@@ -699,9 +698,9 @@
} }
}, },
"node_modules/@rolldown/binding-linux-arm64-gnu": { "node_modules/@rolldown/binding-linux-arm64-gnu": {
"version": "1.0.2", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.2.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz",
"integrity": "sha512-1jn6qDU5iiOgFgygDzKUuKP0maTi0/f1+sBLgvij/76C77Nm3ts6ufz9Bjg5q5dduxiUIxtq86JIoBvo1xQ4Ig==", "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
...@@ -719,9 +718,9 @@ ...@@ -719,9 +718,9 @@
} }
}, },
"node_modules/@rolldown/binding-linux-arm64-musl": { "node_modules/@rolldown/binding-linux-arm64-musl": {
"version": "1.0.2", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.2.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz",
"integrity": "sha512-QVLO/czFMdoMFSqlX3bcswcJNm/23r+qoa/jgtmFc/qEp6/jXmIkDjF/XIo8dPfGaiwy1xfQn8o77L79GeXFgw==", "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
...@@ -739,9 +738,9 @@ ...@@ -739,9 +738,9 @@
} }
}, },
"node_modules/@rolldown/binding-linux-ppc64-gnu": { "node_modules/@rolldown/binding-linux-ppc64-gnu": {
"version": "1.0.2", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.2.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz",
"integrity": "sha512-hgO5Abm0w5UL6FEa2iFnZqo2KlK7TQ5QhV5x09hujBf7t5KzHQ1VmfPuTpqRy/rNlSxua3eWH374xxiVrP+lcA==", "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
...@@ -759,9 +758,9 @@ ...@@ -759,9 +758,9 @@
} }
}, },
"node_modules/@rolldown/binding-linux-s390x-gnu": { "node_modules/@rolldown/binding-linux-s390x-gnu": {
"version": "1.0.2", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.2.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz",
"integrity": "sha512-fy8rXxuYEu602abC8MUNaPjYLIFzReOaEIEMKMUa0rFEUxNpVXhs15KSSQ4qlqSaM7B6rcj9rDZgADh/IGDzLQ==", "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
...@@ -779,9 +778,9 @@ ...@@ -779,9 +778,9 @@
} }
}, },
"node_modules/@rolldown/binding-linux-x64-gnu": { "node_modules/@rolldown/binding-linux-x64-gnu": {
"version": "1.0.2", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.2.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz",
"integrity": "sha512-0+bOkiQ779+r1WpoHOWHqncvyySci0vKph+myNDYb+im6meJAzHQXay6oEgnkHuUGouM1LKTZwqKpBow6Kj7CQ==", "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
...@@ -799,9 +798,9 @@ ...@@ -799,9 +798,9 @@
} }
}, },
"node_modules/@rolldown/binding-linux-x64-musl": { "node_modules/@rolldown/binding-linux-x64-musl": {
"version": "1.0.2", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.2.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz",
"integrity": "sha512-mjSkrzZK5Qsl0a9d1JgILOiuZOSDTVdKENcSXBoqbzSrspLR/4/IRVDo5wd2GgZjNss/viBFJdeq+j7qH2nypw==", "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
...@@ -819,9 +818,9 @@ ...@@ -819,9 +818,9 @@
} }
}, },
"node_modules/@rolldown/binding-openharmony-arm64": { "node_modules/@rolldown/binding-openharmony-arm64": {
"version": "1.0.2", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.2.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz",
"integrity": "sha512-1v5vHasdfQAZoEHakBV72LIFAC9JjnymsiKxp+GEr/ma3+NJCPSaYK+qavInOovJkgwFrs7GccX2d6IgDA3Z5w==", "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
...@@ -836,9 +835,9 @@ ...@@ -836,9 +835,9 @@
} }
}, },
"node_modules/@rolldown/binding-wasm32-wasi": { "node_modules/@rolldown/binding-wasm32-wasi": {
"version": "1.0.2", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.2.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz",
"integrity": "sha512-mb1VobWn6NheziTk5/WEaR6AKVbrwT5sOi6C7zk3gy/pD1qtJfU1j4PgTo2NJnOtbL9Dl3Aeei8w9jJ7qC2jZQ==", "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==",
"cpu": [ "cpu": [
"wasm32" "wasm32"
], ],
...@@ -855,9 +854,9 @@ ...@@ -855,9 +854,9 @@
} }
}, },
"node_modules/@rolldown/binding-win32-arm64-msvc": { "node_modules/@rolldown/binding-win32-arm64-msvc": {
"version": "1.0.2", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.2.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz",
"integrity": "sha512-SqKonF56vA/L2yHwHYcEp2P34URpOZ7d1fS635cTkpDnUtEGdUbhI6NzsPdqeSWvAAeGDrxjWjNmibDIdFf9/A==", "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
...@@ -872,9 +871,9 @@ ...@@ -872,9 +871,9 @@
} }
}, },
"node_modules/@rolldown/binding-win32-x64-msvc": { "node_modules/@rolldown/binding-win32-x64-msvc": {
"version": "1.0.2", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.2.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz",
"integrity": "sha512-v7qRI7gXLRINcOGXt+7YmAZ6iFuyZVMIoXAxhd8oP+DR9dLfL9GfNIx7PLMxmhZdvq8waUJBQiWN9EKNy+TRBQ==", "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
...@@ -920,13 +919,13 @@ ...@@ -920,13 +919,13 @@
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "24.12.4", "version": "24.13.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.4.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.0.tgz",
"integrity": "sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==", "integrity": "sha512-5vtOqGQr4NJKeEzV441FcOi2MeG9UTWq9LqVLGneDdu4vlX17H8kQ2PA2UmNwCUGPVDj4oBjNhS7ReVEIWJJrg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"undici-types": "~7.16.0" "undici-types": "~7.18.0"
} }
}, },
"node_modules/@vitejs/plugin-vue": { "node_modules/@vitejs/plugin-vue": {
...@@ -1029,53 +1028,53 @@ ...@@ -1029,53 +1028,53 @@
} }
}, },
"node_modules/@vue/compiler-core": { "node_modules/@vue/compiler-core": {
"version": "3.5.34", "version": "3.5.35",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.34.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.35.tgz",
"integrity": "sha512-s9cLyK5mLcvZ4Agva5QgRsQyLKvts9WbU9DB6NqiZkkGEdwmcEiylj5Jbwkp680drF/NNCV8OlAJSe+yMLxaJw==", "integrity": "sha512-BUmHaR1J+O+CKZ9uJucdVTEr1LHsdyvv7vG3eNRhK3CczEHeMd/LtsHAuD7PbrxvI2envCY2v7HI1vC1aBRzKw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/parser": "^7.29.3", "@babel/parser": "^7.29.3",
"@vue/shared": "3.5.34", "@vue/shared": "3.5.35",
"entities": "^7.0.1", "entities": "^7.0.1",
"estree-walker": "^2.0.2", "estree-walker": "^2.0.2",
"source-map-js": "^1.2.1" "source-map-js": "^1.2.1"
} }
}, },
"node_modules/@vue/compiler-dom": { "node_modules/@vue/compiler-dom": {
"version": "3.5.34", "version": "3.5.35",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.34.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.35.tgz",
"integrity": "sha512-EbF/T++k0e2MMZlJsBhzK8Sgwt0HcIPOhzn1CTB/lv6sQcyk+OWf8YeiLxZp3ro7MbbLcAfAJ6sEvjFWuNgUCw==", "integrity": "sha512-k+bprkXxuqhVajgTx5mUHuir7TwQzUKOWR40ng1ncAqQRPnrLngGGgqVEEhOnTMlc8btHYVKmrP8s5Qyg0hvYA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/compiler-core": "3.5.34", "@vue/compiler-core": "3.5.35",
"@vue/shared": "3.5.34" "@vue/shared": "3.5.35"
} }
}, },
"node_modules/@vue/compiler-sfc": { "node_modules/@vue/compiler-sfc": {
"version": "3.5.34", "version": "3.5.35",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.34.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.35.tgz",
"integrity": "sha512-D/ihr6uZeIt6r+pVZf46RWT1fAsLFMbUP7k8G1VkiiWexriED9GrX3echHd4Abbt17zjlfiFJ8z7a3BxZOPNjg==", "integrity": "sha512-G5VPMcXTSywXBgtFOZOnHKBxKSrwXUcvY1iaF5/hRcy7t0J6CH/d8ha9F4nzi00Fax1eLV0QHM7v4mQu68jydw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/parser": "^7.29.3", "@babel/parser": "^7.29.3",
"@vue/compiler-core": "3.5.34", "@vue/compiler-core": "3.5.35",
"@vue/compiler-dom": "3.5.34", "@vue/compiler-dom": "3.5.35",
"@vue/compiler-ssr": "3.5.34", "@vue/compiler-ssr": "3.5.35",
"@vue/shared": "3.5.34", "@vue/shared": "3.5.35",
"estree-walker": "^2.0.2", "estree-walker": "^2.0.2",
"magic-string": "^0.30.21", "magic-string": "^0.30.21",
"postcss": "^8.5.14", "postcss": "^8.5.15",
"source-map-js": "^1.2.1" "source-map-js": "^1.2.1"
} }
}, },
"node_modules/@vue/compiler-ssr": { "node_modules/@vue/compiler-ssr": {
"version": "3.5.34", "version": "3.5.35",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.34.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.35.tgz",
"integrity": "sha512-cDtTHKibkThKGHH1SP+WdccquNRYQDFH6rRjQCqT9G2ltFAfoR5pUftpab/z+aM5mW9HLLVQW7hfKKQe/1GBeQ==", "integrity": "sha512-rGhAeXgdM7/ffTJGXT69rCCdTmjDewnFuUZfBQQHTdcEBeWdT5HCGY60y2ytLJr9/Dsu7IntUi5z/w0h6Rjnzw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/compiler-dom": "3.5.34", "@vue/compiler-dom": "3.5.35",
"@vue/shared": "3.5.34" "@vue/shared": "3.5.35"
} }
}, },
"node_modules/@vue/devtools-api": { "node_modules/@vue/devtools-api": {
...@@ -1119,9 +1118,9 @@ ...@@ -1119,9 +1118,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@vue/language-core": { "node_modules/@vue/language-core": {
"version": "3.3.2", "version": "3.3.3",
"resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-3.3.2.tgz", "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-3.3.3.tgz",
"integrity": "sha512-CLwjSfHlPLhjd2qhuS3tTFtnOIWHXAM5u4X1DxmzlQ8j5bmOYlKCsSusOP7jCRJnlVg0mCTQtHU3vwFvopZGoQ==", "integrity": "sha512-X6p+7nfY7vVT6dQwUJ+v0Jfq/lwIfhL2jMi91dQ3ln4hnlGXlxsDu/FNkeyHYgvYtyQy18ZX76IZy7X4diDbiQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
...@@ -1135,53 +1134,53 @@ ...@@ -1135,53 +1134,53 @@
} }
}, },
"node_modules/@vue/reactivity": { "node_modules/@vue/reactivity": {
"version": "3.5.34", "version": "3.5.35",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.34.tgz", "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.35.tgz",
"integrity": "sha512-y9XDjCEuBp+98k+UL5dbYkh57AHU4o6cxZedOPXw3bmrZZYLQsVHguGurq7hVrPCSrQtrnz1f9dssyFr+dMXfQ==", "integrity": "sha512-tVc+SsHConvh/Lz64qq1pP3rYArBmK42xonovEcxY74SQtvctZodG/zhq54P5dr38cVuw25d27cPNRdlMidpGQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/shared": "3.5.34" "@vue/shared": "3.5.35"
} }
}, },
"node_modules/@vue/runtime-core": { "node_modules/@vue/runtime-core": {
"version": "3.5.34", "version": "3.5.35",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.34.tgz", "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.35.tgz",
"integrity": "sha512-mKeBYvu8tcMSLhypAHBmriUFfWXKTCF/23Z4jiCoYK3UtWepkliViNLuR90V9XOyD62mUxs9p1jsrpK3CCGIzw==", "integrity": "sha512-A/xFNX9loIcWDygeQuNCfKuh0CoYBzxhqEMNah5TSFg9Z53DrFYEN2qi5CU9necjM1OWYegYREUTHmXTmhfXtg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/reactivity": "3.5.34", "@vue/reactivity": "3.5.35",
"@vue/shared": "3.5.34" "@vue/shared": "3.5.35"
} }
}, },
"node_modules/@vue/runtime-dom": { "node_modules/@vue/runtime-dom": {
"version": "3.5.34", "version": "3.5.35",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.34.tgz", "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.35.tgz",
"integrity": "sha512-e8kZzERmCwUnBRVsgSQlAfrfU2rGoy0FFKPBXSlfEjc/O3KfA7QP0t1/2ZylrbchjmIKB4dPTd07A6WPr0eOrg==", "integrity": "sha512-odrJ1C391dbGnyDRh8U+rnP7J2amIEzfmRk5vXy7xi3aZhEXofTvpi0T4HJb6jlNqQZTNPR5MPHSB3RHNkIORA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/reactivity": "3.5.34", "@vue/reactivity": "3.5.35",
"@vue/runtime-core": "3.5.34", "@vue/runtime-core": "3.5.35",
"@vue/shared": "3.5.34", "@vue/shared": "3.5.35",
"csstype": "^3.2.3" "csstype": "^3.2.3"
} }
}, },
"node_modules/@vue/server-renderer": { "node_modules/@vue/server-renderer": {
"version": "3.5.34", "version": "3.5.35",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.34.tgz", "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.35.tgz",
"integrity": "sha512-nHxmJoTrKsmrkbILRhkC9gY1G3moZbJTqCzDd7DOOzG5KH9oeJ0Unqrff5f9v0pW//jES05ZkJcNtfE8JjOIew==", "integrity": "sha512-NkebSOYdB97wi8OQcO3HqzZSlymJi/aWsN/7h74OSVhRTm6qGs3Jp3e0rCXynmWwSlKeRrnlIug+ilYoHBmQDA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/compiler-ssr": "3.5.34", "@vue/compiler-ssr": "3.5.35",
"@vue/shared": "3.5.34" "@vue/shared": "3.5.35"
}, },
"peerDependencies": { "peerDependencies": {
"vue": "3.5.34" "vue": "3.5.35"
} }
}, },
"node_modules/@vue/shared": { "node_modules/@vue/shared": {
"version": "3.5.34", "version": "3.5.35",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.34.tgz", "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.35.tgz",
"integrity": "sha512-24uqU4OIiX29ryC3MeWid/Xf2fa2EFRUVLb77nRhk+UrTVrh/XiGtFAFmJBAtBRbjwNdsPRP+jj/OL27Eg1NDA==", "integrity": "sha512-zSbjL7gRXwks2ZQLRGCajBtBXEOXW9Ddhn/HvSdrGkE2dqGnumzW8XtusRrxrE9LvqtiqDXQ+A60Hp6mvdYxfA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@vue/tsconfig": { "node_modules/@vue/tsconfig": {
...@@ -1224,9 +1223,9 @@ ...@@ -1224,9 +1223,9 @@
} }
}, },
"node_modules/ansis": { "node_modules/ansis": {
"version": "4.3.0", "version": "4.3.1",
"resolved": "https://registry.npmjs.org/ansis/-/ansis-4.3.0.tgz", "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.3.1.tgz",
"integrity": "sha512-44mvgtPvohuU/70DdY5Oz2AIrLJ9k6/5x4KmoSvPwO+5Moijo0+N9D0fKbbYZQWP1hNm5CpOf+E01jhxG/r8xg==", "integrity": "sha512-BJ8/l4R5LRE7hW9WdSuGYrLSHi2ynxeFpDFbH0K/CgNeY/tyhk+vO6TYxXC5r5CpUhNVX310xzPsN/H9lCdfOA==",
"dev": true, "dev": true,
"license": "ISC", "license": "ISC",
"engines": { "engines": {
...@@ -1234,9 +1233,9 @@ ...@@ -1234,9 +1233,9 @@
} }
}, },
"node_modules/baseline-browser-mapping": { "node_modules/baseline-browser-mapping": {
"version": "2.10.32", "version": "2.10.33",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.32.tgz", "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.33.tgz",
"integrity": "sha512-wbPvpyjJPC0zdfdKXxqEL3Ea+bOMD/87X4lftiJkkaBiuG6ALQy1SLmEd7BSmVCuwCQsBrCamgBoLyfFDD1EPg==", "integrity": "sha512-bA6+tcSLpz2tIEdDXZPpPTIuxBcC4+w6SieaYyfigIa4h8GlFxbA17v22Vx3JUtuZQj9SgOsnbK+aTBzyDyEuw==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"bin": { "bin": {
...@@ -1455,9 +1454,9 @@ ...@@ -1455,9 +1454,9 @@
} }
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.362", "version": "1.5.368",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.362.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.368.tgz",
"integrity": "sha512-PUY2DrLvkjkUuWqq+KPL2iWshrJsZOcIojzRQ7eXFacc9dWga7MGMJAa15VbiejSZB1PAXaRLAiKgruHP8LB1w==", "integrity": "sha512-7RckJJK4uESJF9PxvfMWd3TGqIiieUTG4HxnKaKuIpGbcr+r2ZEB3g2gAhCP3Fqm42vJSzLfgab9eva/C4/XVw==",
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
...@@ -1587,6 +1586,19 @@ ...@@ -1587,6 +1586,19 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/is-in-ssh": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-in-ssh/-/is-in-ssh-1.0.0.tgz",
"integrity": "sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-inside-container": { "node_modules/is-inside-container": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
...@@ -1999,22 +2011,6 @@ ...@@ -1999,22 +2011,6 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/msgpack": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/msgpack/-/msgpack-1.0.3.tgz",
"integrity": "sha512-FX88+Pexuh+UItdqg68WhNPGPhqs57RlXAYyXNZ8eTQC/Tx5lzeIoxTxA2qAd7qU5a/crON5F0ADf4l6k2b7Jw==",
"hasInstallScript": true,
"dependencies": {
"nan": "^2.14.0"
},
"bin": {
"json2msgpack": "bin/json2msgpack",
"msgpack2json": "bin/msgpack2json"
},
"engines": {
"node": ">=0.12.7"
}
},
"node_modules/muggle-string": { "node_modules/muggle-string": {
"version": "0.4.1", "version": "0.4.1",
"resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz",
...@@ -2022,12 +2018,6 @@ ...@@ -2022,12 +2018,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/nan": {
"version": "2.27.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.27.0.tgz",
"integrity": "sha512-hC+0LidcL3XE4rp1C4H54KujgXKzbfyTngZTwBByQxsOxCEKZT0MPQ4hOKUH2jU1OYstqdDH4onyHPDzcV0XdQ==",
"license": "MIT"
},
"node_modules/nanoid": { "node_modules/nanoid": {
"version": "3.3.12", "version": "3.3.12",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
...@@ -2047,9 +2037,9 @@ ...@@ -2047,9 +2037,9 @@
} }
}, },
"node_modules/node-releases": { "node_modules/node-releases": {
"version": "2.0.46", "version": "2.0.47",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.46.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.47.tgz",
"integrity": "sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==", "integrity": "sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
...@@ -2093,6 +2083,20 @@ ...@@ -2093,6 +2083,20 @@
"npm": ">= 10" "npm": ">= 10"
} }
}, },
"node_modules/obug": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/obug/-/obug-2.1.2.tgz",
"integrity": "sha512-AWGB9WFcRXOQs48Z/udjI5ZcZMHXwX8XPByNpOydgcGsDLIzjGizhoMWJyKAWze7AVW/2W1i+/gPX4YtKe5cyg==",
"dev": true,
"funding": [
"https://github.com/sponsors/sxzz",
"https://opencollective.com/debug"
],
"license": "MIT",
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/ohash": { "node_modules/ohash": {
"version": "2.0.11", "version": "2.0.11",
"resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz",
...@@ -2101,19 +2105,21 @@ ...@@ -2101,19 +2105,21 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/open": { "node_modules/open": {
"version": "10.2.0", "version": "11.0.0",
"resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", "resolved": "https://registry.npmjs.org/open/-/open-11.0.0.tgz",
"integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", "integrity": "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"default-browser": "^5.2.1", "default-browser": "^5.4.0",
"define-lazy-prop": "^3.0.0", "define-lazy-prop": "^3.0.0",
"is-in-ssh": "^1.0.0",
"is-inside-container": "^1.0.0", "is-inside-container": "^1.0.0",
"wsl-utils": "^0.1.0" "powershell-utils": "^0.1.0",
"wsl-utils": "^0.3.0"
}, },
"engines": { "engines": {
"node": ">=18" "node": ">=20"
}, },
"funding": { "funding": {
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
...@@ -2210,6 +2216,19 @@ ...@@ -2210,6 +2216,19 @@
"node": "^10 || ^12 || >=14" "node": "^10 || ^12 || >=14"
} }
}, },
"node_modules/powershell-utils": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/powershell-utils/-/powershell-utils-0.1.0.tgz",
"integrity": "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/read-package-json-fast": { "node_modules/read-package-json-fast": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-4.0.0.tgz", "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-4.0.0.tgz",
...@@ -2225,13 +2244,13 @@ ...@@ -2225,13 +2244,13 @@
} }
}, },
"node_modules/rolldown": { "node_modules/rolldown": {
"version": "1.0.2", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.2.tgz", "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz",
"integrity": "sha512-oZx5zVDtVB44AW3eaifgDml1gWRDZGvjcfdxonE4swNPG98PrrXjaO/KrnUjzlMnztCCRVlUueA1kCXhARGk6g==", "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@oxc-project/types": "=0.132.0", "@oxc-project/types": "=0.133.0",
"@rolldown/pluginutils": "^1.0.0" "@rolldown/pluginutils": "^1.0.0"
}, },
"bin": { "bin": {
...@@ -2241,21 +2260,21 @@ ...@@ -2241,21 +2260,21 @@
"node": "^20.19.0 || >=22.12.0" "node": "^20.19.0 || >=22.12.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"@rolldown/binding-android-arm64": "1.0.2", "@rolldown/binding-android-arm64": "1.0.3",
"@rolldown/binding-darwin-arm64": "1.0.2", "@rolldown/binding-darwin-arm64": "1.0.3",
"@rolldown/binding-darwin-x64": "1.0.2", "@rolldown/binding-darwin-x64": "1.0.3",
"@rolldown/binding-freebsd-x64": "1.0.2", "@rolldown/binding-freebsd-x64": "1.0.3",
"@rolldown/binding-linux-arm-gnueabihf": "1.0.2", "@rolldown/binding-linux-arm-gnueabihf": "1.0.3",
"@rolldown/binding-linux-arm64-gnu": "1.0.2", "@rolldown/binding-linux-arm64-gnu": "1.0.3",
"@rolldown/binding-linux-arm64-musl": "1.0.2", "@rolldown/binding-linux-arm64-musl": "1.0.3",
"@rolldown/binding-linux-ppc64-gnu": "1.0.2", "@rolldown/binding-linux-ppc64-gnu": "1.0.3",
"@rolldown/binding-linux-s390x-gnu": "1.0.2", "@rolldown/binding-linux-s390x-gnu": "1.0.3",
"@rolldown/binding-linux-x64-gnu": "1.0.2", "@rolldown/binding-linux-x64-gnu": "1.0.3",
"@rolldown/binding-linux-x64-musl": "1.0.2", "@rolldown/binding-linux-x64-musl": "1.0.3",
"@rolldown/binding-openharmony-arm64": "1.0.2", "@rolldown/binding-openharmony-arm64": "1.0.3",
"@rolldown/binding-wasm32-wasi": "1.0.2", "@rolldown/binding-wasm32-wasi": "1.0.3",
"@rolldown/binding-win32-arm64-msvc": "1.0.2", "@rolldown/binding-win32-arm64-msvc": "1.0.3",
"@rolldown/binding-win32-x64-msvc": "1.0.2" "@rolldown/binding-win32-x64-msvc": "1.0.3"
} }
}, },
"node_modules/run-applescript": { "node_modules/run-applescript": {
...@@ -2370,9 +2389,9 @@ ...@@ -2370,9 +2389,9 @@
} }
}, },
"node_modules/tinyglobby": { "node_modules/tinyglobby": {
"version": "0.2.16", "version": "0.2.17",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
"integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
...@@ -2419,9 +2438,9 @@ ...@@ -2419,9 +2438,9 @@
} }
}, },
"node_modules/undici-types": { "node_modules/undici-types": {
"version": "7.16.0", "version": "7.18.2",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
...@@ -2474,17 +2493,17 @@ ...@@ -2474,17 +2493,17 @@
} }
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "8.0.14", "version": "8.0.16",
"resolved": "https://registry.npmjs.org/vite/-/vite-8.0.14.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz",
"integrity": "sha512-s4BJJ+5y1pYL6Otw51FHhVJQhPnuRinKig64g/1+EUNaJsd3gCKdD31IPFvswUgW9/60QT9oFHbZHbQK5imcxw==", "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"lightningcss": "^1.32.0", "lightningcss": "^1.32.0",
"picomatch": "^4.0.4", "picomatch": "^4.0.4",
"postcss": "^8.5.15", "postcss": "^8.5.15",
"rolldown": "1.0.2", "rolldown": "1.0.3",
"tinyglobby": "^0.2.16" "tinyglobby": "^0.2.17"
}, },
"bin": { "bin": {
"vite": "bin/vite.js" "vite": "bin/vite.js"
...@@ -2551,56 +2570,62 @@ ...@@ -2551,56 +2570,62 @@
} }
} }
}, },
"node_modules/vite-hot-client": { "node_modules/vite-dev-rpc": {
"version": "2.2.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/vite-hot-client/-/vite-hot-client-2.2.0.tgz", "resolved": "https://registry.npmjs.org/vite-dev-rpc/-/vite-dev-rpc-2.0.0.tgz",
"integrity": "sha512-76Zs9zrHbH7M7wqeyooGQKdX+yg0pQ0xuQ1PbFp4z5a0Lzn2e5IPFoCswnmqZ4GiwqB4Jo3WcDAMO9jARTJl8w==", "integrity": "sha512-yKwbTwdHKSD2k/aGqyWpPHepo45OQc8lH3/6IfT4ZqeKE26ooKvi4WIEKzqWav8v+9Is8u1k8q54hvOmqASazA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": {
"birpc": "^4.0.0",
"vite-hot-client": "^2.2.0"
},
"funding": { "funding": {
"url": "https://github.com/sponsors/antfu" "url": "https://github.com/sponsors/antfu"
}, },
"peerDependencies": { "peerDependencies": {
"vite": "^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 || ^8.0.0" "vite": "^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 || ^7.0.0-0 || ^8.0.0"
} }
}, },
"node_modules/vite-plugin-vue-devtools": { "node_modules/vite-dev-rpc/node_modules/birpc": {
"version": "8.1.2", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-8.1.2.tgz", "resolved": "https://registry.npmjs.org/birpc/-/birpc-4.0.0.tgz",
"integrity": "sha512-gt5h1CNryR9Hy0tvhSbqY3j0F7aj0pGxBxWLa1lXSiZVkhdWDf0vbCOZyjh8ivFGE6FDHTGy3zkcZGlMZdVHig==", "integrity": "sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "funding": {
"@vue/devtools-core": "^8.1.2", "url": "https://github.com/sponsors/antfu"
"@vue/devtools-kit": "^8.1.2", }
"@vue/devtools-shared": "^8.1.2",
"sirv": "^3.0.2",
"vite-plugin-inspect": "^11.3.3",
"vite-plugin-vue-inspector": "^6.0.0"
}, },
"engines": { "node_modules/vite-hot-client": {
"node": ">=v14.21.3" "version": "2.2.0",
"resolved": "https://registry.npmjs.org/vite-hot-client/-/vite-hot-client-2.2.0.tgz",
"integrity": "sha512-76Zs9zrHbH7M7wqeyooGQKdX+yg0pQ0xuQ1PbFp4z5a0Lzn2e5IPFoCswnmqZ4GiwqB4Jo3WcDAMO9jARTJl8w==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/antfu"
}, },
"peerDependencies": { "peerDependencies": {
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0" "vite": "^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 || ^8.0.0"
} }
}, },
"node_modules/vite-plugin-vue-devtools/node_modules/vite-plugin-inspect": { "node_modules/vite-plugin-inspect": {
"version": "11.3.3", "version": "11.4.1",
"resolved": "https://registry.npmjs.org/vite-plugin-inspect/-/vite-plugin-inspect-11.3.3.tgz", "resolved": "https://registry.npmjs.org/vite-plugin-inspect/-/vite-plugin-inspect-11.4.1.tgz",
"integrity": "sha512-u2eV5La99oHoYPHE6UvbwgEqKKOQGz86wMg40CCosP6q8BkB6e5xPneZfYagK4ojPJSj5anHCrnvC20DpwVdRA==", "integrity": "sha512-ShOFe2PURXGvRS5OrgmOLZOCwDTD7dEBVt0tMpFPKb9AsvqXKCRGM8QgKrUbRbJYFXScHvDPpGRd28rYidC0tA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"ansis": "^4.1.0", "ansis": "^4.3.0",
"debug": "^4.4.1",
"error-stack-parser-es": "^1.0.5", "error-stack-parser-es": "^1.0.5",
"obug": "^2.1.1",
"ohash": "^2.0.11", "ohash": "^2.0.11",
"open": "^10.2.0", "open": "^11.0.0",
"perfect-debounce": "^2.0.0", "perfect-debounce": "^2.1.0",
"sirv": "^3.0.1", "sirv": "^3.0.2",
"unplugin-utils": "^0.3.0", "unplugin-utils": "^0.3.1",
"vite-dev-rpc": "^1.1.0" "vite-dev-rpc": "^2.0.0"
}, },
"engines": { "engines": {
"node": ">=14" "node": ">=14"
...@@ -2609,7 +2634,7 @@ ...@@ -2609,7 +2634,7 @@
"url": "https://github.com/sponsors/antfu" "url": "https://github.com/sponsors/antfu"
}, },
"peerDependencies": { "peerDependencies": {
"vite": "^6.0.0 || ^7.0.0-0" "vite": "^6.0.0 || ^7.0.0-0 || ^8.0.0-0"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"@nuxt/kit": { "@nuxt/kit": {
...@@ -2617,21 +2642,25 @@ ...@@ -2617,21 +2642,25 @@
} }
} }
}, },
"node_modules/vite-plugin-vue-devtools/node_modules/vite-plugin-inspect/node_modules/vite-dev-rpc": { "node_modules/vite-plugin-vue-devtools": {
"version": "1.1.0", "version": "8.1.2",
"resolved": "https://registry.npmjs.org/vite-dev-rpc/-/vite-dev-rpc-1.1.0.tgz", "resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-8.1.2.tgz",
"integrity": "sha512-pKXZlgoXGoE8sEKiKJSng4hI1sQ4wi5YT24FCrwrLt6opmkjlqPPVmiPWWJn8M8byMxRGzp1CrFuqQs4M/Z39A==", "integrity": "sha512-gt5h1CNryR9Hy0tvhSbqY3j0F7aj0pGxBxWLa1lXSiZVkhdWDf0vbCOZyjh8ivFGE6FDHTGy3zkcZGlMZdVHig==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"birpc": "^2.4.0", "@vue/devtools-core": "^8.1.2",
"vite-hot-client": "^2.1.0" "@vue/devtools-kit": "^8.1.2",
"@vue/devtools-shared": "^8.1.2",
"sirv": "^3.0.2",
"vite-plugin-inspect": "^11.3.3",
"vite-plugin-vue-inspector": "^6.0.0"
}, },
"funding": { "engines": {
"url": "https://github.com/sponsors/antfu" "node": ">=v14.21.3"
}, },
"peerDependencies": { "peerDependencies": {
"vite": "^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 || ^7.0.0-0" "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
} }
}, },
"node_modules/vite-plugin-vue-inspector": { "node_modules/vite-plugin-vue-inspector": {
...@@ -2663,16 +2692,16 @@ ...@@ -2663,16 +2692,16 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/vue": { "node_modules/vue": {
"version": "3.5.34", "version": "3.5.35",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.34.tgz", "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.35.tgz",
"integrity": "sha512-WdLBG9gm02OgJIG9axd5Hpx0TFLdzVgfG2evFFu8Rur5O/IoGc5cMjnjh3tPL6GnRGsYvUhBSKVPYVcxRKpMCA==", "integrity": "sha512-cx89fnr+0kVGHiNFG6y6s0bdjypJRFNZn6x3WPstNdQR1bi1mbB7h4v5IBGTsPJU3nK1+0Iqj3Zf+hZWMieR4Q==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/compiler-dom": "3.5.34", "@vue/compiler-dom": "3.5.35",
"@vue/compiler-sfc": "3.5.34", "@vue/compiler-sfc": "3.5.35",
"@vue/runtime-dom": "3.5.34", "@vue/runtime-dom": "3.5.35",
"@vue/server-renderer": "3.5.34", "@vue/server-renderer": "3.5.35",
"@vue/shared": "3.5.34" "@vue/shared": "3.5.35"
}, },
"peerDependencies": { "peerDependencies": {
"typescript": "*" "typescript": "*"
...@@ -2699,14 +2728,14 @@ ...@@ -2699,14 +2728,14 @@
} }
}, },
"node_modules/vue-tsc": { "node_modules/vue-tsc": {
"version": "3.3.2", "version": "3.3.3",
"resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-3.3.2.tgz", "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-3.3.3.tgz",
"integrity": "sha512-n7nQoA3YWW/eiDR8jMiv/uJvlg0uLGs+YgUrsTrf9EZaYSt3tuvMZb5V8+7Mvh/EH5pnY/hoVdgfjH+XcK+wwA==", "integrity": "sha512-SWUEG7YRUeDJHT7Xsuhf02elYX2gxPzzAII7OxDAh4KNOr4QHQ0Lls0YfnaO5GNd560CwVa2HTfdqmA5MqvRqQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@volar/typescript": "2.4.28", "@volar/typescript": "2.4.28",
"@vue/language-core": "3.3.2" "@vue/language-core": "3.3.3"
}, },
"bin": { "bin": {
"vue-tsc": "bin/vue-tsc.js" "vue-tsc": "bin/vue-tsc.js"
...@@ -2753,16 +2782,17 @@ ...@@ -2753,16 +2782,17 @@
} }
}, },
"node_modules/wsl-utils": { "node_modules/wsl-utils": {
"version": "0.1.0", "version": "0.3.1",
"resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.3.1.tgz",
"integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", "integrity": "sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"is-wsl": "^3.1.0" "is-wsl": "^3.1.0",
"powershell-utils": "^0.1.0"
}, },
"engines": { "engines": {
"node": ">=18" "node": ">=20"
}, },
"funding": { "funding": {
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
"dependencies": { "dependencies": {
"@msgpack/msgpack": "^3.1.3", "@msgpack/msgpack": "^3.1.3",
"crypto-js": "^4.2.0", "crypto-js": "^4.2.0",
"msgpack": "^1.0.3",
"socket.io-client": "^4.8.3", "socket.io-client": "^4.8.3",
"vue": "^3.5.32", "vue": "^3.5.32",
"vue-router": "^4.6.4" "vue-router": "^4.6.4"
......
...@@ -117,7 +117,8 @@ onBeforeUnmount(() => { ...@@ -117,7 +117,8 @@ onBeforeUnmount(() => {
<template> <template>
<div class="design-stage-viewport" :style="{ background }"> <div class="design-stage-viewport" :style="{ background }">
<div class="design-stage" :style="stageStyle"> <div class="design-stage" :style="stageStyle">
<div v-if="gameCountdownVisible" class="game-countdown">{{ gameCountdown }}</div> <div v-if="gameCountdownVisible" class="game-countdown">
倒计时: &nbsp;{{ gameCountdown }}</div>
<div v-if="countdownVisible" class="countdown-modal"> <div v-if="countdownVisible" class="countdown-modal">
<div :key="countdownKey" class="countdown-number">{{ countdown }}</div> <div :key="countdownKey" class="countdown-number">{{ countdown }}</div>
</div> </div>
...@@ -159,16 +160,14 @@ onBeforeUnmount(() => { ...@@ -159,16 +160,14 @@ onBeforeUnmount(() => {
top: 64px; top: 64px;
right: 80px; right: 80px;
z-index: 10; z-index: 10;
min-width: 220px; width: 300px;
height: 132px; height: 84px;
padding: 0 40px; padding: 0 40px;
border: 6px solid rgba(255, 255, 255, 0.85);
border-radius: 66px;
background: rgba(0, 0, 0, 0.42); background: rgba(0, 0, 0, 0.42);
border: 1px dashed #ccc;
color: #fff; color: #fff;
font-size: 92px; font-size: 42px;
font-weight: 800; line-height: 84px;
line-height: 120px;
text-align: center; text-align: center;
box-shadow: 0 18px 42px rgba(0, 0, 0, 0.25); box-shadow: 0 18px 42px rgba(0, 0, 0, 0.25);
text-shadow: 0 8px 18px rgba(0, 0, 0, 0.4); text-shadow: 0 8px 18px rgba(0, 0, 0, 0.4);
......
...@@ -9,7 +9,22 @@ const imageUrls = { ...@@ -9,7 +9,22 @@ const imageUrls = {
bg1: cssAssetUrl('main-bg1.png'), bg1: cssAssetUrl('main-bg1.png'),
logo: cssAssetUrl('game1/logo.png'), logo: cssAssetUrl('game1/logo.png'),
title1: cssAssetUrl('main-title.png'), title1: cssAssetUrl('main-title.png'),
icon1: cssAssetUrl('icon1.png'),
icon2: cssAssetUrl('icon2.png'),
icon3: cssAssetUrl('icon3.png'),
icon4: cssAssetUrl('icon4.png'),
icon5: cssAssetUrl('icon5.png'),
icon6: cssAssetUrl('icon6.png'),
} }
const iconUrls = [
imageUrls.icon1,
imageUrls.icon2,
imageUrls.icon3,
imageUrls.icon4,
imageUrls.icon5,
imageUrls.icon6,
]
const list = ref(['击鼓齐福', '聚宝接福', const list = ref(['击鼓齐福', '聚宝接福',
'马上有福', '策马迎福', '圈彩纳福', '福运当头' '马上有福', '策马迎福', '圈彩纳福', '福运当头'
...@@ -49,7 +64,7 @@ const loginSuccessHandler = () => { ...@@ -49,7 +64,7 @@ const loginSuccessHandler = () => {
<div v-for="item, index in list" @click="gameHandler(index)"> <div v-for="item, index in list" @click="gameHandler(index)">
<div class="card"> <div class="card">
<div class="img"> <div class="img">
<div></div> <div :style="{ background: `${iconUrls[index]} center / cover no-repeat` }"></div>
</div> </div>
<div class="btn">{{ item }}</div> <div class="btn">{{ item }}</div>
</div> </div>
...@@ -153,13 +168,10 @@ const loginSuccessHandler = () => { ...@@ -153,13 +168,10 @@ const loginSuccessHandler = () => {
transition: transform 0.2s ease 0.1s; transition: transform 0.2s ease 0.1s;
>div { >div {
width: calc(100% - 20px); width: 100%;
height: calc(100% - 20px); height: 100%;
border: 1px solid red;
border-radius: 20px; border-radius: 20px;
position: absolute; position: absolute;
left: 10px;
top: 10px;
} }
} }
......
...@@ -148,7 +148,6 @@ const { startGame, createRoom, backRoom } = useAdminGameSocket({ ...@@ -148,7 +148,6 @@ const { startGame, createRoom, backRoom } = useAdminGameSocket({
onRelogin: async () => { onRelogin: async () => {
$remove_socket_storage(); $remove_socket_storage();
await router.replace('/') await router.replace('/')
debugger
} }
}) })
......
...@@ -141,7 +141,7 @@ function handleRoomState(data: any) { ...@@ -141,7 +141,7 @@ function handleRoomState(data: any) {
switch (data?.status) { switch (data?.status) {
case 0: case 0:
gotoLoading(true); gotoLoading(true);
createRoom(1); createRoom(4);
break; break;
case 1: case 1:
gotoLoading(); gotoLoading();
......
...@@ -121,7 +121,7 @@ function handleRoomState(data: any) { ...@@ -121,7 +121,7 @@ function handleRoomState(data: any) {
switch (data?.status) { switch (data?.status) {
case 0: case 0:
gotoLoading(true) gotoLoading(true)
createRoom(1) createRoom(6)
break break
case 1: case 1:
gotoLoading() gotoLoading()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment