From 0d8dab3564c31b61cce0b83c3b4ded8096332e01 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Mon, 24 Jul 2023 20:55:43 +0900 Subject: [PATCH] [feat] apply yuso --- package.json | 3 +- pnpm-lock.yaml | 7 ++ src/ts/characterCards.ts | 90 +++++-------------- src/ts/characters.ts | 9 +- src/ts/exif.ts | 57 ------------ ....timestamp-1690197732653-922a2adc95a59.mjs | 70 +++++++++++++++ 6 files changed, 103 insertions(+), 133 deletions(-) delete mode 100644 src/ts/exif.ts create mode 100644 vite.config.ts.timestamp-1690197732653-922a2adc95a59.mjs diff --git a/package.json b/package.json index 30e97736..75909193 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,8 @@ "tippy.js": "^6.3.7", "uuid": "^9.0.0", "wasmoon": "^1.15.0", - "web-streams-polyfill": "^3.2.1" + "web-streams-polyfill": "^3.2.1", + "yuso": "^0.1.1" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^2.4.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6dd37b42..fe01cabf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -119,6 +119,9 @@ dependencies: web-streams-polyfill: specifier: ^3.2.1 version: 3.2.1 + yuso: + specifier: ^0.1.1 + version: 0.1.1 devDependencies: '@sveltejs/vite-plugin-svelte': @@ -3091,3 +3094,7 @@ packages: resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==} engines: {node: '>= 14'} dev: true + + /yuso@0.1.1: + resolution: {integrity: sha512-GAPk64cRjlnIgDcMkpgRpydJqJcD41aLF5taY7AXm7JRcmSBaHMubFtgSsPf0oDtbDH5j/FIeVJyDtGFwXXv2Q==} + dev: false diff --git a/src/ts/characterCards.ts b/src/ts/characterCards.ts index 393f95b7..cf575e71 100644 --- a/src/ts/characterCards.ts +++ b/src/ts/characterCards.ts @@ -1,17 +1,15 @@ import { get, writable, type Writable } from "svelte/store" import { alertConfirm, alertError, alertMd, alertNormal, alertSelect, alertStore, alertTOS } from "./alert" import { DataBase, defaultSdDataFunc, type character, setDatabase, type customscript, type loreSettings, type loreBook } from "./storage/database" -import { checkNullish, selectMultipleFile, selectSingleFile, sleep } from "./util" +import { checkNullish, selectMultipleFile, sleep } from "./util" import { language } from "src/lang" -import { encode as encodeMsgpack, decode as decodeMsgpack } from "msgpackr"; import { v4 as uuidv4 } from 'uuid'; -import exifr from 'exifr' -import { PngMetadata } from "./exif" import { characterFormatUpdate } from "./characters" import { checkCharOrder, downloadFile, readImage, saveAsset } from "./storage/globalApi" import { cloneDeep } from "lodash" import { selectedCharID } from "./stores" import { convertImage } from "./parser" +import * as yuso from 'yuso' export const hubURL = "https://sv.risuai.xyz" @@ -60,69 +58,22 @@ async function importCharacterProcess(f:{ }) await sleep(10) const img = f.data - const readed = (await exifr.parse(img, true)) - if(readed.chara){ - // standard spec v2 imports - const charaData:CharacterCardV2 = JSON.parse(Buffer.from(readed.chara, 'base64').toString('utf-8')) + + const readed = yuso.decode(img, 'chara') + { + const charaData:CharacterCardV2 = JSON.parse(Buffer.from(readed, 'base64').toString('utf-8')) if(await importSpecv2(charaData, img)){ let db = get(DataBase) return db.characters.length - 1 } } - if(readed.risuai){ - // old risu imports - await sleep(10) - const va = decodeMsgpack(Buffer.from(readed.risuai, 'base64')) as any - if(va.type !== 101){ - alertError(language.errors.noData) - return - } - - let char:character = va.data - let db = get(DataBase) - if(char.emotionImages && char.emotionImages.length > 0){ - for(let i=0;i = writable(null) @@ -170,18 +121,18 @@ export async function characterURLImport() { }) const img = new Uint8Array(await chara.arrayBuffer()) - const readed = (await exifr.parse(img, true)) + const readed = (yuso.decode(img, "chara")) { - const charaData:CharacterCardV2 = JSON.parse(Buffer.from(readed.chara, 'base64').toString('utf-8')) + const charaData:CharacterCardV2 = JSON.parse(Buffer.from(readed, 'base64').toString('utf-8')) if(await importSpecv2(charaData, img)){ checkCharOrder() return } } { - const imgp = await saveAsset(PngMetadata.filter(img)) + const imgp = await saveAsset(yuso.trim(img)) let db = get(DataBase) - const charaData:OldTavernChar = JSON.parse(Buffer.from(readed.chara, 'base64').toString('utf-8')) + const charaData:OldTavernChar = JSON.parse(Buffer.from(readed, 'base64').toString('utf-8')) db.characters.push(convertOldTavernAndJSON(charaData, imgp)) DataBase.set(db) @@ -268,7 +219,7 @@ async function importSpecv2(card:CharacterCardV2, img?:Uint8Array, mode?:'hub'|' } const data = card.data - const im = img ? await saveAsset(PngMetadata.filter(img)) : undefined + const im = img ? await saveAsset(yuso.trim(img)) : undefined let db = get(DataBase) const risuext = cloneDeep(data.extensions.risuai) @@ -517,9 +468,8 @@ export async function exportSpecV2(char:character, type:'png'|'json' = 'png') { }) await sleep(10) - img = PngMetadata.write(img, { - 'chara': Buffer.from(JSON.stringify(card)).toString('base64'), - }) + + img = yuso.encode(img, "chara",Buffer.from(JSON.stringify(card)).toString('base64')) alertStore.set({ type: 'wait', diff --git a/src/ts/characters.ts b/src/ts/characters.ts index 67cfd0e3..500684d7 100644 --- a/src/ts/characters.ts +++ b/src/ts/characters.ts @@ -1,14 +1,13 @@ import { get, writable } from "svelte/store"; import { DataBase, saveImage, setDatabase, type character, type Chat, defaultSdDataFunc } from "./storage/database"; -import exifr from 'exifr' import { alertConfirm, alertError, alertNormal, alertSelect, alertStore } from "./alert"; import { language } from "../lang"; -import { PngMetadata } from "./exif"; import { encode as encodeMsgpack, decode as decodeMsgpack } from "msgpackr"; import { checkNullish, findCharacterbyId, selectMultipleFile, selectSingleFile, sleep } from "./util"; import { v4 as uuidv4 } from 'uuid'; import { selectedCharID } from "./stores"; import { checkCharOrder, downloadFile, getFileSrc, readImage } from "./storage/globalApi"; +import * as yuso from 'yuso' export function createNewCharacter() { let db = get(DataBase) @@ -493,9 +492,9 @@ export async function addDefaultCharacters() { for(const img of imgs){ const imgBuffer = await (await img).arrayBuffer() - const readed = (await exifr.parse(imgBuffer, true)) + const readed = yuso.decode(Buffer.from(imgBuffer), "risuai") await sleep(10) - const va = decodeMsgpack(Buffer.from(readed.risuai, 'base64')) as any + const va = decodeMsgpack(Buffer.from(readed,'base64')) as any if(va.type !== 101){ alertError(language.errors.noData) return @@ -521,7 +520,7 @@ export async function addDefaultCharacters() { } char.chatPage = 0 - char.image = await saveImage(PngMetadata.filter(Buffer.from(imgBuffer))) + char.image = await saveImage(yuso.trim(Buffer.from(imgBuffer))) char.chaId = uuidv4() db.characters.push(characterFormatUpdate(char)) setDatabase(db) diff --git a/src/ts/exif.ts b/src/ts/exif.ts deleted file mode 100644 index a557fbad..00000000 --- a/src/ts/exif.ts +++ /dev/null @@ -1,57 +0,0 @@ -import extract from 'png-chunks-extract'; -import encode from 'png-chunks-encode'; -import textKey from 'png-chunk-text' - -export const PngMetadata = { - write: (pngBuffer: Uint8Array, metadata: Record): Buffer => { - let chunks:{ - name:string - data:Uint8Array - }[] = extract(Buffer.from(pngBuffer)); - - chunks = chunks.filter((v) => { - return v.name.toLocaleLowerCase() !== 'text' - }) - - for (const key in metadata) { - const value = metadata[key]; - chunks.splice(-1, 0, textKey.encode(key, value)) - } - const encoded = encode(chunks); - return encoded - }, - writeStream:(pngBuffer: Uint8Array, metadata: Record): Buffer => { - let chunks:{ - name:string - data:Uint8Array - }[] = extract(Buffer.from(pngBuffer)); - - chunks = chunks.filter((v) => { - return v.name.toLocaleLowerCase() !== 'text' - }) - - for (const key in metadata) { - const value = metadata[key]; - chunks.splice(-1, 0, textKey.encode(key, value)) - } - const encoded = encode(chunks); - return encoded - }, - filter: (pngBuffer: Uint8Array) => { - try { - let chunks:{ - name:string - data:Uint8Array - }[] = extract(Buffer.from(pngBuffer)); - - chunks = chunks.filter((v) => { - return v.name.toLocaleLowerCase() !== 'text' - }) - - const encoded = encode(chunks); - return encoded - } catch (error) { - return pngBuffer - } - } -} \ No newline at end of file diff --git a/vite.config.ts.timestamp-1690197732653-922a2adc95a59.mjs b/vite.config.ts.timestamp-1690197732653-922a2adc95a59.mjs new file mode 100644 index 00000000..f7bbf13a --- /dev/null +++ b/vite.config.ts.timestamp-1690197732653-922a2adc95a59.mjs @@ -0,0 +1,70 @@ +// vite.config.ts +import { defineConfig } from "file:///C:/Users/blueb/OneDrive/Documents/VSC/_Risu/kakuna/RisuAI/node_modules/.pnpm/vite@4.4.5_@types+node@18.16.19/node_modules/vite/dist/node/index.js"; +import { svelte } from "file:///C:/Users/blueb/OneDrive/Documents/VSC/_Risu/kakuna/RisuAI/node_modules/.pnpm/@sveltejs+vite-plugin-svelte@2.4.2_svelte@4.1.0_vite@4.4.5/node_modules/@sveltejs/vite-plugin-svelte/src/index.js"; +import sveltePreprocess from "file:///C:/Users/blueb/OneDrive/Documents/VSC/_Risu/kakuna/RisuAI/node_modules/.pnpm/svelte-preprocess@5.0.4_postcss@8.4.26_svelte@4.1.0_typescript@5.1.6/node_modules/svelte-preprocess/dist/index.js"; +import wasm from "file:///C:/Users/blueb/OneDrive/Documents/VSC/_Risu/kakuna/RisuAI/node_modules/.pnpm/vite-plugin-wasm@3.2.2_vite@4.4.5/node_modules/vite-plugin-wasm/exports/import.mjs"; +import { internalIpV4 } from "file:///C:/Users/blueb/OneDrive/Documents/VSC/_Risu/kakuna/RisuAI/node_modules/.pnpm/internal-ip@7.0.0/node_modules/internal-ip/index.js"; +import topLevelAwait from "file:///C:/Users/blueb/OneDrive/Documents/VSC/_Risu/kakuna/RisuAI/node_modules/.pnpm/vite-plugin-top-level-await@1.3.1_rollup@3.26.3_vite@4.4.5/node_modules/vite-plugin-top-level-await/exports/import.mjs"; +var vite_config_default = defineConfig(async () => { + const host = await internalIpV4(); + return { + plugins: [ + svelte({ + preprocess: [ + sveltePreprocess({ + typescript: true + }) + ], + onwarn: (warning, handler) => { + if (warning.code.startsWith("a11y-")) + return; + handler(warning); + } + }), + wasm(), + topLevelAwait() + ], + // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build` + // prevent vite from obscuring rust errors + clearScreen: false, + // tauri expects a fixed port, fail if that port is not available + server: { + host: "0.0.0.0", + // listen on all addresses + port: 5174, + strictPort: true, + hmr: { + protocol: "ws", + host, + port: 5184 + } + }, + // to make use of `TAURI_DEBUG` and other env variables + // https://tauri.studio/v1/api/config#buildconfig.beforedevcommand + envPrefix: ["VITE_", "TAURI_"], + build: { + // Tauri supports es2021 + target: process.env.TAURI_PLATFORM == "windows" ? "chrome105" : "safari13", + // don't minify for debug builds + minify: process.env.TAURI_DEBUG ? false : "esbuild", + // produce sourcemaps for debug builds + sourcemap: !!process.env.TAURI_DEBUG, + chunkSizeWarningLimit: 2e3 + }, + optimizeDeps: { + needsInterop: [ + "@mlc-ai/web-tokenizers" + ] + }, + resolve: { + alias: { + "src": "/src", + "modules": "/modules" + } + } + }; +}); +export { + vite_config_default as default +}; +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJDOlxcXFxVc2Vyc1xcXFxibHVlYlxcXFxPbmVEcml2ZVxcXFxEb2N1bWVudHNcXFxcVlNDXFxcXF9SaXN1XFxcXGtha3VuYVxcXFxSaXN1QUlcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIkM6XFxcXFVzZXJzXFxcXGJsdWViXFxcXE9uZURyaXZlXFxcXERvY3VtZW50c1xcXFxWU0NcXFxcX1Jpc3VcXFxca2FrdW5hXFxcXFJpc3VBSVxcXFx2aXRlLmNvbmZpZy50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vQzovVXNlcnMvYmx1ZWIvT25lRHJpdmUvRG9jdW1lbnRzL1ZTQy9fUmlzdS9rYWt1bmEvUmlzdUFJL3ZpdGUuY29uZmlnLnRzXCI7aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSBcInZpdGVcIjtcclxuaW1wb3J0IHsgc3ZlbHRlIH0gZnJvbSBcIkBzdmVsdGVqcy92aXRlLXBsdWdpbi1zdmVsdGVcIjtcclxuaW1wb3J0IHN2ZWx0ZVByZXByb2Nlc3MgZnJvbSBcInN2ZWx0ZS1wcmVwcm9jZXNzXCI7XHJcbmltcG9ydCB3YXNtIGZyb20gXCJ2aXRlLXBsdWdpbi13YXNtXCI7XHJcbmltcG9ydCB7IGludGVybmFsSXBWNCB9IGZyb20gJ2ludGVybmFsLWlwJ1xyXG5pbXBvcnQgdG9wTGV2ZWxBd2FpdCBmcm9tIFwidml0ZS1wbHVnaW4tdG9wLWxldmVsLWF3YWl0XCI7XHJcblxyXG4vLyBodHRwczovL3ZpdGVqcy5kZXYvY29uZmlnL1xyXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVDb25maWcoYXN5bmMgKCkgPT4ge1xyXG4gIFxyXG4gIGNvbnN0IGhvc3QgPSBhd2FpdCBpbnRlcm5hbElwVjQoKVxyXG5cclxuICByZXR1cm4ge1xyXG4gICAgcGx1Z2luczogW1xyXG4gICAgICBcclxuICAgICAgc3ZlbHRlKHtcclxuICAgICAgICBwcmVwcm9jZXNzOiBbXHJcbiAgICAgICAgICBzdmVsdGVQcmVwcm9jZXNzKHtcclxuICAgICAgICAgICAgdHlwZXNjcmlwdDogdHJ1ZSxcclxuICAgICAgICAgIH0pLFxyXG4gICAgICAgIF0sXHJcbiAgICAgICAgb253YXJuOiAod2FybmluZywgaGFuZGxlcikgPT4ge1xyXG4gICAgICAgICAgLy8gZGlzYWJsZSBhMTF5IHdhcm5pbmdzXHJcbiAgICAgICAgICBpZiAod2FybmluZy5jb2RlLnN0YXJ0c1dpdGgoXCJhMTF5LVwiKSkgcmV0dXJuO1xyXG4gICAgICAgICAgaGFuZGxlcih3YXJuaW5nKTtcclxuICAgICAgICB9LFxyXG4gICAgICB9KSxcclxuICAgICAgd2FzbSgpLFxyXG4gICAgICB0b3BMZXZlbEF3YWl0KCksXHJcbiAgICBdLFxyXG5cclxuICAgIC8vIFZpdGUgb3B0aW9ucyB0YWlsb3JlZCBmb3IgVGF1cmkgZGV2ZWxvcG1lbnQgYW5kIG9ubHkgYXBwbGllZCBpbiBgdGF1cmkgZGV2YCBvciBgdGF1cmkgYnVpbGRgXHJcbiAgICAvLyBwcmV2ZW50IHZpdGUgZnJvbSBvYnNjdXJpbmcgcnVzdCBlcnJvcnNcclxuICAgIGNsZWFyU2NyZWVuOiBmYWxzZSxcclxuICAgIC8vIHRhdXJpIGV4cGVjdHMgYSBmaXhlZCBwb3J0LCBmYWlsIGlmIHRoYXQgcG9ydCBpcyBub3QgYXZhaWxhYmxlXHJcbiAgICBzZXJ2ZXI6IHtcclxuICAgICAgaG9zdDogJzAuMC4wLjAnLCAvLyBsaXN0ZW4gb24gYWxsIGFkZHJlc3Nlc1xyXG4gICAgICBwb3J0OiA1MTc0LFxyXG4gICAgICBzdHJpY3RQb3J0OiB0cnVlLFxyXG4gICAgICBobXI6IHtcclxuICAgICAgICBwcm90b2NvbDogJ3dzJyxcclxuICAgICAgICBob3N0LFxyXG4gICAgICAgIHBvcnQ6IDUxODQsXHJcbiAgICAgIH0sXHJcbiAgICB9LFxyXG4gICAgLy8gdG8gbWFrZSB1c2Ugb2YgYFRBVVJJX0RFQlVHYCBhbmQgb3RoZXIgZW52IHZhcmlhYmxlc1xyXG4gICAgLy8gaHR0cHM6Ly90YXVyaS5zdHVkaW8vdjEvYXBpL2NvbmZpZyNidWlsZGNvbmZpZy5iZWZvcmVkZXZjb21tYW5kXHJcbiAgICBlbnZQcmVmaXg6IFtcIlZJVEVfXCIsIFwiVEFVUklfXCJdLFxyXG4gICAgYnVpbGQ6IHtcclxuICAgICAgLy8gVGF1cmkgc3VwcG9ydHMgZXMyMDIxXHJcbiAgICAgIHRhcmdldDogcHJvY2Vzcy5lbnYuVEFVUklfUExBVEZPUk0gPT0gXCJ3aW5kb3dzXCIgPyBcImNocm9tZTEwNVwiIDogXCJzYWZhcmkxM1wiLFxyXG4gICAgICAvLyBkb24ndCBtaW5pZnkgZm9yIGRlYnVnIGJ1aWxkc1xyXG4gICAgICBtaW5pZnk6IHByb2Nlc3MuZW52LlRBVVJJX0RFQlVHID8gZmFsc2UgOiAnZXNidWlsZCcsXHJcbiAgICAgIC8vIHByb2R1Y2Ugc291cmNlbWFwcyBmb3IgZGVidWcgYnVpbGRzXHJcbiAgICAgIHNvdXJjZW1hcDogISFwcm9jZXNzLmVudi5UQVVSSV9ERUJVRyxcclxuICAgICAgY2h1bmtTaXplV2FybmluZ0xpbWl0OiAyMDAwXHJcbiAgICB9LFxyXG4gICAgXHJcbiAgICBvcHRpbWl6ZURlcHM6e1xyXG4gICAgICBuZWVkc0ludGVyb3A6W1xyXG4gICAgICAgIFwiQG1sYy1haS93ZWItdG9rZW5pemVyc1wiXHJcbiAgICAgIF1cclxuICAgIH0sXHJcblxyXG4gICAgcmVzb2x2ZTp7XHJcbiAgICAgIGFsaWFzOntcclxuICAgICAgICAnc3JjJzonL3NyYycsXHJcbiAgICAgICAgJ21vZHVsZXMnOiAnL21vZHVsZXMnXHJcbiAgICAgIH1cclxuICAgIH1cclxufX0pO1xyXG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQStXLFNBQVMsb0JBQW9CO0FBQzVZLFNBQVMsY0FBYztBQUN2QixPQUFPLHNCQUFzQjtBQUM3QixPQUFPLFVBQVU7QUFDakIsU0FBUyxvQkFBb0I7QUFDN0IsT0FBTyxtQkFBbUI7QUFHMUIsSUFBTyxzQkFBUSxhQUFhLFlBQVk7QUFFdEMsUUFBTSxPQUFPLE1BQU0sYUFBYTtBQUVoQyxTQUFPO0FBQUEsSUFDTCxTQUFTO0FBQUEsTUFFUCxPQUFPO0FBQUEsUUFDTCxZQUFZO0FBQUEsVUFDVixpQkFBaUI7QUFBQSxZQUNmLFlBQVk7QUFBQSxVQUNkLENBQUM7QUFBQSxRQUNIO0FBQUEsUUFDQSxRQUFRLENBQUMsU0FBUyxZQUFZO0FBRTVCLGNBQUksUUFBUSxLQUFLLFdBQVcsT0FBTztBQUFHO0FBQ3RDLGtCQUFRLE9BQU87QUFBQSxRQUNqQjtBQUFBLE1BQ0YsQ0FBQztBQUFBLE1BQ0QsS0FBSztBQUFBLE1BQ0wsY0FBYztBQUFBLElBQ2hCO0FBQUE7QUFBQTtBQUFBLElBSUEsYUFBYTtBQUFBO0FBQUEsSUFFYixRQUFRO0FBQUEsTUFDTixNQUFNO0FBQUE7QUFBQSxNQUNOLE1BQU07QUFBQSxNQUNOLFlBQVk7QUFBQSxNQUNaLEtBQUs7QUFBQSxRQUNILFVBQVU7QUFBQSxRQUNWO0FBQUEsUUFDQSxNQUFNO0FBQUEsTUFDUjtBQUFBLElBQ0Y7QUFBQTtBQUFBO0FBQUEsSUFHQSxXQUFXLENBQUMsU0FBUyxRQUFRO0FBQUEsSUFDN0IsT0FBTztBQUFBO0FBQUEsTUFFTCxRQUFRLFFBQVEsSUFBSSxrQkFBa0IsWUFBWSxjQUFjO0FBQUE7QUFBQSxNQUVoRSxRQUFRLFFBQVEsSUFBSSxjQUFjLFFBQVE7QUFBQTtBQUFBLE1BRTFDLFdBQVcsQ0FBQyxDQUFDLFFBQVEsSUFBSTtBQUFBLE1BQ3pCLHVCQUF1QjtBQUFBLElBQ3pCO0FBQUEsSUFFQSxjQUFhO0FBQUEsTUFDWCxjQUFhO0FBQUEsUUFDWDtBQUFBLE1BQ0Y7QUFBQSxJQUNGO0FBQUEsSUFFQSxTQUFRO0FBQUEsTUFDTixPQUFNO0FBQUEsUUFDSixPQUFNO0FBQUEsUUFDTixXQUFXO0FBQUEsTUFDYjtBQUFBLElBQ0Y7QUFBQSxFQUNKO0FBQUMsQ0FBQzsiLAogICJuYW1lcyI6IFtdCn0K