Sửa lỗi trực tiếp trên window

This commit is contained in:
2026-08-11 09:51:13 +07:00
parent aae0b05473
commit f8cb2c6a5e
16 changed files with 10409 additions and 1820 deletions
+20 -3
View File
@@ -573,7 +573,7 @@ def _carla_osc_ready() -> bool:
import socket import socket
port = _carla_osc_port() port = _carla_osc_port()
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("127.0.0.1", port)) s.bind(("0.0.0.0", port))
s.close() s.close()
return False return False
except OSError: except OSError:
@@ -749,12 +749,20 @@ async def carla_stop(authorization: Optional[str] = Header(None)):
_send_carla_all_notes_off() _send_carla_all_notes_off()
except Exception: except Exception:
pass pass
# 2. Terminate tiến trình Carla đã spawn # 2. Terminate tiến trình Carla đã spawn — Windows PHẢI giết cả process
# tree (Carla.exe spawn carla-backend child giữ cổng OSC 22752; terminate
# đơn lẻ chỉ giết cha → child sống → cổng chưa giải phóng → lần mở sau
# open_in_carla thấy already_running dù Carla đã chết → GUI không xuất
# hiện lại (Bug 3 standalone)).
killed = 0 killed = 0
_prune_carla_processes() _prune_carla_processes()
for proc in list(_CARLA_PROCESSES): for proc in list(_CARLA_PROCESSES):
try: try:
proc.terminate() if os.name == "nt" and proc.pid:
subprocess.run(["taskkill", "/PID", str(proc.pid), "/T", "/F"],
capture_output=True, timeout=15)
else:
proc.terminate()
except Exception: except Exception:
pass pass
# Chờ tiến trình thoát (tối đa ~2s) rồi kill mạnh nếu còn sống # Chờ tiến trình thoát (tối đa ~2s) rồi kill mạnh nếu còn sống
@@ -774,6 +782,15 @@ async def carla_stop(authorization: Optional[str] = Header(None)):
except Exception: except Exception:
pass pass
_CARLA_PROCESSES.clear() _CARLA_PROCESSES.clear()
# 3. Chờ cổng OSC UDP thực sự được giải phóng (child có thể thoát chậm
# hơn cha) — nếu không, mở lại Carla ngay sẽ bị gate already_running.
try:
import time as _t
deadline = _t.time() + 5.0
while _t.time() < deadline and _carla_osc_ready():
_t.sleep(0.1)
except Exception:
pass
return { return {
"success": True, "success": True,
"stopped": True, "stopped": True,
+106 -5
View File
@@ -205,6 +205,37 @@ const shouldRouteCarla = (se) => !!(window.SonicCarlaMidi && window.SonicCarlaMi
// Mi key (thưng = track.id) mt Audio element note mi stop note cũ; // Mi key (thưng = track.id) mt Audio element note mi stop note cũ;
// token chng stale (response cũ không đè response mi). // token chng stale (response cũ không đè response mi).
const _nativeSfPreviews = {}; const _nativeSfPreviews = {};
// WASM fallback: backend pyfluidsynth render HONG tren ban standalone
// (thieu libfluidsynth DLL) -> /soundfont-render 501 -> apiRequest throw ->
// native path cam lang. Fallback choi note TRUC TIEP qua SonicSF (Web Audio
// + libfluidsynth WASM da bundle) - am ra _gainNode -> masterBus.input.
// window.__nativeSfOk: undefined (chua biet) | true (native OK) | false (dung WASM).
const _sfWasmFallbackNote = (track, pitch, velocity, durationMs, startTime, key, token) => {
try {
const eng = track && track.synth_engine;
const sfId = (eng && eng.soundfont_id) || (track && track.instrumentId && String(track.instrumentId).startsWith('sf_') ? track.instrumentId : null);
if (!sfId) return;
const bank = (eng && eng.soundfont_bank) || 0;
const program = (eng && eng.soundfont_program) || (track && track.instrumentProgram !== undefined ? track.instrumentProgram : 0);
const k = key || (track ? track.id : 'global');
if (_nativeSfPreviews[k] && token != null && _nativeSfPreviews[k].token !== token) return; // stale
const S = window.SonicSF;
if (!S) return;
const ch = (track && track.midiChannel != null) ? track.midiChannel : 0;
const durMs = Math.max(200, durationMs || 500);
const ctx = getAudioContext();
const delaySec = startTime ? Math.max(0, (startTime - ctx.currentTime)) : 0;
_nativeSfPreviews[k] = { wasm: { ch: ch, pitch: pitch }, token: token };
const fire = function () {
Promise.resolve(S.selectInstrument(ch, bank, program, sfId)).then(function () {
S.playNote(pitch, velocity != null ? velocity : 0.8, durMs, undefined, eng ? undefined : program, null, ch, eng || undefined);
}).catch(function () {
try { S.playNote(pitch, velocity != null ? velocity : 0.8, durMs, undefined, eng ? undefined : program, null, ch, eng || undefined); } catch (e2) {}
});
};
if (delaySec > 0) { setTimeout(fire, delaySec * 1000); } else { fire(); }
} catch (e) { console.warn('[NativeSF] wasm fallback note error:', e); }
};
const playNativeSfNote = (track, pitch, velocity, durationMs, startTime, key) => { const playNativeSfNote = (track, pitch, velocity, durationMs, startTime, key) => {
try { try {
const eng = track && track.synth_engine; const eng = track && track.synth_engine;
@@ -215,6 +246,11 @@ const playNativeSfNote = (track, pitch, velocity, durationMs, startTime, key) =>
const k = key || (track ? track.id : 'global'); const k = key || (track ? track.id : 'global');
const prev = _nativeSfPreviews[k]; const prev = _nativeSfPreviews[k];
const token = (prev ? prev.token : 0) + 1; const token = (prev ? prev.token : 0) + 1;
// Native hong da biet (501) -> di thang WASM fallback, khong goi API.
if (window.__nativeSfOk === false) {
_sfWasmFallbackNote(track, pitch, velocity, durationMs, startTime, k, token);
return;
}
const durationSec = Math.max(0.2, (durationMs || 500) / 1000); const durationSec = Math.max(0.2, (durationMs || 500) / 1000);
window.SonicAPI.soundfontRender({ window.SonicAPI.soundfontRender({
soundfont_id: sfId, soundfont_id: sfId,
@@ -223,8 +259,13 @@ const playNativeSfNote = (track, pitch, velocity, durationMs, startTime, key) =>
bpm: 120, bpm: 120,
notes: [{ pitch: pitch, start_beat: 0, duration_beats: durationSec * 2, velocity: velocity != null ? velocity : 0.8 }], notes: [{ pitch: pitch, start_beat: 0, duration_beats: durationSec * 2, velocity: velocity != null ? velocity : 0.8 }],
}).then(function (res) { }).then(function (res) {
if (!res || !res.success || !res.url) return; if (!res || !res.success || !res.url) {
window.__nativeSfOk = false;
_sfWasmFallbackNote(track, pitch, velocity, durationMs, startTime, k, token);
return;
}
if (_nativeSfPreviews[k] && _nativeSfPreviews[k].token !== token) return; // stale if (_nativeSfPreviews[k] && _nativeSfPreviews[k].token !== token) return; // stale
window.__nativeSfOk = true;
const audio = new Audio(API_BASE_URL + res.url); const audio = new Audio(API_BASE_URL + res.url);
_nativeSfPreviews[k] = { audio: audio, token: token }; _nativeSfPreviews[k] = { audio: audio, token: token };
const ctx = getAudioContext(); const ctx = getAudioContext();
@@ -235,7 +276,10 @@ const playNativeSfNote = (track, pitch, velocity, durationMs, startTime, key) =>
audio._sfStopTimer && clearTimeout(audio._sfStopTimer); audio._sfStopTimer && clearTimeout(audio._sfStopTimer);
audio._sfStopTimer = setTimeout(function () { try { audio.pause(); } catch (e) {} }, durationSec * 1000 + 400); audio._sfStopTimer = setTimeout(function () { try { audio.pause(); } catch (e) {} }, durationSec * 1000 + 400);
}, delay); }, delay);
}).catch(function () {}); }).catch(function () {
window.__nativeSfOk = false;
_sfWasmFallbackNote(track, pitch, velocity, durationMs, startTime, k, token);
});
} catch (e) { console.warn('[NativeSF] playNativeSfNote error:', e); } } catch (e) { console.warn('[NativeSF] playNativeSfNote error:', e); }
}; };
const stopNativeSfNote = (key) => { const stopNativeSfNote = (key) => {
@@ -245,6 +289,7 @@ const stopNativeSfNote = (key) => {
if (!prev) return; if (!prev) return;
prev.token++; prev.token++;
try { if (prev.audio) { prev.audio.pause(); prev.audio.currentTime = 0; } } catch (e) {} try { if (prev.audio) { prev.audio.pause(); prev.audio.currentTime = 0; } } catch (e) {}
try { if (prev.wasm && window.SonicSF) window.SonicSF.stopNote(prev.wasm.ch, prev.wasm.pitch); } catch (e) {}
} catch (e) {} } catch (e) {}
}; };
const stopAllNativeSfNotes = () => { const stopAllNativeSfNotes = () => {
@@ -263,6 +308,10 @@ const scheduleNativeSfItem = (track, item, offsetTime, context, destNode, bpm, o
if (!sfId) return; if (!sfId) return;
const notes = (item && item.notes) || []; const notes = (item && item.notes) || [];
if (!notes.length) return; if (!notes.length) return;
if (window.__nativeSfOk === false) {
scheduleNativeSfItemWasm(track, item, offsetTime, context, destNode, bpm, opts);
return;
}
const secPerBeat = 60.0 / (parseInt(bpm) || 120); const secPerBeat = 60.0 / (parseInt(bpm) || 120);
const baseOffsetSec = (opts && opts.baseOffsetSec) || 0; const baseOffsetSec = (opts && opts.baseOffsetSec) || 0;
const itemStartAbs = baseOffsetSec + (item.startTime || 0); const itemStartAbs = baseOffsetSec + (item.startTime || 0);
@@ -278,7 +327,12 @@ const scheduleNativeSfItem = (track, item, offsetTime, context, destNode, bpm, o
bpm: parseFloat(bpm) || 120, bpm: parseFloat(bpm) || 120,
notes: notes.map(function (n) { return { pitch: n.pitch || 60, start_beat: n.start_beat || 0, duration_beats: n.duration_beats || 1, velocity: n.velocity != null ? n.velocity : 0.8 }; }), notes: notes.map(function (n) { return { pitch: n.pitch || 60, start_beat: n.start_beat || 0, duration_beats: n.duration_beats || 1, velocity: n.velocity != null ? n.velocity : 0.8 }; }),
}).then(function (res) { }).then(function (res) {
if (!res || !res.success || !res.url) return; if (!res || !res.success || !res.url) {
window.__nativeSfOk = false;
scheduleNativeSfItemWasm(track, item, offsetTime, context, destNode, bpm, opts);
return;
}
window.__nativeSfOk = true;
fetch(API_BASE_URL + res.url).then(function (r) { return r.arrayBuffer(); }).then(function (buf) { fetch(API_BASE_URL + res.url).then(function (r) { return r.arrayBuffer(); }).then(function (buf) {
context.decodeAudioData(buf, function (audioBuf) { context.decodeAudioData(buf, function (audioBuf) {
try { try {
@@ -299,11 +353,58 @@ const scheduleNativeSfItem = (track, item, offsetTime, context, destNode, bpm, o
if (opts && opts.sources && opts.sources.push) opts.sources.push(src); if (opts && opts.sources && opts.sources.push) opts.sources.push(src);
} catch (e) { console.warn('[NativeSF] schedule decode error:', e); } } catch (e) { console.warn('[NativeSF] schedule decode error:', e); }
}, function () {}); }, function () {});
}).catch(function () {}); }).catch(function () {
}).catch(function () {}); window.__nativeSfOk = false;
scheduleNativeSfItemWasm(track, item, offsetTime, context, destNode, bpm, opts);
});
}).catch(function () {
window.__nativeSfOk = false;
scheduleNativeSfItemWasm(track, item, offsetTime, context, destNode, bpm, opts);
});
} catch (e) { console.warn('[NativeSF] scheduleNativeSfItem error:', e); } } catch (e) { console.warn('[NativeSF] scheduleNativeSfItem error:', e); }
}; };
// WASM fallback cho item (backend 501): schedule TUNG NOTE qua SonicSF
// (Web Audio) dung vi tri thoi gian - thay vi render 1 file WAV ca item.
const scheduleNativeSfItemWasm = (track, item, offsetTime, context, destNode, bpm, opts) => {
try {
const eng = track && track.synth_engine;
const sfId = eng && eng.soundfont_id;
if (!sfId) return;
const notes = (item && item.notes) || [];
if (!notes.length) return;
const S = window.SonicSF;
if (!S) return;
const secPerBeat = 60.0 / (parseInt(bpm) || 120);
const baseOffsetSec = (opts && opts.baseOffsetSec) || 0;
const itemStartAbs = baseOffsetSec + (item.startTime || 0);
const now = context.currentTime;
const ch = (track && track.midiChannel != null) ? track.midiChannel : 0;
const bank = (eng && eng.soundfont_bank) || 0;
const program = (eng && eng.soundfont_program) || 0;
const fire = function () {
if (opts && typeof opts.isActive === 'function' && !opts.isActive()) return;
notes.forEach(function (n) {
try {
const noteStartSec = itemStartAbs + (n.start_beat || 0) * secPerBeat;
const noteDurSec = (n.duration_beats || 1) * secPerBeat;
const clipStart = Math.max(offsetTime, noteStartSec);
var durMs = (noteStartSec + noteDurSec - clipStart) * 1000;
if (opts && opts.limitSec) {
const limitMs = (opts.limitSec - clipStart) * 1000;
if (limitMs <= 0) return;
durMs = Math.min(durMs, limitMs);
}
if (durMs <= 0) return;
const startWall = now + Math.max(0, noteStartSec - offsetTime);
S.playNote(n.pitch || 60, n.velocity != null ? n.velocity : 0.8, durMs, startWall, undefined, destNode || null, ch, eng);
} catch (e) {}
});
};
Promise.resolve(S.selectInstrument(ch, bank, program, sfId)).then(fire).catch(fire);
} catch (e) { console.warn('[NativeSF] scheduleNativeSfItemWasm error:', e); }
};
// Handle ?sfs=<encoded> from double-clicking a .sfs file (opens domain -> loads project) // Handle ?sfs=<encoded> from double-clicking a .sfs file (opens domain -> loads project)
(function handleSfsDeepLink() { (function handleSfsDeepLink() {
try { try {
File diff suppressed because one or more lines are too long
+6
View File
@@ -120,6 +120,12 @@ window.SonicCarlaMidi = window.SonicCarlaMidi || {
stopBridge: function () { stopBridge: function () {
var self = this; var self = this;
try { self.allNotesOff(); } catch (e) {} try { self.allNotesOff(); } catch (e) {}
// Reset trạng thái Carla bridge — nếu không, sau unload các cờ stale
// (__carlaRunning=true) khiến ensureCarlaForPlayback early-return và
// GUI Carla KHÔNG mở lại được khi reload.
window.__carlaRunning = false;
window.__carlaOpening = false;
window.__carlaNoteQueue = [];
if (window.SonicAPI && window.SonicAPI.stopCarla) { if (window.SonicAPI && window.SonicAPI.stopCarla) {
return window.SonicAPI.stopCarla().catch(function () {}); return window.SonicAPI.stopCarla().catch(function () {});
} }
+239 -4
View File
@@ -13,6 +13,9 @@
"jsdom": "^30.0.1", "jsdom": "^30.0.1",
"react": "^19.2.8", "react": "^19.2.8",
"react-dom": "^19.2.8" "react-dom": "^19.2.8"
},
"devDependencies": {
"@tauri-apps/cli": "^2.11.4"
} }
}, },
"node_modules/@asamuzakjp/css-color": { "node_modules/@asamuzakjp/css-color": {
@@ -608,6 +611,238 @@
"@jridgewell/sourcemap-codec": "^1.4.14" "@jridgewell/sourcemap-codec": "^1.4.14"
} }
}, },
"node_modules/@tauri-apps/cli": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.11.4.tgz",
"integrity": "sha512-R8xGtMpwyetawSqm9kYOuMmEqkhUbvcUy8n0aNXIxollKBLESUu5f4Fx+64hgASYm1H+jSWq6jCW6zqTnH6hqQ==",
"dev": true,
"license": "Apache-2.0 OR MIT",
"bin": {
"tauri": "tauri.js"
},
"engines": {
"node": ">= 10"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/tauri"
},
"optionalDependencies": {
"@tauri-apps/cli-darwin-arm64": "2.11.4",
"@tauri-apps/cli-darwin-x64": "2.11.4",
"@tauri-apps/cli-linux-arm-gnueabihf": "2.11.4",
"@tauri-apps/cli-linux-arm64-gnu": "2.11.4",
"@tauri-apps/cli-linux-arm64-musl": "2.11.4",
"@tauri-apps/cli-linux-riscv64-gnu": "2.11.4",
"@tauri-apps/cli-linux-x64-gnu": "2.11.4",
"@tauri-apps/cli-linux-x64-musl": "2.11.4",
"@tauri-apps/cli-win32-arm64-msvc": "2.11.4",
"@tauri-apps/cli-win32-ia32-msvc": "2.11.4",
"@tauri-apps/cli-win32-x64-msvc": "2.11.4"
}
},
"node_modules/@tauri-apps/cli-darwin-arm64": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.11.4.tgz",
"integrity": "sha512-1ryOF3ZhpZ/nemHV5zVwBQBz9jDGKmKPvWPADOhc83ig0P4bMc2iER4NbC6r9sjeIZ6RVQ4g3RZIYvezhcl4TQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-darwin-x64": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.11.4.tgz",
"integrity": "sha512-uFsGQAAfuyz1k/yGLmkWfkBlgKAqZfxqlHmLWx81QU27RJWfmbNHCIq8T8w1e+VClleIuZUjpHWfoE4E3DLo3A==",
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.11.4.tgz",
"integrity": "sha512-IaHZn5CdBL21oUmjiVOS1ctw6Ip1O0pjp70FwOWmYz1myWe0SY96ZIj2FYf7pT0m8bI2h/hrs5ZbEXXh44/MkQ==",
"cpu": [
"arm"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-arm64-gnu": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.11.4.tgz",
"integrity": "sha512-N41/ukTRVe6XSuUTESuFdGeOW2i7k62tK+6gHK5Kd5/q5RPvvi19GaWAVPPb9u95HSGmTChSolBfzynUsssFaA==",
"cpu": [
"arm64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-arm64-musl": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.11.4.tgz",
"integrity": "sha512-v277UnT/fB64xAfSroL5N3Km3tLmvATWqJJw/wRI+g6o+HkeD0slyE7gOhNs1MbjE41R7bQOTxMVoL3aomUJmw==",
"cpu": [
"arm64"
],
"dev": true,
"libc": [
"musl"
],
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-riscv64-gnu": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.11.4.tgz",
"integrity": "sha512-qqgNkQ2u1yZHxjhxsZaxUtRDW8dIqIYm33rx/mzwQv0SfY9x1B+iraj8vWeFiXjjSVVhEMepXSOts1TqPzvXNQ==",
"cpu": [
"riscv64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-x64-gnu": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.11.4.tgz",
"integrity": "sha512-2VRNWl84FOH0m2giiDkO2h0QXlcMJeX+zJDpI5kDIQAx6s+geF3v48F4DXfJez4GS/FdoDGnPnw1C2iYGbQ7bQ==",
"cpu": [
"x64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-x64-musl": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.11.4.tgz",
"integrity": "sha512-o9GyhYor/nc7xarmwDE3ka2szuW3uuZzXjHWh64Q8YX5AtSgxdQkFWzrY4O8KiGtVNvFBI14H3Q49Qj5TOIP/A==",
"cpu": [
"x64"
],
"dev": true,
"libc": [
"musl"
],
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-win32-arm64-msvc": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.11.4.tgz",
"integrity": "sha512-ld5Ehb598m0VkYyylRPNeCFsBe/km0jxis6KgMpl3IGY6I/i1RwQXO05I1AsXUXO2WC6AvB/Lw4qTf/asiuEiQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-win32-ia32-msvc": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.11.4.tgz",
"integrity": "sha512-12Hxi0XX/H5VFxO/bGgHkFWhml9VMgEOu9CidjeCeTNQ1l6fpUlbiGgSP7CLI3PFtW9/FfbeHieZ+kyWK5H7CA==",
"cpu": [
"ia32"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-win32-x64-msvc": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.11.4.tgz",
"integrity": "sha512-+vDiqBIU5dMISg/wNvX3sF+ZHfgJGJ5T0AcO+EHNXV9GGAG+P5fzodlDXD3QdKCRgZxMoCm5PPvj3BqLNjBthw==",
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@types/gensync": { "node_modules/@types/gensync": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/@types/gensync/-/gensync-1.0.5.tgz", "resolved": "https://registry.npmjs.org/@types/gensync/-/gensync-1.0.5.tgz",
@@ -651,15 +886,15 @@
} }
}, },
"node_modules/brace-expansion": { "node_modules/brace-expansion": {
"version": "5.0.7", "version": "5.0.9",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz",
"integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"balanced-match": "^4.0.2" "balanced-match": "^4.0.2"
}, },
"engines": { "engines": {
"node": "18 || 20 || >=22" "node": "20 || >=22"
} }
}, },
"node_modules/browserslist": { "node_modules/browserslist": {
+3
View File
@@ -12,5 +12,8 @@
"jsdom": "^30.0.1", "jsdom": "^30.0.1",
"react": "^19.2.8", "react": "^19.2.8",
"react-dom": "^19.2.8" "react-dom": "^19.2.8"
},
"devDependencies": {
"@tauri-apps/cli": "^2.11.4"
} }
} }
+4675
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
{"default":{"identifier":"default","description":"Default capability for the main window","local":true,"windows":["main"],"permissions":["core:default","dialog:default"]}}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1 +0,0 @@
PLACEHOLDER - duoc thay boi build_windows.ps1 buoc [4/6] (copy dist\daw_engine)
+1
View File
@@ -0,0 +1 @@
00124e36b2edc6353e9a29c81762747294306d6b3cfeb46e365ff049ea60369e
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
8d8cb8360a19f87760d88df0f6702a6242238d3e51388341646346ad9683cffa
Binary file not shown.