Spaces:
Running on Zero
Running on Zero
Restore bundled Farterrogator UI, built fresh from source
Browse files- README.md +8 -8
- app.py +31 -50
- dist/assets/de-k3hfbLj-.js +1 -0
- dist/assets/en-FHVuPOw2.js +1 -0
- dist/assets/es-DNkSzkRz.js +1 -0
- dist/assets/fr-Ds8MV9-S.js +1 -0
- dist/assets/hi-cTTX2Ggg.js +1 -0
- dist/assets/index-BPgEO71u.css +0 -0
- dist/assets/index-BQRSZhA2.js +5 -0
- dist/assets/it-CJ48uQvE.js +1 -0
- dist/assets/ja-Bu_r5epl.js +1 -0
- dist/assets/ko-Ccvowmxl.js +1 -0
- dist/assets/pt-BpqmNNtz.js +1 -0
- dist/assets/rolldown-runtime-BHe-jwch.js +1 -0
- dist/assets/ru-CbpyFmXE.js +1 -0
- dist/assets/vendor-_ab0A6TJ.js +0 -0
- dist/assets/vendor-files-BrsAlTsV.js +0 -0
- dist/assets/zh-CN-juOm4LJT.js +1 -0
- dist/assets/zh-TW-DcQy6Mhc.js +1 -0
- dist/danbooru_tags.csv +0 -0
- dist/favicon.png +0 -0
- dist/favicon.webp +0 -0
- dist/gpu-garden-logo.png +0 -0
- dist/gpu-garden-logo.webp +0 -0
- dist/index.html +109 -0
- dist/robots.txt +2 -0
README.md
CHANGED
|
@@ -13,16 +13,16 @@ startup_duration_timeout: 1h
|
|
| 13 |
|
| 14 |
# localtagger
|
| 15 |
|
| 16 |
-
This Space
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
dbv4 architectures) across two inference backends (ONNX and PyTorch/timm), or
|
| 22 |
classify an illustration's likely artist/style with the Kaloscope 2.0
|
| 23 |
classifier.
|
| 24 |
|
| 25 |
All inference runs on CPU inside plain FastAPI routes mounted on a
|
| 26 |
`gradio.Server` instance; ZeroGPU hardware is reserved only to satisfy the
|
| 27 |
-
platform's startup requirement and isn't used for real requests.
|
| 28 |
-
|
|
|
|
|
|
| 13 |
|
| 14 |
# localtagger
|
| 15 |
|
| 16 |
+
This Space bundles the real [Farterrogator](https://github.com/mchaker/farterrogator)
|
| 17 |
+
UI, served on the same origin as its backend,
|
| 18 |
+
[localtagger](https://github.com/mchaker/localtagger). Pick from ten
|
| 19 |
+
Danbooru-style taggers (WD14 v3, Pixai, Camie v2, and five Animetimm dbv4
|
| 20 |
+
architectures) across two inference backends (ONNX and PyTorch/timm), or
|
|
|
|
| 21 |
classify an illustration's likely artist/style with the Kaloscope 2.0
|
| 22 |
classifier.
|
| 23 |
|
| 24 |
All inference runs on CPU inside plain FastAPI routes mounted on a
|
| 25 |
`gradio.Server` instance; ZeroGPU hardware is reserved only to satisfy the
|
| 26 |
+
platform's startup requirement and isn't used for real requests. The raw API
|
| 27 |
+
is also usable cross-origin (CORS is open) for anyone who wants to run
|
| 28 |
+
Farterrogator separately against this backend instead.
|
app.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
import os
|
|
|
|
| 2 |
|
| 3 |
os.environ.setdefault("PYTORCH_CUDA_ALLOC_CONF", "expandable_segments:True")
|
| 4 |
|
|
@@ -14,7 +15,8 @@ os.environ.setdefault("DEVICE", "cpu")
|
|
| 14 |
|
| 15 |
import spaces
|
| 16 |
from fastapi.middleware.cors import CORSMiddleware
|
| 17 |
-
from fastapi.responses import
|
|
|
|
| 18 |
from gradio import Server
|
| 19 |
|
| 20 |
from app.catalog import load_catalog
|
|
@@ -33,9 +35,9 @@ app.state.settings = settings
|
|
| 33 |
app.state.catalog = CATALOG
|
| 34 |
app.state.manager = MANAGER
|
| 35 |
|
| 36 |
-
#
|
| 37 |
-
#
|
| 38 |
-
# No cookies/auth are used, so a wildcard is safe here.
|
| 39 |
app.add_middleware(
|
| 40 |
CORSMiddleware,
|
| 41 |
allow_origins=["*"],
|
|
@@ -70,59 +72,38 @@ def warmup() -> bool:
|
|
| 70 |
return _gpu_warmup()
|
| 71 |
|
| 72 |
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
<h2>Use it with Farterrogator</h2>
|
| 98 |
-
<p>
|
| 99 |
-
Run the <a href="https://github.com/mchaker/farterrogator">Farterrogator</a>
|
| 100 |
-
frontend (locally or wherever you host it) and point its backend URL at this
|
| 101 |
-
Space:
|
| 102 |
-
</p>
|
| 103 |
-
<pre>https://mooshie-localtagger.hf.space</pre>
|
| 104 |
-
|
| 105 |
-
<h2>API</h2>
|
| 106 |
-
<table>
|
| 107 |
-
<tr><th>Endpoint</th><th>Description</th></tr>
|
| 108 |
-
<tr><td><code>GET /models</code></td><td>List available taggers</td></tr>
|
| 109 |
-
<tr><td><code>POST /interrogate?model=...&threshold=...</code></td><td>Tag an image (multipart <code>file</code>)</td></tr>
|
| 110 |
-
<tr><td><code>POST /kaloscope/infer</code></td><td>Guess an image's artist/style</td></tr>
|
| 111 |
-
<tr><td><code>GET /health</code></td><td>Health check</td></tr>
|
| 112 |
-
</table>
|
| 113 |
-
<p>Interactive schema + try-it-out: <a href="/docs">/docs</a></p>
|
| 114 |
-
</body>
|
| 115 |
-
</html>
|
| 116 |
-
"""
|
| 117 |
|
| 118 |
|
| 119 |
@app.get("/", include_in_schema=False)
|
| 120 |
async def index():
|
| 121 |
-
return
|
| 122 |
|
| 123 |
|
| 124 |
print(
|
| 125 |
-
"localtagger (
|
| 126 |
+ ", ".join(spec.id for spec in CATALOG.specs)
|
| 127 |
)
|
| 128 |
|
|
|
|
| 1 |
import os
|
| 2 |
+
from pathlib import Path
|
| 3 |
|
| 4 |
os.environ.setdefault("PYTORCH_CUDA_ALLOC_CONF", "expandable_segments:True")
|
| 5 |
|
|
|
|
| 15 |
|
| 16 |
import spaces
|
| 17 |
from fastapi.middleware.cors import CORSMiddleware
|
| 18 |
+
from fastapi.responses import FileResponse
|
| 19 |
+
from fastapi.staticfiles import StaticFiles
|
| 20 |
from gradio import Server
|
| 21 |
|
| 22 |
from app.catalog import load_catalog
|
|
|
|
| 35 |
app.state.catalog = CATALOG
|
| 36 |
app.state.manager = MANAGER
|
| 37 |
|
| 38 |
+
# The Farterrogator UI below is served same-origin, but the raw API is also
|
| 39 |
+
# useful to callers hitting it directly from elsewhere (scripts, other
|
| 40 |
+
# frontends). No cookies/auth are used, so a wildcard origin is safe here.
|
| 41 |
app.add_middleware(
|
| 42 |
CORSMiddleware,
|
| 43 |
allow_origins=["*"],
|
|
|
|
| 72 |
return _gpu_warmup()
|
| 73 |
|
| 74 |
|
| 75 |
+
# Farterrogator (https://github.com/mchaker/farterrogator) build, served
|
| 76 |
+
# same-origin as the API. `dist/` is built fresh from that repo and uploaded
|
| 77 |
+
# alongside this file -- never mount StaticFiles at bare "/": Starlette's
|
| 78 |
+
# root Mount intercepts Gradio's own /gradio_api/startup-events self-check
|
| 79 |
+
# route (registered only during demo.launch(), after this module runs) and
|
| 80 |
+
# 404s it, crashing the app at boot. Individual routes avoid that collision.
|
| 81 |
+
DIST_DIR = Path(__file__).parent / "dist"
|
| 82 |
+
|
| 83 |
+
app.mount("/assets", StaticFiles(directory=DIST_DIR / "assets"), name="assets")
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
def _make_static_file_route(file_path: Path):
|
| 87 |
+
async def _serve():
|
| 88 |
+
return FileResponse(file_path)
|
| 89 |
+
|
| 90 |
+
return _serve
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
for _entry in DIST_DIR.iterdir():
|
| 94 |
+
if _entry.is_file() and _entry.name != "index.html":
|
| 95 |
+
app.get(f"/{_entry.name}", include_in_schema=False)(
|
| 96 |
+
_make_static_file_route(_entry)
|
| 97 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
|
| 99 |
|
| 100 |
@app.get("/", include_in_schema=False)
|
| 101 |
async def index():
|
| 102 |
+
return FileResponse(DIST_DIR / "index.html")
|
| 103 |
|
| 104 |
|
| 105 |
print(
|
| 106 |
+
"localtagger (Farterrogator UI) ready. Enabled models: "
|
| 107 |
+ ", ".join(spec.id for spec in CATALOG.specs)
|
| 108 |
)
|
| 109 |
|
dist/assets/de-k3hfbLj-.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
var e={title:`Farterrogator`,subtitle:`KI-Bild-Interrogator`,copyright:`Farterrogator © {{year}} Fartcore. Alle Rechte vorbehalten. Die Modelle sind kein Eigentum von Fartcore und werden kostenlos bereitgestellt.`,logoAlt:`Farterrogator-Logo`,modelsNotice:`Neu: Es stehen jetzt mehrere Tagger-Modelle zur Verfügung! Wähle eines in den Einstellungen aus.`,madeBy:`erstellt von <mooshieblob>mooshieblob</mooshieblob> und <ashtaka>ashtaka</ashtaka>`},t={close:`Schließen`,changeLanguage:`Sprache ändern`,languageSelection:`Sprachauswahl`},n={whatIsThis:`Was ist das?`,poweredBy:`Modell: {{model}}`,nothingYet:`Keins`},r={inputImage:`Eingabebild`,dragDrop:`Bild hierher ziehen oder klicken zum Auswählen`,dropHere:`Dateien hier ablegen`,supports:`Unterstützt PNG, JPG, WEBP, GIF`,supportsArchives:`(+ ZIP, TAR)`,clear:`Bild entfernen`,interrogate:`Analysieren`,previewAlt:`Vorschau des hochgeladenen Bildes`,filesSelected:`{{num}} Dateien ausgewählt`,batchReady:`Bereit für Stapelverarbeitung`},i={title:`Analyseergebnis`,ready:`Bereit zur Analyse`,readySub:`Lade ein Bild hoch, um mit dem Tagging zu beginnen`,failed:`Analyse fehlgeschlagen`,troubleshoot:`Fehlerbehebung:`,troubleshootTagger:`Stelle sicher, dass der Tagger unter {{endpoint}} erreichbar ist`,processing:`Verarbeitung...`,analyzing:`Analysiere...`,technicalTags:`Tags`,noTags:`Keine Tags beim aktuellen Schwellenwert gefunden.`,copyAll:`Alle kopieren`,copied:`Kopiert!`,copiedItem:`Kopiert: {{item}}`,naiReady:`NAI Ready`,downloadNai:`Mit eingebetteten Tags herunterladen`,tagsCopied:`Alle Tags in die Zwischenablage kopiert!`,embedFailed:`NAI-Ready-Bild konnte nicht erstellt werden.`,score:`Wert`,batchResults:`Stapelergebnisse`,artistSimilarity:`Künstler-Ähnlichkeit`,matchingArtists:`Künstlerstile werden abgeglichen...`,copyArtist:`Künstlernamen kopieren`,noPreview:`Keine Vorschau`,openOnDanbooru:`Auf Danbooru öffnen`,openArtistOnDanbooru:`{{artist}} auf Danbooru öffnen`},a={starting:`Starte...`,analyzingImage:`Bild wird analysiert...`,done:`Fertig`},o={title:`Einstellungen`,thresholds:`Schwellenwerte`,outputSettings:`Ausgabe`,topK:`Top-K-Tags`,randomize:`Zufällige Reihenfolge`,removeUnderscores:`Unterstriche entfernen`,scoreDescend:`Nach Bewertung sortieren`,includeRanks:`Werte an Tags anhängen`,useEscape:`Klammern maskieren`,advancedThresholds:`Erweitert`,backend:{model:`Tagger-Modell`,baseUrl:`API-URL`,baseUrlHint:`API-Endpunkt-URL, z. B. https://localtagger.gpu.garden oder http://localhost:8000`,families:{wd14:`WD-Familie`,animetimm:`AnimeTimm`,camie:`Camie`},models:{},gatedHint:`Erfordert ein Hugging-Face-Token auf dem Server.`,warmupHint:`Modell noch nicht geladen — die erste Anfrage kann länger dauern.`,onlineHint:`Backend online.`,offlineHint:`Backend nicht erreichbar. Überprüfe die API-URL oder ob der Server läuft.`,resetToDefault:`Auf Standard zurücksetzen`},categories:{general:`Allgemein`,character:`Charakter`,copyright:`Copyright`,artist:`Künstler`,meta:`Meta`,rating:`Einstufung`},maxTags:`Max. Tags (0 = unbegrenzt)`,whitelist:`Tag-Whitelist`,whitelistPlaceholder:`z. B. masterpiece, best quality`,blacklist:`Tag-Blacklist`,blacklistPlaceholder:`z. B. watermark, signature`},s={taggerRequired:`Die Basis-URL des Taggers ist erforderlich. Bitte in den Backend-Einstellungen konfigurieren.`,taggerError:`Tagger-Fehler: {{status}} {{statusText}}`,batchTaggerError:`Batch-Tagger-Fehler: {{status}} {{statusText}}`,kaloscopeError:`Kaloscope-Fehler: {{status}} {{statusText}}`,unknown:`Ein unbekannter Fehler ist aufgetreten`},c={title:`Was ist Farterrogator?`,description:`<strong>Farterrogator</strong> ist ein schneller, lokaler Bild-Tagger im Booru-Stil. Er analysiert Bilder mit Modellen der WD EVA 02-Familie und illustrationszentrierten Modellen, um Danbooru-kompatible Tags für Datensatzerstellung und Prompt-Engineering zu extrahieren.`,features:{models:{title:`Mehrere Tagger-Modelle`,description:`Wähle zwischen <strong>WD SwinV2</strong>, <strong>WD EVA02</strong>, <strong>AnimeTimm</strong> und <strong>Camie</strong> — plus Kaloscope-Künstlerstil-Ähnlichkeit.`},naiReady:{title:`NAI-Ready-Einbettung`,description:`Bettet generierte Tags automatisch in PNG-Metadaten ein. Die resultierenden Bilder sind "NAI Ready" — einfach in NovelAI ziehen, um Prompts automatisch auszufüllen.`},privacy:{title:`Datenschutz & Leistung`,description:`Die gesamte Inferenz läuft auf dem konfigurierten Backend (gpu.garden oder lokal). Keine Cloud-API-Schlüssel erforderlich.`},gpuGarden:{title:`GPU-Garden-Integration`,description:`Optimiert für die gpu.garden-Infrastruktur mit automatischem CORS-Proxy-Routing.`}},howTo:{title:`Anleitung`,step1:`Lade ein Bild hoch oder ziehe es auf die Fläche.`,step2:`Wähle ein Tagger-Modell — die Liste wird vom Backend geladen.`,step3:`Passe die Konfidenz-Schwellenwerte an, um Tags zu filtern.`,step4:`Klicke auf <strong>Analysieren</strong>.`,step5:`Kopiere die Tags oder lade ein <strong>NAI Ready</strong>-PNG herunter.`},madeBy:`Erstellt von`},l={label:`Themenauswahl`,light:`Heller Modus`,auto:`System-Automatik`,dark:`Dunkler Modus`},u={app:e,common:t,header:n,upload:r,results:i,status:a,settings:o,errors:s,info:c,theme:l};export{e as app,t as common,u as default,s as errors,n as header,c as info,i as results,o as settings,a as status,l as theme,r as upload};
|
dist/assets/en-FHVuPOw2.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
var e={title:`Farterrogator`,subtitle:`AI Image Interrogator`,copyright:`Farterrogator © {{year}} Fartcore. All rights reserved. Models are not property of Fartcore and are provided free of charge.`,logoAlt:`Farterrogator logo`,modelsNotice:`New: multiple tagger models are now available! Pick one in the settings.`,madeBy:`made by <mooshieblob>mooshieblob</mooshieblob> and <ashtaka>ashtaka</ashtaka>`},t={close:`Close`,changeLanguage:`Change Language`,languageSelection:`Language selection`},n={whatIsThis:`What is this?`,poweredBy:`Model: {{model}}`,nothingYet:`None`},r={inputImage:`Input Image`,dragDrop:`Drag & drop an image here, or click to select`,dropHere:`Drop files here`,supports:`Supports PNG, JPG, WEBP, GIF`,supportsArchives:`(+ ZIP, TAR)`,clear:`Clear Image`,interrogate:`Interrogate`,previewAlt:`Uploaded image preview`,filesSelected:`{{num}} files selected`,batchReady:`Ready for batch processing`},i={title:`Analysis Result`,ready:`Ready to Interrogate`,readySub:`Upload an image to begin tagging`,failed:`Analysis Failed`,troubleshoot:`Troubleshooting:`,troubleshootTagger:`Ensure the tagger is reachable at {{endpoint}}`,processing:`Processing...`,analyzing:`Analyzing...`,technicalTags:`Tags`,noTags:`No tags found at current threshold.`,copyAll:`Copy All`,copied:`Copied!`,copiedItem:`Copied: {{item}}`,naiReady:`NAI Ready`,downloadNai:`Download with tags embedded`,tagsCopied:`All tags copied to clipboard!`,embedFailed:`Failed to create NAI ready image.`,score:`Score`,batchResults:`Batch Results`,artistSimilarity:`Artist Similarity`,matchingArtists:`Matching artist styles...`,copyArtist:`Copy artist name`,noPreview:`No preview`,openOnDanbooru:`Open on Danbooru`,openArtistOnDanbooru:`Open {{artist}} on Danbooru`},a={starting:`Starting...`,analyzingImage:`Analyzing image...`,done:`Done`},o={title:`Settings`,thresholds:`Thresholds`,outputSettings:`Output`,topK:`Top K Tags`,randomize:`Randomize Order`,removeUnderscores:`Remove Underscores`,scoreDescend:`Sort by Score`,includeRanks:`Append Scores to Tags`,useEscape:`Escape Parentheses`,advancedThresholds:`Advanced`,backend:{model:`Tagger Model`,baseUrl:`API URL`,baseUrlHint:`API endpoint URL, e.g. https://localtagger.gpu.garden or http://localhost:8000`,families:{wd14:`WD Family`,animetimm:`AnimeTimm`,camie:`Camie`},models:{},gatedHint:`Requires a Hugging Face token on the server.`,warmupHint:`Model not loaded yet — the first request may take longer.`,onlineHint:`Backend online.`,offlineHint:`Backend unreachable. Check the API URL or that the server is running.`,resetToDefault:`Reset to default`},categories:{general:`General`,character:`Character`,copyright:`Copyright`,artist:`Artist`,meta:`Meta`,rating:`Rating`},maxTags:`Max Tags (0 = Unlimited)`,whitelist:`Tag Whitelist`,whitelistPlaceholder:`e.g. masterpiece, best quality`,blacklist:`Tag Blacklist`,blacklistPlaceholder:`e.g. watermark, signature`},s={taggerRequired:`Tagger base URL is required. Please configure it in the backend settings.`,taggerError:`Tagger error: {{status}} {{statusText}}`,batchTaggerError:`Batch tagger error: {{status}} {{statusText}}`,kaloscopeError:`Kaloscope error: {{status}} {{statusText}}`,unknown:`An unknown error occurred`},c={title:`What is Farterrogator?`,description:`<strong>Farterrogator</strong> is a fast, local Booru-style image tagger. It analyzes images using WD EVA 02-family and illustration-centric models to extract Danbooru-compatible tags for dataset creation and prompt engineering.`,features:{models:{title:`Multiple Tagger Models`,description:`Choose between <strong>WD SwinV2</strong>, <strong>WD EVA02</strong>, <strong>AnimeTimm</strong> and <strong>Camie</strong> models — plus Kaloscope artist style similarity.`},naiReady:{title:`NAI Ready Embedding`,description:`Automatically embed generated tags into PNG metadata. The resulting images are "NAI Ready" — simply drag them into NovelAI to autopopulate prompts.`},privacy:{title:`Privacy & Performance`,description:`All inference runs on the configured backend (gpu.garden or local). No cloud API keys required.`},gpuGarden:{title:`GPU Garden Integration`,description:`Optimized for gpu.garden infrastructure with automatic CORS proxy routing.`}},howTo:{title:`How to use`,step1:`Upload an image or drag & drop it onto the canvas.`,step2:`Select a tagger model — the list is loaded from the backend.`,step3:`Adjust confidence thresholds to filter tags.`,step4:`Click <strong>Interrogate</strong>.`,step5:`Copy tags, or download an <strong>NAI Ready</strong> PNG.`},madeBy:`Made by`},l={label:`Theme selection`,light:`Light Mode`,auto:`System Auto`,dark:`Dark Mode`},u={app:e,common:t,header:n,upload:r,results:i,status:a,settings:o,errors:s,info:c,theme:l};export{e as app,t as common,u as default,s as errors,n as header,c as info,i as results,o as settings,a as status,l as theme,r as upload};
|
dist/assets/es-DNkSzkRz.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
var e={title:`Farterrogator`,subtitle:`Interrogador de Imágenes IA`,copyright:`Farterrogator © {{year}} Fartcore. Todos los derechos reservados. Los modelos no son propiedad de Fartcore y se ofrecen de forma gratuita.`,logoAlt:`Logotipo de Farterrogator`,modelsNotice:`Novedad: ¡ya hay varios modelos de etiquetado disponibles! Elige uno en los ajustes.`,madeBy:`hecho por <mooshieblob>mooshieblob</mooshieblob> y <ashtaka>ashtaka</ashtaka>`},t={close:`Cerrar`,changeLanguage:`Cambiar idioma`,languageSelection:`Selección de idioma`},n={whatIsThis:`¿Qué es esto?`,poweredBy:`Modelo: {{model}}`,nothingYet:`Ninguno`},r={inputImage:`Imagen de entrada`,dragDrop:`Arrastra y suelta una imagen aquí, o haz clic para seleccionar`,dropHere:`Suelta los archivos aquí`,supports:`Compatible con PNG, JPG, WEBP, GIF`,supportsArchives:`(+ ZIP, TAR)`,clear:`Quitar imagen`,interrogate:`Interrogar`,previewAlt:`Vista previa de la imagen subida`,filesSelected:`{{num}} archivos seleccionados`,batchReady:`Listo para procesamiento por lotes`},i={title:`Resultado del análisis`,ready:`Listo para interrogar`,readySub:`Sube una imagen para comenzar el etiquetado`,failed:`Análisis fallido`,troubleshoot:`Solución de problemas:`,troubleshootTagger:`Asegúrate de que el etiquetador sea accesible en {{endpoint}}`,processing:`Procesando...`,analyzing:`Analizando...`,technicalTags:`Etiquetas`,noTags:`No se encontraron etiquetas con el umbral actual.`,copyAll:`Copiar todo`,copied:`¡Copiado!`,copiedItem:`Copiado: {{item}}`,naiReady:`NAI Ready`,downloadNai:`Descargar con etiquetas incrustadas`,tagsCopied:`¡Todas las etiquetas copiadas al portapapeles!`,embedFailed:`Error al crear la imagen NAI Ready.`,score:`Puntuación`,batchResults:`Resultados por lotes`,artistSimilarity:`Similitud de artista`,matchingArtists:`Buscando estilos de artistas...`,copyArtist:`Copiar nombre del artista`,noPreview:`Sin vista previa`,openOnDanbooru:`Abrir en Danbooru`,openArtistOnDanbooru:`Abrir {{artist}} en Danbooru`},a={starting:`Iniciando...`,analyzingImage:`Analizando imagen...`,done:`Hecho`},o={title:`Ajustes`,thresholds:`Umbrales`,outputSettings:`Salida`,topK:`Top K etiquetas`,randomize:`Orden aleatorio`,removeUnderscores:`Quitar guiones bajos`,scoreDescend:`Ordenar por puntuación`,includeRanks:`Añadir puntuaciones a las etiquetas`,useEscape:`Escapar paréntesis`,advancedThresholds:`Avanzado`,backend:{model:`Modelo de etiquetado`,baseUrl:`URL de la API`,baseUrlHint:`URL del endpoint API, p. ej. https://localtagger.gpu.garden o http://localhost:8000`,families:{wd14:`Familia WD`,animetimm:`AnimeTimm`,camie:`Camie`},models:{},gatedHint:`Requiere un token de Hugging Face en el servidor.`,warmupHint:`El modelo aún no está cargado: la primera solicitud puede tardar más.`,onlineHint:`Backend en línea.`,offlineHint:`Backend inaccesible. Comprueba la URL de la API o que el servidor esté en ejecución.`,resetToDefault:`Restablecer predeterminado`},categories:{general:`General`,character:`Personaje`,copyright:`Copyright`,artist:`Artista`,meta:`Meta`,rating:`Clasificación`},maxTags:`Máx. etiquetas (0 = ilimitado)`,whitelist:`Lista blanca de etiquetas`,whitelistPlaceholder:`p. ej. masterpiece, best quality`,blacklist:`Lista negra de etiquetas`,blacklistPlaceholder:`p. ej. watermark, signature`},s={taggerRequired:`Se requiere la URL base del etiquetador. Configúrala en los ajustes del backend.`,taggerError:`Error del etiquetador: {{status}} {{statusText}}`,batchTaggerError:`Error del etiquetador por lotes: {{status}} {{statusText}}`,kaloscopeError:`Error de Kaloscope: {{status}} {{statusText}}`,unknown:`Ocurrió un error desconocido`},c={title:`¿Qué es Farterrogator?`,description:`<strong>Farterrogator</strong> es un etiquetador de imágenes local y rápido al estilo Booru. Analiza imágenes con modelos de la familia WD EVA 02 y modelos centrados en ilustración para extraer etiquetas compatibles con Danbooru, ideales para crear datasets y diseñar prompts.`,features:{models:{title:`Varios modelos de etiquetado`,description:`Elige entre los modelos <strong>WD SwinV2</strong>, <strong>WD EVA02</strong>, <strong>AnimeTimm</strong> y <strong>Camie</strong>, además de la similitud de estilo de artista con Kaloscope.`},naiReady:{title:`Incrustación NAI Ready`,description:`Incrusta automáticamente las etiquetas generadas en los metadatos PNG. Las imágenes resultantes son "NAI Ready": simplemente arrástralas a NovelAI para autocompletar los prompts.`},privacy:{title:`Privacidad y rendimiento`,description:`Toda la inferencia se ejecuta en el backend configurado (gpu.garden o local). No se requieren claves de API en la nube.`},gpuGarden:{title:`Integración con GPU Garden`,description:`Optimizado para la infraestructura de gpu.garden con enrutamiento automático del proxy CORS.`}},howTo:{title:`Cómo usarlo`,step1:`Sube una imagen o arrástrala al lienzo.`,step2:`Selecciona un modelo de etiquetado: la lista se carga desde el backend.`,step3:`Ajusta los umbrales de confianza para filtrar etiquetas.`,step4:`Haz clic en <strong>Interrogar</strong>.`,step5:`Copia las etiquetas o descarga un PNG <strong>NAI Ready</strong>.`},madeBy:`Hecho por`},l={label:`Selección de tema`,light:`Modo claro`,auto:`Automático del sistema`,dark:`Modo oscuro`},u={app:e,common:t,header:n,upload:r,results:i,status:a,settings:o,errors:s,info:c,theme:l};export{e as app,t as common,u as default,s as errors,n as header,c as info,i as results,o as settings,a as status,l as theme,r as upload};
|
dist/assets/fr-Ds8MV9-S.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
var e={title:`Farterrogator`,subtitle:`Interrogateur d'images IA`,copyright:`Farterrogator © {{year}} Fartcore. Tous droits réservés. Les modèles ne sont pas la propriété de Fartcore et sont fournis gratuitement.`,logoAlt:`Logo Farterrogator`,modelsNotice:`Nouveau : plusieurs modèles de tagging sont désormais disponibles ! Choisissez-en un dans les réglages.`,madeBy:`créé par <mooshieblob>mooshieblob</mooshieblob> et <ashtaka>ashtaka</ashtaka>`},t={close:`Fermer`,changeLanguage:`Changer de langue`,languageSelection:`Sélection de la langue`},n={whatIsThis:`Qu'est-ce que c'est ?`,poweredBy:`Modèle : {{model}}`,nothingYet:`Aucun`},r={inputImage:`Image d'entrée`,dragDrop:`Glissez-déposez une image ici, ou cliquez pour sélectionner`,dropHere:`Déposez les fichiers ici`,supports:`Prend en charge PNG, JPG, WEBP, GIF`,supportsArchives:`(+ ZIP, TAR)`,clear:`Retirer l'image`,interrogate:`Interroger`,previewAlt:`Aperçu de l'image téléversée`,filesSelected:`{{num}} fichiers sélectionnés`,batchReady:`Prêt pour le traitement par lots`},i={title:`Résultat de l'analyse`,ready:`Prêt à interroger`,readySub:`Téléversez une image pour commencer le tagging`,failed:`Échec de l'analyse`,troubleshoot:`Dépannage :`,troubleshootTagger:`Vérifiez que le tagger est accessible à {{endpoint}}`,processing:`Traitement...`,analyzing:`Analyse...`,technicalTags:`Tags`,noTags:`Aucun tag trouvé au seuil actuel.`,copyAll:`Tout copier`,copied:`Copié !`,copiedItem:`Copié : {{item}}`,naiReady:`NAI Ready`,downloadNai:`Télécharger avec les tags intégrés`,tagsCopied:`Tous les tags copiés dans le presse-papiers !`,embedFailed:`Échec de la création de l'image NAI Ready.`,score:`Score`,batchResults:`Résultats par lots`,artistSimilarity:`Similarité d'artiste`,matchingArtists:`Recherche de styles d'artistes...`,copyArtist:`Copier le nom de l'artiste`,noPreview:`Aucun aperçu`,openOnDanbooru:`Ouvrir sur Danbooru`,openArtistOnDanbooru:`Ouvrir {{artist}} sur Danbooru`},a={starting:`Démarrage...`,analyzingImage:`Analyse de l'image...`,done:`Terminé`},o={title:`Paramètres`,thresholds:`Seuils`,outputSettings:`Sortie`,topK:`Top K tags`,randomize:`Ordre aléatoire`,removeUnderscores:`Supprimer les underscores`,scoreDescend:`Trier par score`,includeRanks:`Ajouter les scores aux tags`,useEscape:`Échapper les parenthèses`,advancedThresholds:`Avancé`,backend:{model:`Modèle de tagging`,baseUrl:`URL de l'API`,baseUrlHint:`URL de l'endpoint API, ex. https://localtagger.gpu.garden ou http://localhost:8000`,families:{wd14:`Famille WD`,animetimm:`AnimeTimm`,camie:`Camie`},models:{},gatedHint:`Nécessite un jeton Hugging Face côté serveur.`,warmupHint:`Modèle pas encore chargé — la première requête peut prendre plus de temps.`,onlineHint:`Backend en ligne.`,offlineHint:`Backend injoignable. Vérifiez l'URL de l'API ou que le serveur est démarré.`,resetToDefault:`Réinitialiser par défaut`},categories:{general:`Général`,character:`Personnage`,copyright:`Copyright`,artist:`Artiste`,meta:`Méta`,rating:`Classification`},maxTags:`Max. tags (0 = illimité)`,whitelist:`Liste blanche de tags`,whitelistPlaceholder:`p. ex. masterpiece, best quality`,blacklist:`Liste noire de tags`,blacklistPlaceholder:`p. ex. watermark, signature`},s={taggerRequired:`L'URL de base du tagger est requise. Veuillez la configurer dans les paramètres du backend.`,taggerError:`Erreur du tagger : {{status}} {{statusText}}`,batchTaggerError:`Erreur du tagger par lots : {{status}} {{statusText}}`,kaloscopeError:`Erreur Kaloscope : {{status}} {{statusText}}`,unknown:`Une erreur inconnue s'est produite`},c={title:`Qu'est-ce que Farterrogator ?`,description:`<strong>Farterrogator</strong> est un tagger d'images local et rapide de style Booru. Il analyse les images avec des modèles de la famille WD EVA 02 et des modèles centrés sur l'illustration pour extraire des tags compatibles Danbooru, pour la création de datasets et le prompt engineering.`,features:{models:{title:`Plusieurs modèles de tagging`,description:`Choisissez entre les modèles <strong>WD SwinV2</strong>, <strong>WD EVA02</strong>, <strong>AnimeTimm</strong> et <strong>Camie</strong> — plus la similarité de style d'artiste Kaloscope.`},naiReady:{title:`Intégration NAI Ready`,description:`Intègre automatiquement les tags générés dans les métadonnées PNG. Les images obtenues sont « NAI Ready » : glissez-les simplement dans NovelAI pour remplir automatiquement les prompts.`},privacy:{title:`Confidentialité et performances`,description:`Toute l'inférence s'exécute sur le backend configuré (gpu.garden ou local). Aucune clé API cloud requise.`},gpuGarden:{title:`Intégration GPU Garden`,description:`Optimisé pour l'infrastructure gpu.garden avec routage automatique du proxy CORS.`}},howTo:{title:`Mode d'emploi`,step1:`Téléversez une image ou glissez-déposez-la sur la zone.`,step2:`Sélectionnez un modèle de tagging — la liste est chargée depuis le backend.`,step3:`Ajustez les seuils de confiance pour filtrer les tags.`,step4:`Cliquez sur <strong>Interroger</strong>.`,step5:`Copiez les tags ou téléchargez un PNG <strong>NAI Ready</strong>.`},madeBy:`Créé par`},l={label:`Sélection du thème`,light:`Mode clair`,auto:`Auto (système)`,dark:`Mode sombre`},u={app:e,common:t,header:n,upload:r,results:i,status:a,settings:o,errors:s,info:c,theme:l};export{e as app,t as common,u as default,s as errors,n as header,c as info,i as results,o as settings,a as status,l as theme,r as upload};
|
dist/assets/hi-cTTX2Ggg.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
var e={title:`Farterrogator`,subtitle:`AI इमेज एनालाइज़र`,copyright:`Farterrogator © {{year}} Fartcore. सर्वाधिकार सुरक्षित। मॉडल Fartcore की संपत्ति नहीं हैं और निःशुल्क प्रदान किए जाते हैं।`,logoAlt:`Farterrogator लोगो`,modelsNotice:`नया: अब कई टैगर मॉडल उपलब्ध हैं! सेटिंग्स में से कोई एक चुनें।`,madeBy:`<mooshieblob>mooshieblob</mooshieblob> और <ashtaka>ashtaka</ashtaka> द्वारा निर्मित`},t={close:`बंद करें`,changeLanguage:`भाषा बदलें`,languageSelection:`भाषा चयन`},n={whatIsThis:`यह क्या है?`,poweredBy:`मॉडल: {{model}}`,nothingYet:`कोई नहीं`},r={inputImage:`इनपुट इमेज`,dragDrop:`इमेज को यहाँ खींचकर छोड़ें, या चुनने के लिए क्लिक करें`,dropHere:`फ़ाइलें यहाँ छोड़ें`,supports:`PNG, JPG, WEBP, GIF समर्थित`,supportsArchives:`(+ ZIP, TAR)`,clear:`इमेज हटाएँ`,interrogate:`विश्लेषण करें`,previewAlt:`अपलोड की गई इमेज का पूर्वावलोकन`,filesSelected:`{{num}} फ़ाइलें चुनी गईं`,batchReady:`बैच प्रोसेसिंग के लिए तैयार`},i={title:`विश्लेषण परिणाम`,ready:`विश्लेषण के लिए तैयार`,readySub:`टैगिंग शुरू करने के लिए एक इमेज अपलोड करें`,failed:`विश्लेषण विफल`,troubleshoot:`समस्या निवारण:`,troubleshootTagger:`सुनिश्चित करें कि टैगर {{endpoint}} पर उपलब्ध है`,processing:`प्रोसेस हो रहा है...`,analyzing:`विश्लेषण हो रहा है...`,technicalTags:`टैग`,noTags:`वर्तमान थ्रेशोल्ड पर कोई टैग नहीं मिला।`,copyAll:`सभी कॉपी करें`,copied:`कॉपी हो गया!`,copiedItem:`कॉपी किया गया: {{item}}`,naiReady:`NAI Ready`,downloadNai:`टैग सहित डाउनलोड करें`,tagsCopied:`सभी टैग क्लिपबोर्ड पर कॉपी हो गए!`,embedFailed:`NAI Ready इमेज बनाने में विफल।`,score:`स्कोर`,batchResults:`बैच परिणाम`,artistSimilarity:`कलाकार समानता`,matchingArtists:`कलाकार शैलियों का मिलान हो रहा है...`,copyArtist:`कलाकार का नाम कॉपी करें`,noPreview:`कोई पूर्वावलोकन नहीं`,openOnDanbooru:`Danbooru पर खोलें`,openArtistOnDanbooru:`{{artist}} को Danbooru पर खोलें`},a={starting:`शुरू हो रहा है...`,analyzingImage:`छवि का विश्लेषण हो रहा है...`,done:`पूर्ण`},o={title:`सेटिंग्स`,thresholds:`थ्रेशोल्ड`,outputSettings:`आउटपुट`,topK:`शीर्ष K टैग`,randomize:`क्रम यादृच्छिक करें`,removeUnderscores:`अंडरस्कोर हटाएँ`,scoreDescend:`स्कोर के अनुसार क्रमबद्ध करें`,includeRanks:`टैग में स्कोर जोड़ें`,useEscape:`कोष्ठक एस्केप करें`,advancedThresholds:`उन्नत`,backend:{model:`टैगर मॉडल`,baseUrl:`API URL`,baseUrlHint:`API एंडपॉइंट URL, जैसे https://localtagger.gpu.garden या http://localhost:8000`,families:{wd14:`WD परिवार`,animetimm:`AnimeTimm`,camie:`Camie`},models:{},gatedHint:`सर्वर पर Hugging Face टोकन आवश्यक है।`,warmupHint:`मॉडल अभी लोड नहीं हुआ है — पहली रिक्वेस्ट में अधिक समय लग सकता है।`,onlineHint:`बैकएंड ऑनलाइन है।`,offlineHint:`बैकएंड तक नहीं पहुँचा जा सका। API URL जाँचें या सुनिश्चित करें कि सर्वर चल रहा है।`,resetToDefault:`डिफ़ॉल्ट पर रीसेट करें`},categories:{general:`सामान्य`,character:`पात्र`,copyright:`कॉपीराइट`,artist:`कलाकार`,meta:`मेटा`,rating:`रेटिंग`},maxTags:`अधिकतम टैग (0 = असीमित)`,whitelist:`टैग व्हाइटलिस्ट`,whitelistPlaceholder:`जैसे masterpiece, best quality`,blacklist:`टैग ब्लैकलिस्ट`,blacklistPlaceholder:`जैसे watermark, signature`},s={taggerRequired:`टैगर का बेस URL आवश्यक है। कृपया इसे बैकएंड सेटिंग्स में कॉन्फ़िगर करें।`,taggerError:`टैगर त्रुटि: {{status}} {{statusText}}`,batchTaggerError:`बैच टैगर त्रुटि: {{status}} {{statusText}}`,kaloscopeError:`Kaloscope त्रुटि: {{status}} {{statusText}}`,unknown:`एक अज्ञात त्रुटि हुई`},c={title:`Farterrogator क्या है?`,description:`<strong>Farterrogator</strong> एक तेज़, लोकल Booru-शैली इमेज टैगर है। यह डेटासेट निर्माण और प्रॉम्प्ट इंजीनियरिंग के लिए WD EVA 02-परिवार और इलस्ट्रेशन-केंद्रित मॉडलों से इमेज का विश्लेषण करके Danbooru-संगत टैग निकालता है।`,features:{models:{title:`कई टैगर मॉडल`,description:`<strong>WD SwinV2</strong>, <strong>WD EVA02</strong>, <strong>AnimeTimm</strong> और <strong>Camie</strong> मॉडलों में से चुनें — साथ ही Kaloscope कलाकार शैली समानता।`},naiReady:{title:`NAI Ready एम्बेडिंग`,description:`जनरेट किए गए टैग स्वचालित रूप से PNG मेटाडेटा में एम्बेड होते हैं। परिणामी इमेज "NAI Ready" होती हैं — बस उन्हें NovelAI में खींचें और प्रॉम्प्ट अपने आप भर जाएँगे।`},privacy:{title:`गोपनीयता और प्रदर्शन`,description:`सारा इन्फ़रेंस कॉन्फ़िगर किए गए बैकएंड (gpu.garden या लोकल) पर चलता है। किसी क्लाउड API कुंजी की आवश्यकता नहीं।`},gpuGarden:{title:`GPU Garden एकीकरण`,description:`स्वचालित CORS प्रॉक्सी रूटिंग के साथ gpu.garden इन्फ्रास्ट्रक्चर के लिए अनुकूलित।`}},howTo:{title:`उपयोग कैसे करें`,step1:`इमेज अपलोड करें या उसे कैनवास पर खींचकर छोड़ें।`,step2:`टैगर मॉडल चुनें — सूची बैकएंड से लोड होती है।`,step3:`टैग फ़िल्टर करने के लिए विश्वास थ्रेशोल्ड समायोजित करें।`,step4:`<strong>विश्लेषण करें</strong> पर क्लिक करें।`,step5:`टैग कॉपी करें, या <strong>NAI Ready</strong> PNG डाउनलोड करें।`},madeBy:`निर्माता`},l={label:`थीम चयन`,light:`लाइट मोड`,auto:`सिस्टम स्वचालित`,dark:`डार्क मोड`},u={app:e,common:t,header:n,upload:r,results:i,status:a,settings:o,errors:s,info:c,theme:l};export{e as app,t as common,u as default,s as errors,n as header,c as info,i as results,o as settings,a as status,l as theme,r as upload};
|
dist/assets/index-BPgEO71u.css
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
dist/assets/index-BQRSZhA2.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as e}from"./rolldown-runtime-BHe-jwch.js";import{$ as t,A as n,B as r,C as i,D as a,E as o,F as s,G as c,H as l,I as u,J as d,K as f,L as p,M as m,N as h,O as g,P as _,Q as v,R as y,S as b,T as x,U as S,V as C,W as w,X as T,Y as E,Z as D,_ as O,a as k,b as A,c as j,d as M,et as N,f as P,g as F,h as I,i as L,j as R,k as ee,l as z,m as B,n as V,nt as te,o as ne,p as re,q as H,r as ie,s as ae,t as oe,tt as se,u as ce,v as le,w as ue,x as de,y as fe,z as pe}from"./vendor-_ab0A6TJ.js";import{n as me,t as he}from"./vendor-files-BrsAlTsV.js";(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var U=e(te(),1),ge=e(N(),1),_e=(e,t,n)=>{let r=t.lastIndexOf(`?`),i=e[r===-1||r<t.lastIndexOf(`/`)?t:t.slice(0,r)];return i?typeof i==`function`?i():Promise.resolve(i):new Promise((e,r)=>{(typeof queueMicrotask==`function`?queueMicrotask:setTimeout)(r.bind(null,Error(`Unknown variable dynamic import: `+t+(t.split(`/`).length===n?``:`. Note that variables only represent file names one level deep.`))))})},ve=`modulepreload`,ye=function(e){return`/`+e},be={},W=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}r=o(t.map(t=>{if(t=ye(t,n),t in be)return;be[t]=!0;let r=t.endsWith(`.css`),i=r?`[rel="stylesheet"]`:``;if(n)for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}else if(document.querySelector(`link[href="${t}"]${i}`))return;let o=document.createElement(`link`);if(o.rel=r?`stylesheet`:ve,r||(o.as=`script`),o.crossOrigin=``,o.href=t,a&&o.setAttribute(`nonce`,a),document.head.appendChild(o),r)return new Promise((e,n)=>{o.addEventListener(`load`,e),o.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})};t.use(E).use(v).use({type:`backend`,read:(e,t,n)=>{_e(Object.assign({"./locales/de.json":()=>W(()=>import(`./de-k3hfbLj-.js`),[]),"./locales/en.json":()=>W(()=>import(`./en-FHVuPOw2.js`),[]),"./locales/es.json":()=>W(()=>import(`./es-DNkSzkRz.js`),[]),"./locales/fr.json":()=>W(()=>import(`./fr-Ds8MV9-S.js`),[]),"./locales/hi.json":()=>W(()=>import(`./hi-cTTX2Ggg.js`),[]),"./locales/it.json":()=>W(()=>import(`./it-CJ48uQvE.js`),[]),"./locales/ja.json":()=>W(()=>import(`./ja-Bu_r5epl.js`),[]),"./locales/ko.json":()=>W(()=>import(`./ko-Ccvowmxl.js`),[]),"./locales/pt.json":()=>W(()=>import(`./pt-BpqmNNtz.js`),[]),"./locales/ru.json":()=>W(()=>import(`./ru-CbpyFmXE.js`),[]),"./locales/zh-CN.json":()=>W(()=>import(`./zh-CN-juOm4LJT.js`),[]),"./locales/zh-TW.json":()=>W(()=>import(`./zh-TW-DcQy6Mhc.js`),[])}),`./locales/${e}.json`,3).then(e=>{n(null,e.default||e)}).catch(e=>{n(e,null)})}}).init({fallbackLng:`en`,interpolation:{escapeValue:!1},detection:{order:[`querystring`,`cookie`,`localStorage`,`navigator`,`htmlTag`],caches:[`localStorage`,`cookie`]}});var G=oe(),xe=[{value:`light`,icon:(0,G.jsx)(ce,{className:`w-4 h-4`,"aria-hidden":`true`}),labelKey:`theme.light`},{value:`auto`,icon:(0,G.jsx)(fe,{className:`w-4 h-4`,"aria-hidden":`true`}),labelKey:`theme.auto`},{value:`dark`,icon:(0,G.jsx)(le,{className:`w-4 h-4`,"aria-hidden":`true`}),labelKey:`theme.dark`}],Se=({theme:e,setTheme:t})=>{let{t:n}=T();return(0,G.jsx)(`div`,{className:`flex items-center gap-0.5 p-1 rounded-full bg-md-light-surface-3 dark:bg-md-dark-surface-3`,role:`group`,"aria-label":n(`theme.label`),children:xe.map(r=>(0,G.jsx)(`button`,{onClick:()=>t(r.value),className:`w-8 h-8 flex items-center justify-center rounded-full transition-all ${e===r.value?`bg-md-light-primary-container dark:bg-md-dark-primary-container text-md-light-on-primary-container dark:text-md-dark-on-primary-container shadow-sm`:`text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant hover:text-md-light-on-surface dark:hover:text-md-dark-on-surface`}`,title:n(r.labelKey),"aria-label":n(r.labelKey),"aria-pressed":e===r.value,children:r.icon},r.value))})},Ce=()=>{let{t:e,i18n:t}=T(),[n,r]=(0,U.useState)(!1),i=(0,U.useRef)(null);(0,U.useEffect)(()=>{let e=e=>{i.current&&!i.current.contains(e.target)&&r(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[]);let a=e=>{t.changeLanguage(e),r(!1)},o=[{code:`en`,label:`English`},{code:`es`,label:`Español`},{code:`divider`,label:``},{code:`de`,label:`Deutsch`},{code:`zh-TW`,label:`繁體中文`},{code:`fr`,label:`Français`},{code:`ko`,label:`한국어`},{code:`hi`,label:`हिन्दी`},{code:`it`,label:`Italiano`},{code:`zh-CN`,label:`简体中文`},{code:`ja`,label:`日本語`},{code:`pt`,label:`Português`},{code:`ru`,label:`Русский`}],s=t.language||`en`,c=s.startsWith(`zh`)?s:s.split(`-`)[0];return(0,G.jsxs)(`div`,{className:`relative`,ref:i,children:[(0,G.jsxs)(f,{clear:!0,rounded:!0,onClick:()=>r(!n),className:`flex items-center gap-2 px-3 py-1.5 text-sm font-medium uppercase ${n?`bg-md-light-primary/10 dark:bg-md-dark-primary/10 text-md-light-primary dark:text-md-dark-primary`:`text-stone-600 dark:text-stone-300`}`,title:e(`common.changeLanguage`),"aria-label":e(`common.changeLanguage`),"aria-haspopup":`true`,"aria-expanded":n,children:[(0,G.jsx)(ue,{className:`w-4 h-4`,"aria-hidden":`true`}),c]}),n&&(0,G.jsx)(`div`,{className:`absolute right-0 top-full mt-2 w-36 bg-md-light-surface-2 dark:bg-md-dark-surface-2 rounded-xl overflow-hidden z-50 animate-in fade-in zoom-in-95 duration-100`,role:`menu`,"aria-orientation":`vertical`,"aria-label":e(`common.languageSelection`),children:o.map(e=>e.code===`divider`?(0,G.jsx)(`div`,{className:`h-px bg-stone-200 dark:bg-stone-700 my-1 mx-2`,role:`separator`},`divider`):(0,G.jsxs)(`button`,{onClick:()=>a(e.code),className:`w-full text-left px-4 py-2.5 text-sm flex items-center justify-between transition-colors ${s===e.code?`font-medium bg-md-light-primary/10 dark:bg-md-dark-primary/10 text-md-light-primary dark:text-md-dark-primary`:`text-stone-600 dark:text-stone-400 hover:bg-md-light-surface-4 dark:hover:bg-md-dark-surface-4`}`,role:`menuitem`,"aria-current":s===e.code?`true`:void 0,children:[e.label,s===e.code&&(0,G.jsx)(_,{className:`w-3.5 h-3.5`,"aria-hidden":`true`})]},e.code))})]})},we=({theme:e,setTheme:t})=>{let{t:n}=T();return(0,G.jsx)(l,{transparent:!0,className:`top-0 sticky backdrop-blur-md`,innerClassName:`overflow-visible!`,bgClassName:`bg-md-light-surface-2/80 dark:bg-md-dark-surface-2/80`,left:(0,G.jsxs)(`div`,{className:`flex items-center gap-2.5 pl-2`,children:[(0,G.jsx)(`img`,{src:`/favicon.webp`,alt:n(`app.logoAlt`),className:`w-8 h-8 object-contain drop-shadow-sm`}),(0,G.jsxs)(`h1`,{className:`text-lg font-bold leading-tight tracking-tight text-md-light-on-surface dark:text-md-dark-on-surface`,children:[n(`app.title`).substring(0,4),(0,G.jsx)(`span`,{className:`text-primary dark:text-md-dark-primary`,children:n(`app.title`).substring(4)})]})]}),right:(0,G.jsxs)(`div`,{className:`flex items-center gap-1.5 pr-2`,children:[(0,G.jsx)(Ce,{}),(0,G.jsx)(Se,{theme:e,setTheme:t})]})})},Te=e(me(),1),Ee=e(he(),1),De=/\.(png|jpg|jpeg|webp|gif)$/i,Oe={png:`image/png`,jpg:`image/jpeg`,jpeg:`image/jpeg`,webp:`image/webp`,gif:`image/gif`},ke=e=>Oe[e.split(`.`).pop()?.toLowerCase()??``]??``;async function Ae(e,t,n){let r=Array(e.length).fill(null),i=0,a=Array.from({length:Math.min(t,e.length)},async()=>{for(;i<e.length;){let t=i++;try{r[t]=await n(e[t])}catch{r[t]=null}}});return await Promise.all(a),r.filter(e=>e!==null)}var je=({onFilesSelect:e,selectedFiles:t,onClear:n})=>{let{t:r}=T(),[i,a]=(0,U.useState)(null),[o,s]=(0,U.useState)(!1),[c,l]=(0,U.useState)(!1);(0,U.useEffect)(()=>(t.length===1&&!i&&a(URL.createObjectURL(t[0])),()=>{i&&URL.revokeObjectURL(i)}),[t,i]);let u=async e=>{let t=10*1024*1024;return e.size<=t?e:new Promise((n,r)=>{let i=new Image;i.src=URL.createObjectURL(e),i.onload=async()=>{URL.revokeObjectURL(i.src);let a=Math.min(1,Math.sqrt(t/e.size)*.95),o=null,s=document.createElement(`canvas`);for(let c=0;c<10;c++){let c=Math.max(1,Math.floor(i.width*a)),l=Math.max(1,Math.floor(i.height*a));s.width=c,s.height=l;let u=s.getContext(`2d`);if(!u){r(Error(`Canvas context failed`));return}u.imageSmoothingEnabled=!0,u.imageSmoothingQuality=`high`,u.drawImage(i,0,0,c,l);let d=e.type===`image/png`?`image/png`:`image/jpeg`;if(o=await new Promise(e=>s.toBlob(e,d,.9)),o&&o.size<=t){n(new File([o],e.name,{type:d}));return}a*=.85}n(o?new File([o],e.name,{type:e.type}):e)},i.onerror=r})},d=(0,U.useCallback)(async t=>{l(!0);let n=[];try{for(let e of t)if(e.name.toLowerCase().endsWith(`.zip`))try{let t=await new Te.default().loadAsync(e),r=await Ae(Object.values(t.files).filter(e=>!e.dir&&De.test(e.name)),4,async e=>{let t=await e.async(`blob`),n=t.type||ke(e.name);return u(new File([t],e.name,{type:n}))});n.push(...r)}catch(t){console.error(`Failed to unzip file:`,e.name,t)}else if(e.name.toLowerCase().endsWith(`.tar`))try{let t=await Ae((await(0,Ee.default)(await e.arrayBuffer())).filter(e=>De.test(e.name)),4,async e=>{let t=new Blob([e.buffer]),n=t.type||ke(e.name);return u(new File([t],e.name,{type:n}))});n.push(...t)}catch(t){console.error(`Failed to untar file:`,e.name,t)}else if(e.type.startsWith(`image/`)){let t=await u(e);n.push(t)}n.length>0&&(e(n),n.length===1?a(URL.createObjectURL(n[0])):a(null))}catch(e){console.error(`Error processing files:`,e)}finally{l(!1)}},[e]),f=e=>{e.target.files&&e.target.files.length>0&&d(Array.from(e.target.files))};(0,U.useEffect)(()=>{let e=e=>{e.clipboardData&&e.clipboardData.files.length>0&&d(Array.from(e.clipboardData.files))};return window.addEventListener(`paste`,e),()=>window.removeEventListener(`paste`,e)},[d]);let p=(0,U.useCallback)(e=>{e.preventDefault(),s(!0)},[]),m=(0,U.useCallback)(e=>{e.preventDefault(),s(!1)},[]),h=(0,U.useCallback)(e=>{e.preventDefault(),s(!1),e.dataTransfer.files&&e.dataTransfer.files.length>0&&d(Array.from(e.dataTransfer.files))},[d]);return t.length>0?(0,G.jsxs)(`div`,{className:`relative group w-fit mx-auto bg-md-light-surface-1 dark:bg-md-dark-surface-1 rounded-[28px] overflow-hidden transition-colors duration-300 shadow-sm`,children:[t.length===1&&i?(0,G.jsx)(`img`,{src:i,alt:r(`upload.previewAlt`),className:`max-w-full max-h-[600px] w-auto h-auto block`}):(0,G.jsxs)(`div`,{className:`p-12 flex flex-col items-center justify-center gap-4 text-md-light-on-surface dark:text-md-dark-on-surface`,children:[(0,G.jsx)(g,{className:`w-16 h-16 text-amber-500`}),(0,G.jsxs)(`div`,{className:`text-center`,children:[(0,G.jsx)(`p`,{className:`text-lg font-semibold`,children:r(`upload.filesSelected`,{num:t.length})}),(0,G.jsx)(`p`,{className:`text-sm text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant`,children:r(`upload.batchReady`)})]})]}),(0,G.jsx)(`div`,{className:`absolute inset-0 bg-black/0 group-hover:bg-black/10 transition-colors duration-300`,"aria-hidden":`true`}),(0,G.jsx)(`button`,{onClick:()=>{a(null),n()},className:`absolute top-4 right-4 p-2 bg-md-light-surface/90 dark:bg-md-dark-surface/80 text-md-light-on-surface dark:text-md-dark-on-surface rounded-full hover:bg-red-50 hover:text-red-500 dark:hover:bg-red-500/20 dark:hover:text-red-400 transition-colors backdrop-blur-sm shadow-md opacity-100 duration-200`,title:r(`upload.clear`),"aria-label":r(`upload.clear`),children:(0,G.jsx)(V,{className:`w-5 h-5`,"aria-hidden":`true`})}),c&&(0,G.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center bg-black/50 backdrop-blur-sm z-20`,role:`status`,"aria-live":`polite`,children:(0,G.jsxs)(`div`,{className:`flex flex-col items-center gap-2 text-white`,children:[(0,G.jsx)(de,{className:`w-8 h-8 animate-spin`,"aria-hidden":`true`}),(0,G.jsx)(`span`,{className:`text-sm font-medium`,children:r(`results.processing`)})]})})]}):(0,G.jsxs)(`div`,{className:`
|
| 2 |
+
relative w-full h-[400px] rounded-[28px] border-2 border-dashed transition-all duration-200 flex flex-col items-center justify-center gap-4
|
| 3 |
+
${o?`border-md-light-primary dark:border-md-dark-primary bg-md-light-primary-container/40 dark:bg-md-dark-primary-container/30`:`border-md-light-outline-variant dark:border-md-dark-outline-variant bg-md-light-surface-1 dark:bg-md-dark-surface-1 hover:bg-md-light-surface-2 dark:hover:bg-md-dark-surface-2 hover:border-md-light-outline dark:hover:border-md-dark-outline`}
|
| 4 |
+
`,onDragOver:p,onDragLeave:m,onDrop:h,role:`button`,tabIndex:0,"aria-label":r(`upload.dragDrop`),onKeyDown:e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),document.querySelector(`input[type="file"]`)?.click())},children:[(0,G.jsx)(`input`,{type:`file`,accept:`image/png, image/jpeg, image/webp, image/gif, application/zip, application/x-zip-compressed, application/x-tar`,multiple:!0,onChange:f,className:`absolute inset-0 w-full h-full opacity-0 cursor-pointer z-10`,disabled:c,title:r(`upload.dragDrop`),"aria-label":r(`upload.dragDrop`),tabIndex:-1}),(0,G.jsx)(`div`,{className:`p-5 rounded-full bg-md-light-primary-container dark:bg-md-dark-primary-container transition-colors duration-300`,"aria-hidden":`true`,children:c?(0,G.jsx)(de,{className:`w-8 h-8 animate-spin text-amber-500`}):(0,G.jsx)(ae,{className:`w-8 h-8 ${o?`text-md-light-primary dark:text-md-dark-primary`:`text-md-light-on-primary-container dark:text-md-dark-on-primary-container`}`})}),(0,G.jsxs)(`div`,{className:`text-center space-y-1 pointer-events-none`,children:[(0,G.jsx)(`p`,{className:`text-sm font-medium text-md-light-on-surface dark:text-md-dark-on-surface`,children:r(o?`upload.dropHere`:`upload.dragDrop`)}),(0,G.jsxs)(`p`,{className:`text-xs text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant`,children:[r(`upload.supports`),` `,(0,G.jsx)(`span`,{className:`opacity-70`,children:r(`upload.supportsArchives`)})]})]})]})},Me=({settings:e,backendConfig:t,models:n,health:r,onSettingsChange:i,onBackendChange:a,disabled:o})=>{let{t:s}=T(),l=(0,U.useMemo)(()=>{let e=new Map;return(n??[]).forEach(t=>{let n=e.get(t.family)??[];n.push(t),e.set(t.family,n)}),[...e.entries()]},[n]),u=n?.find(e=>e.id===t.taggerModel),d=r=>{a({...t,taggerModel:r});let o=n?.find(e=>e.id===r);o&&i({...e,thresholds:{...e.thresholds,general:o.default_threshold,character:o.default_character_threshold}})};return(0,G.jsxs)(`div`,{children:[(0,G.jsx)(H,{className:`mt-0! mb-2!`,children:s(`settings.backend.model`)}),(0,G.jsxs)(c,{strong:!0,inset:!0,className:`my-0!`,children:[(0,G.jsx)(S,{label:s(`settings.backend.model`),type:`select`,dropdown:!0,media:(0,G.jsx)(B,{className:`w-5 h-5`,"aria-hidden":`true`}),value:t.taggerModel,disabled:o,onChange:e=>d(e.target.value),children:n?l.map(([e,t])=>(0,G.jsx)(`optgroup`,{label:s(`settings.backend.families.${e}`,{defaultValue:e}),children:t.map(e=>(0,G.jsxs)(`option`,{value:e.id,children:[e.recommended?`★ `:``,e.label,` —`,` `,s(`settings.backend.models.${e.id}`,{defaultValue:e.description}),e.gated?` 🔒`:``]},e.id))},e)):(0,G.jsx)(`option`,{value:t.taggerModel,children:t.taggerModel})}),(0,G.jsx)(S,{label:s(`settings.backend.baseUrl`),type:`url`,media:(0,G.jsx)(b,{className:`w-5 h-5`,"aria-hidden":`true`}),value:t.taggerBaseUrl,placeholder:`https://localtagger.gpu.garden`,disabled:o,inputClassName:`font-mono text-xs`,onChange:e=>a({...t,taggerBaseUrl:e.target.value})})]}),r===`down`&&(0,G.jsxs)(`p`,{className:`flex items-center gap-1.5 px-4 pt-1.5 text-xs text-rose-600 dark:text-rose-400`,children:[(0,G.jsx)(L,{className:`w-3 h-3 shrink-0`,"aria-hidden":`true`}),s(`settings.backend.offlineHint`)]}),r===`ok`&&(0,G.jsxs)(`p`,{className:`flex items-center gap-1.5 px-4 pt-1.5 text-xs text-green-600 dark:text-green-400`,children:[(0,G.jsx)(ie,{className:`w-3 h-3 shrink-0`,"aria-hidden":`true`}),s(`settings.backend.onlineHint`)]}),u?.gated&&(0,G.jsxs)(`p`,{className:`flex items-center gap-1.5 px-4 pt-1.5 text-xs text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant`,children:[(0,G.jsx)(A,{className:`w-3 h-3 shrink-0`,"aria-hidden":`true`}),s(`settings.backend.gatedHint`)]}),u&&!u.loaded&&(0,G.jsxs)(`p`,{className:`flex items-center gap-1.5 px-4 pt-1.5 text-xs text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant`,children:[(0,G.jsx)(x,{className:`w-3 h-3 shrink-0`,"aria-hidden":`true`}),s(`settings.backend.warmupHint`)]}),(0,G.jsx)(`div`,{className:`flex justify-end px-4 pt-1`,children:(0,G.jsxs)(`button`,{type:`button`,onClick:()=>a({...t,taggerBaseUrl:`https://localtagger.gpu.garden`}),disabled:o||t.taggerBaseUrl===`https://localtagger.gpu.garden`,className:`flex items-center gap-1 text-xs text-primary dark:text-md-dark-primary hover:underline disabled:opacity-30 disabled:no-underline disabled:cursor-default transition-opacity`,children:[(0,G.jsx)(I,{className:`w-3 h-3`,"aria-hidden":`true`}),s(`settings.backend.resetToDefault`)]})})]})},Ne=({settings:e,onSettingsChange:t,disabled:n})=>{let{t:r}=T(),[l,d]=(0,U.useState)(!1),f=(n,r)=>{t({...e,thresholds:{...e.thresholds,[n]:r}})},p=n=>{t({...e,thresholds:{general:n,character:n,copyright:n,artist:n,meta:n,rating:.8}})},m=[{id:`copyright`,label:r(`settings.categories.copyright`),icon:(0,G.jsx)(a,{className:`w-4 h-4`,"aria-hidden":`true`}),color:`text-purple-600 dark:text-purple-400`},{id:`character`,label:r(`settings.categories.character`),icon:(0,G.jsx)(ne,{className:`w-4 h-4`,"aria-hidden":`true`}),color:`text-green-600 dark:text-green-400`},{id:`artist`,label:r(`settings.categories.artist`),icon:(0,G.jsx)(O,{className:`w-4 h-4`,"aria-hidden":`true`}),color:`text-amber-600 dark:text-amber-400`},{id:`general`,label:r(`settings.categories.general`),icon:(0,G.jsx)(i,{className:`w-4 h-4`,"aria-hidden":`true`}),color:`text-blue-600 dark:text-blue-400`},{id:`meta`,label:r(`settings.categories.meta`),icon:(0,G.jsx)(R,{className:`w-4 h-4`,"aria-hidden":`true`}),color:`text-slate-600 dark:text-slate-400`},{id:`rating`,label:r(`settings.categories.rating`),icon:(0,G.jsx)(re,{className:`w-4 h-4`,"aria-hidden":`true`}),color:`text-rose-600 dark:text-rose-400`}],h=(e,t,r,i,a,o,s)=>(0,G.jsxs)(`div`,{className:`flex w-full flex-col gap-1`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between text-sm`,children:[e,(0,G.jsx)(`span`,{className:`font-mono text-xs text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant`,children:r})]}),(0,G.jsx)(y,{value:t,min:a,max:o,step:s,disabled:n,onInput:e=>i(parseFloat(e.target.value))})]});return(0,G.jsxs)(`div`,{children:[(0,G.jsx)(H,{className:`mt-0! mb-2!`,children:r(`settings.outputSettings`)}),(0,G.jsxs)(c,{strong:!0,inset:!0,className:`my-0!`,children:[(0,G.jsx)(w,{innerChildren:h((0,G.jsx)(`span`,{children:r(`settings.topK`)}),e.topK,String(e.topK),n=>t({...e,topK:n}),10,100,5)}),(0,G.jsx)(w,{innerChildren:h((0,G.jsx)(`span`,{children:r(`settings.maxTags`)}),e.maxTags||0,String(e.maxTags||0),n=>t({...e,maxTags:n}),0,100,5)}),(0,G.jsx)(S,{label:r(`settings.whitelist`),type:`text`,value:e.whitelist||``,placeholder:r(`settings.whitelistPlaceholder`),disabled:n,onChange:n=>t({...e,whitelist:n.target.value})}),(0,G.jsx)(S,{label:r(`settings.blacklist`),type:`text`,value:e.blacklist||``,placeholder:r(`settings.blacklistPlaceholder`),disabled:n,onChange:n=>t({...e,blacklist:n.target.value})}),(0,G.jsx)(w,{label:!0,title:r(`settings.randomize`),media:(0,G.jsx)(P,{className:`w-5 h-5 ${e.randomize?`text-primary dark:text-md-dark-primary`:`opacity-50`}`,"aria-hidden":`true`}),after:(0,G.jsx)(u,{checked:e.randomize,disabled:n,onChange:()=>t({...e,randomize:!e.randomize})})}),(0,G.jsx)(w,{label:!0,title:r(`settings.removeUnderscores`),media:(0,G.jsx)(j,{className:`w-5 h-5 ${e.removeUnderscores?`text-primary dark:text-md-dark-primary`:`opacity-50`}`,"aria-hidden":`true`}),after:(0,G.jsx)(u,{checked:e.removeUnderscores,disabled:n,onChange:()=>t({...e,removeUnderscores:!e.removeUnderscores})})}),(0,G.jsx)(w,{label:!0,title:r(`settings.scoreDescend`),media:(0,G.jsx)(s,{className:`w-5 h-5 ${e.scoreDescend?`text-primary dark:text-md-dark-primary`:`opacity-50`}`,"aria-hidden":`true`}),after:(0,G.jsx)(u,{checked:e.scoreDescend,disabled:n,onChange:()=>t({...e,scoreDescend:!e.scoreDescend})})}),(0,G.jsx)(w,{label:!0,title:r(`settings.includeRanks`),media:(0,G.jsx)(o,{className:`w-5 h-5 ${e.includeRanks?`text-primary dark:text-md-dark-primary`:`opacity-50`}`,"aria-hidden":`true`}),after:(0,G.jsx)(u,{checked:e.includeRanks,disabled:n,onChange:()=>t({...e,includeRanks:!e.includeRanks})})}),(0,G.jsx)(w,{label:!0,title:r(`settings.useEscape`),media:(0,G.jsx)(F,{className:`w-5 h-5 ${e.useEscape?`text-primary dark:text-md-dark-primary`:`opacity-50`}`,"aria-hidden":`true`}),after:(0,G.jsx)(u,{checked:e.useEscape,disabled:n,onChange:()=>t({...e,useEscape:!e.useEscape})})})]}),(0,G.jsx)(H,{className:`mt-6! mb-2!`,children:r(`settings.thresholds`)}),(0,G.jsxs)(c,{strong:!0,inset:!0,className:`my-0!`,children:[(0,G.jsx)(w,{label:!0,title:r(`settings.advancedThresholds`),media:(0,G.jsx)(i,{className:`w-5 h-5 ${l?`text-primary dark:text-md-dark-primary`:`opacity-50`}`,"aria-hidden":`true`}),after:(0,G.jsx)(u,{checked:l,disabled:n,onChange:()=>d(!l)})}),l?m.map(t=>(0,G.jsx)(w,{innerChildren:h((0,G.jsxs)(`span`,{className:`flex items-center gap-1.5 font-medium ${t.color}`,children:[t.icon,t.label]}),e.thresholds[t.id],e.thresholds[t.id].toFixed(2),e=>f(t.id,e),0,.95,.05)},t.id)):(0,G.jsx)(w,{innerChildren:h((0,G.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,G.jsx)(i,{className:`w-4 h-4`,"aria-hidden":`true`}),r(`settings.categories.general`)]}),e.thresholds.general,e.thresholds.general.toFixed(2),p,0,.95,.05)})]})]})},K=se(),Pe=new Uint32Array(256);for(let e=0;e<256;e++){let t=e;for(let e=0;e<8;e++)t&1?t=3988292384^t>>>1:t>>>=1;Pe[e]=t}var Fe=e=>{let t=4294967295;for(let n=0;n<e.length;n++)t=Pe[(t^e[n])&255]^t>>>8;return t^4294967295},Ie=async(e,t)=>{let n=await(await Le(e)).arrayBuffer(),r=new Uint8Array(n),i=new Uint8Array([137,80,78,71,13,10,26,10]);for(let e=0;e<8;e++)if(r[e]!==i[e])throw Error(`Failed to process PNG data`);let a=[],o=8,s=(e,t)=>{let n=t.length,r=new Uint8Array(8+n+4),i=new DataView(r.buffer);i.setUint32(0,n,!1);for(let t=0;t<4;t++)r[4+t]=e.charCodeAt(t);r.set(t,8);let a=Fe(r.subarray(4,8+n));return i.setUint32(8+n,a,!1),r},c=new TextEncoder,l=(e,t)=>{let n=c.encode(e),r=c.encode(t),i=new Uint8Array(n.length+1+r.length);return i.set(n,0),i[n.length]=0,i.set(r,n.length+1),s(`tEXt`,i)},u=[l(`Software`,`NovelAI`),l(`Source`,`NovelAI`),l(`Description`,t),l(`Comment`,JSON.stringify({prompt:t}))];a.push(r.subarray(0,8));let d=new DataView(n);for(;o<r.length;){let e=d.getUint32(o,!1),t=String.fromCharCode(r[o+4],r[o+5],r[o+6],r[o+7]),n=e+12,i=r.subarray(o,o+n);a.push(i),o+=n,t===`IHDR`&&a.push(...u)}let f=a.reduce((e,t)=>e+t.length,0),p=new Uint8Array(f),m=0;for(let e of a)p.set(e,m),m+=e.length;return new Blob([p],{type:`image/png`})},Le=e=>new Promise((t,n)=>{let r=new Image;r.onload=()=>{let e=r.width,i=r.height,a=e*i,o=Math.sqrt(1048576/a);e=Math.round(e*o),i=Math.round(i*o);let s=document.createElement(`canvas`);s.width=e,s.height=i;let c=s.getContext(`2d`);if(!c){n(Error(`Could not get canvas context`));return}c.imageSmoothingEnabled=!0,c.imageSmoothingQuality=`high`,c.drawImage(r,0,0,e,i),s.toBlob(e=>{e?t(e):n(Error(`Canvas to Blob failed`))},`image/png`)},r.onerror=n,r.src=URL.createObjectURL(e)}),q=function(e){return e.IDLE=`IDLE`,e.ANALYZING=`ANALYZING`,e.SUCCESS=`SUCCESS`,e.ERROR=`ERROR`,e}({}),J=class extends Error{constructor(e,t){super(e),this.name=`I18nError`,this.key=e,this.params=t}},Y=new Map,X=null,Re={0:`general`,1:`artist`,3:`copyright`,4:`character`,5:`meta`,9:`rating`},ze=async()=>{let e=await fetch(`/danbooru_tags.csv`);if(!e.ok)throw Error(`Failed to load tag database: ${e.statusText}`);let t=(await e.text()).split(`
|
| 5 |
+
`);for(let e=0;e<t.length;e++){let n=t[e],r=n.indexOf(`,`);if(r<=0)continue;let i=n.slice(0,r),a=n.indexOf(`,`,r+1),o=parseInt(n.slice(r+1,a===-1?n.length:a),10);Number.isNaN(o)||Y.set(i,Re[o]||`general`)}console.log(`[TagService] Loaded ${Y.size} tags.`)},Be=()=>(X||=ze().catch(e=>{console.error(`[TagService] Error loading tag database:`,e),X=null}),X),Ve=new Set([`general`,`safe`,`questionable`,`explicit`,`sensitive`,`nsfw`]),He=new Set([`highres`,`absurdres`,`4k`,`8k`,`masterpiece`,`best quality`,`comic`,`monochrome`,`greyscale`,`lowres`,`bad quality`,`worst quality`]),Ue=e=>Y.get(e)||(e.startsWith(`rating:`)||Ve.has(e)?`rating`:He.has(e)?`meta`:`general`);function Z(e,t){let n=e.replace(/\/$/,``);return n.includes(`localtagger.gpu.garden`)?`/interrogate/gpu-garden${t}`:n.includes(`localhost`)||n.includes(`127.0.0.1`)?t:`${n}${t}`}function Q(e){return e.trim().toLowerCase().replace(/ /g,`_`)}function $(e){return new Set((e??``).split(`,`).map(Q).filter(Boolean))}var We=new Set([`blue_skin`,`colored_skin`]);function Ge(e){let t=[],n=Array.isArray(e)?e[0]:e,r=n?.tags,i=new Set(Object.keys(n?.character??{})),a=e=>i.has(e)?`character`:Ue(e);Array.isArray(r)?r.forEach(e=>{let n=``,r=0;Array.isArray(e)?(n=e[0],r=Number(e[1])):typeof e==`object`&&(n=e.name||e.tag,r=Number(e.score??e.confidence??e.probability??0)),n&&t.push({name:n,score:r>1?r/100:r,category:a(n)})}):r&&typeof r==`object`&&Object.entries(r).forEach(([e,n])=>{let r=Number(n);r>1&&(r/=100),t.push({name:e,score:r,category:a(e)})});let o=n?.rating;if(o&&typeof o==`object`){let e=new Set(t.map(e=>e.name));Object.entries(o).forEach(([n,r])=>{if(e.has(n))return;let i=Number(r);i>1&&(i/=100),t.push({name:n,score:i,category:`rating`})})}return t.filter(e=>!(We.has(e.name)&&e.score<.85))}function Ke(e,t){e.append(`use_escape`,String(t.useEscape)),e.append(`include_ranks`,String(t.includeRanks)),e.append(`score_descend`,String(t.scoreDescend))}var qe=async e=>{try{let t=await fetch(Z(e,`/health`));if(t.ok){let e=await t.json().catch(()=>null);return e?.status&&e.status!==`ok`?`down`:`ok`}return t.status>=400&&t.status<500?`unknown`:`down`}catch{return`down`}},Je=async e=>{let t=await fetch(Z(e,`/models`));if(!t.ok)throw new J(`errors.taggerError`,{status:t.status,statusText:t.statusText});let n=await t.json();return Array.isArray(n?.models)?n.models.filter(e=>e&&typeof e.id==`string`):[]},Ye=async(e,t,n)=>{let r=Z(t.taggerBaseUrl,`/interrogate`),i=new FormData;i.append(`file`,e);let a=new URLSearchParams;a.append(`model`,t.taggerModel),n?(a.append(`threshold`,n.thresholds.general.toString()),a.append(`character_threshold`,n.thresholds.character.toString()),Ke(a,n)):(a.append(`threshold`,`0.35`),a.append(`character_threshold`,`0.85`));let o=`${r}?${a}`,s=Be(),c=await fetch(o,{method:`POST`,body:i});if(!c.ok)throw new J(`errors.taggerError`,{status:c.status,statusText:c.statusText});let l=await c.json();await s;let u=Ge(l).sort((e,t)=>t.score-e.score);return n?.maxTags&&n.maxTags>0?u.slice(0,n.maxTags):u},Xe=async(e,t,n)=>{let r=Z(t.taggerBaseUrl,`/interrogate`),i=new FormData;e.forEach(e=>i.append(`file`,e));let a=new URLSearchParams;a.append(`output_format`,`zip`),a.append(`model`,t.taggerModel),n?(n.whitelist?.trim()&&a.append(`trigger_word`,n.whitelist.trim()),n.randomize&&a.append(`random_order`,`true`),n.removeUnderscores&&a.append(`use_spaces`,`true`),a.append(`threshold`,n.thresholds.general.toString()),a.append(`character_threshold`,n.thresholds.character.toString()),Ke(a,n)):(a.append(`threshold`,`0.35`),a.append(`character_threshold`,`0.85`));let o=`${r}?${a}`,s=await fetch(o,{method:`POST`,body:i});if(!s.ok)throw new J(`errors.batchTaggerError`,{status:s.status,statusText:s.statusText});let c=s.headers.get(`content-type`)??``;if(c.includes(`application/zip`)||c.includes(`application/octet-stream`)){let e=await s.blob(),t=window.URL.createObjectURL(e),n=document.createElement(`a`);return n.href=t,n.download=(s.headers.get(`content-disposition`)??``).match(/filename="?([^"]+)"?/)?.[1]??`batch_tags.zip`,document.body.appendChild(n),n.click(),window.URL.revokeObjectURL(t),document.body.removeChild(n),{}}let l=await s.json(),u=$(n?.blacklist),d=e=>e.map(([e,t])=>{let n=Number(t);return n>1&&(n/=100),{tag:e,score:n}}).filter(e=>!u.has(Q(e.tag)));if(Array.isArray(l)){let t={};return l.forEach((r,i)=>{let a=e[i]?.name??`image_${i}.png`;if(!r?.tags)return;let o=d(Object.entries(r.tags)).sort((e,t)=>t.score-e.score);n?.maxTags&&n.maxTags>0&&(o=o.slice(0,n.maxTags));let s={};o.forEach(e=>s[e.tag]=e.score),t[a]={tags:s,tag_string:o.map(e=>e.tag).join(`, `)}}),t}return l&&typeof l==`object`&&Object.keys(l).forEach(e=>{let t=l[e];if(!t?.tags)return;let r=d(Object.entries(t.tags)).sort((e,t)=>t.score-e.score);n?.maxTags&&n.maxTags>0&&(r=r.slice(0,n.maxTags));let i={};r.forEach(e=>i[e.tag]=e.score),t.tags=i,t.tag_string=r.map(e=>e.tag).join(`, `)}),l},Ze=async(e,t,n,r,i)=>{i?.(`status.analyzingImage`,20);let a=await Ye(e,t,n);return i?.(`status.done`,100),{tags:a}},Qe=({result:e,settings:t,taggerModel:s,loadingState:c,selectedFile:l,artistMatches:u,isMatchingArtists:d})=>{let{t:p}=T(),[h,g]=(0,U.useState)(!1),[v,y]=(0,U.useState)(!1),[b,x]=(0,U.useState)(null),[S,C]=(0,U.useState)(null),w=(0,U.useRef)(new Map),E=(0,U.useRef)(null),[D,k]=(0,U.useState)({});(0,U.useEffect)(()=>{if(!u||u.length===0)return;k({});let e=u.map(e=>e.name);fetch(`https://danbooru.donmai.us/tags.json?search[name_comma]=${encodeURIComponent(e.join(`,`))}&limit=${e.length}`).then(e=>e.json()).then(t=>{let n={};e.forEach(e=>n[e]=0),Array.isArray(t)&&t.forEach(e=>n[e.name]=e.post_count??0),k(n)}).catch(()=>{})},[u]);let A=async(e,t)=>{E.current&&clearTimeout(E.current);let n=t.currentTarget.getBoundingClientRect(),r=n.left-248,i=Math.max(8,Math.min(n.top+n.height/2-120,window.innerHeight-248)),a=w.current.get(e);if(a!==void 0){C({name:e,url:a,loading:!1,x:r,y:i});return}C({name:e,url:null,loading:!0,x:r,y:i});try{let t=await(await fetch(`https://danbooru.donmai.us/posts.json?tags=${encodeURIComponent(e+` -rating:e -rating:q`)}&limit=1&random=true`)).json(),n=t.length>0?t[0].large_file_url??t[0].sample_file_url??t[0].preview_file_url??null:null;w.current.set(e,n),C(t=>t?.name===e?{...t,url:n,loading:!1}:t)}catch{C(t=>t?.name===e?{...t,url:null,loading:!1}:t)}},j=()=>{E.current=setTimeout(()=>C(null),150)},M=e=>{x(e),setTimeout(()=>x(null),2e3)},N=(0,U.useMemo)(()=>{let n=$(t.blacklist),r=(t.whitelist??``).split(`,`).map(e=>e.trim()).filter(Boolean),i=new Set(r.map(Q)),a=e.tags.filter(e=>{let r=Q(e.name);if(n.has(r)||i.has(r))return!1;let a=t.thresholds[e.category]??.5;return e.score>=a});if(a.sort((e,t)=>t.score-e.score),a=a.slice(0,t.topK),t.randomize)for(let e=a.length-1;e>0;e--){let t=Math.floor(Math.random()*(e+1));[a[e],a[t]]=[a[t],a[e]]}return[...r.map(e=>({name:e,score:1,category:`general`})),...a]},[e.tags,t]),P=e=>t.removeUnderscores?e.replace(/_/g,` `):e,F=(0,U.useMemo)(()=>N.map(e=>P(e.name)).join(`, `),[N,t.removeUnderscores]),I=()=>{navigator.clipboard.writeText(F),g(!0),M(p(`results.tagsCopied`)),setTimeout(()=>g(!1),2e3)},L=async(e,t)=>{if(l){y(!0);try{let n=await Ie(l,e),r=URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=l.name.replace(/\.[^/.]+$/,``)+t,document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(r)}catch(e){console.error(`Failed to embed metadata`,e),alert(p(`results.embedFailed`))}finally{y(!1)}}},B=e=>{switch(e){case`copyright`:return`text-purple-700 bg-purple-100 dark:text-purple-200 dark:bg-purple-500/25`;case`character`:return`text-green-700 bg-green-100 dark:text-green-200 dark:bg-green-500/25`;case`artist`:return`text-amber-700 bg-amber-100 dark:text-amber-200 dark:bg-amber-500/25`;case`meta`:return`text-slate-600 bg-slate-200/70 dark:text-slate-300 dark:bg-slate-500/25`;case`rating`:return`text-rose-700 bg-rose-100 dark:text-rose-200 dark:bg-rose-500/25`;default:return`text-blue-700 bg-blue-100 dark:text-blue-200 dark:bg-blue-500/25`}},V=e=>{switch(e){case`copyright`:return(0,G.jsx)(a,{className:`w-3 h-3`});case`character`:return(0,G.jsx)(ne,{className:`w-3 h-3`});case`artist`:return(0,G.jsx)(O,{className:`w-3 h-3`});case`meta`:return(0,G.jsx)(R,{className:`w-3 h-3`});case`rating`:return(0,G.jsx)(re,{className:`w-3 h-3`});default:return(0,G.jsx)(i,{className:`w-3 h-3`})}};return(0,G.jsxs)(`div`,{className:`flex flex-col h-full gap-4 overflow-y-auto pr-2`,children:[(0,G.jsxs)(`div`,{className:`flex flex-col gap-2 flex-1`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,G.jsxs)(`h3`,{className:`text-sm font-semibold text-md-light-on-surface dark:text-md-dark-on-surface uppercase tracking-wider flex items-center gap-2`,children:[(0,G.jsx)(o,{className:`w-4 h-4`,"aria-hidden":`true`}),p(`results.technicalTags`),(0,G.jsx)(`span`,{className:`bg-md-light-surface-3 dark:bg-md-dark-surface-3 px-2 py-0.5 rounded-full text-xs font-normal text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant`,children:c.tags?`...`:N.length}),(0,G.jsx)(`span`,{className:`bg-md-light-surface-3 dark:bg-md-dark-surface-3 px-2 py-0.5 rounded-full text-xs font-normal uppercase text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant`,children:s})]}),(0,G.jsxs)(`div`,{className:`flex gap-2 items-center`,children:[(0,G.jsxs)(f,{small:!0,rounded:!0,tonal:!0,inline:!0,onClick:I,disabled:c.tags||N.length===0,className:`gap-1.5 text-xs disabled:opacity-50`,"aria-label":p(h?`results.copied`:`results.copyAll`),children:[h?(0,G.jsx)(_,{className:`w-3.5 h-3.5`,"aria-hidden":`true`}):(0,G.jsx)(m,{className:`w-3.5 h-3.5`,"aria-hidden":`true`}),p(h?`results.copied`:`results.copyAll`)]}),(0,G.jsxs)(f,{small:!0,rounded:!0,inline:!0,onClick:()=>L(F,`_nai_tags.png`),disabled:c.tags||N.length===0||v||!l,className:`gap-1.5 text-xs disabled:opacity-50`,"aria-label":p(`results.downloadNai`),children:[v?(0,G.jsx)(r,{className:`w-3.5 h-3.5`}):(0,G.jsx)(n,{className:`w-3.5 h-3.5`,"aria-hidden":`true`}),p(`results.naiReady`)]})]})]}),(0,G.jsx)(`div`,{className:`flex-1 min-h-[300px] bg-md-light-surface-2 dark:bg-md-dark-surface-2 rounded-3xl p-4 transition-colors duration-300`,children:c.tags?(0,G.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full space-y-6 py-8`,role:`status`,"aria-live":`polite`,children:[(0,G.jsxs)(`div`,{className:`w-full max-w-md space-y-2`,children:[(0,G.jsxs)(`div`,{className:`flex justify-between text-xs font-medium text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant`,children:[(0,G.jsx)(`span`,{children:c.status||p(`results.processing`)}),(0,G.jsxs)(`span`,{children:[Math.round(c.progress),`%`]})]}),(0,G.jsx)(pe,{progress:Math.max(.05,c.progress/100),className:`h-2 rounded-full`})]}),(0,G.jsx)(`div`,{className:`flex flex-wrap gap-2 animate-pulse opacity-30 justify-center max-w-lg blur-[1px]`,"aria-hidden":`true`,children:Array.from({length:12},(e,t)=>(0,G.jsx)(`div`,{className:`h-8 bg-md-light-surface-5 dark:bg-md-dark-surface-5 rounded-lg w-16`},t))})]}):(0,G.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[N.map(e=>(0,G.jsxs)(`button`,{onClick:()=>{navigator.clipboard.writeText(P(e.name)),M(p(`results.copiedItem`,{item:P(e.name)}))},className:`inline-flex items-center gap-1.5 px-3 h-8 rounded-lg text-xs font-medium cursor-pointer transition-all hover:scale-105 active:scale-95 ${B(e.category)}`,title:`${p(`results.score`)}: ${(e.score*100).toFixed(0)}%`,"aria-label":`${P(e.name)}, ${p(`results.score`)}: ${(e.score*100).toFixed(0)}%`,children:[(0,G.jsx)(`span`,{className:`opacity-50`,"aria-hidden":`true`,children:V(e.category)}),(0,G.jsx)(`span`,{className:`font-mono font-medium`,children:P(e.name)}),(0,G.jsx)(`span`,{className:`ml-1 text-2xs font-bold opacity-60 bg-black/10 dark:bg-black/20 px-1.5 py-0.5 rounded`,"aria-hidden":`true`,children:e.score.toFixed(2)})]},e.name)),N.length===0&&(0,G.jsxs)(`div`,{className:`w-full text-center py-12 text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant opacity-60`,children:[(0,G.jsx)(z,{className:`w-12 h-12 mx-auto mb-3 opacity-20`,"aria-hidden":`true`}),(0,G.jsx)(`p`,{children:p(`results.noTags`)})]})]})}),!c.tags&&N.length>0&&(0,G.jsx)(`div`,{className:`px-3 py-2.5 bg-md-light-surface-2 dark:bg-md-dark-surface-2 rounded-2xl transition-colors duration-300`,children:(0,G.jsx)(`p`,{className:`text-xs text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant font-mono wrap-break-word opacity-80 leading-relaxed`,children:F})})]}),(d||u&&u.length>0)&&(0,G.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,G.jsxs)(`h3`,{className:`text-sm font-semibold text-md-light-on-surface dark:text-md-dark-on-surface uppercase tracking-wider flex items-center gap-2`,children:[(0,G.jsx)(O,{className:`w-4 h-4`,"aria-hidden":`true`}),p(`results.artistSimilarity`),(0,G.jsx)(`span`,{className:`bg-md-light-surface-3 dark:bg-md-dark-surface-3 px-2 py-0.5 rounded-full text-2xs font-normal normal-case tracking-normal text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant`,children:`Kaloscope 2.0`})]}),(0,G.jsx)(`div`,{className:`bg-md-light-surface-2 dark:bg-md-dark-surface-2 rounded-3xl p-4 transition-colors duration-300`,children:d?(0,G.jsxs)(`div`,{className:`flex items-center justify-center gap-3 py-6 text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant`,role:`status`,"aria-live":`polite`,children:[(0,G.jsx)(r,{className:`w-5 h-5`}),(0,G.jsx)(`span`,{className:`text-sm`,children:p(`results.matchingArtists`)})]}):(0,G.jsx)(`ul`,{className:`space-y-0.5`,children:u.map((e,t)=>{let n=t<5;return(0,G.jsxs)(`li`,{onMouseEnter:t=>A(e.name,t),onMouseLeave:j,className:`flex items-center gap-1 rounded-xl transition-opacity ${n?``:`opacity-40 hover:opacity-70`}`,children:[(0,G.jsxs)(`button`,{onClick:()=>{navigator.clipboard.writeText(P(e.name)),M(p(`results.copiedItem`,{item:P(e.name)}))},className:`flex-1 flex items-center gap-3 px-2 py-1.5 rounded-xl hover:bg-md-light-surface-4 dark:hover:bg-md-dark-surface-4 transition-colors text-left cursor-pointer min-w-0`,title:p(`results.copyArtist`),children:[(0,G.jsx)(`span`,{className:`w-5 shrink-0 text-center text-xs font-bold tabular-nums ${n?`text-primary dark:text-md-dark-primary`:`text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant`}`,children:t+1}),(0,G.jsx)(`span`,{className:`flex-1 min-w-0 text-sm font-medium font-mono truncate text-md-light-on-surface dark:text-md-dark-on-surface`,children:P(e.name)}),D[e.name]!==void 0&&(0,G.jsx)(`span`,{className:`shrink-0 text-2xs tabular-nums text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant opacity-50`,children:D[e.name].toLocaleString()})]}),(0,G.jsx)(`a`,{href:`https://danbooru.donmai.us/artists/show_or_new?name=${encodeURIComponent(e.name)}`,target:`_blank`,rel:`noopener noreferrer`,className:`shrink-0 p-1.5 rounded-lg text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant hover:text-primary dark:hover:text-md-dark-primary hover:bg-md-light-surface-4 dark:hover:bg-md-dark-surface-4 transition-colors`,title:p(`results.openOnDanbooru`),"aria-label":p(`results.openArtistOnDanbooru`,{artist:P(e.name)}),onClick:e=>e.stopPropagation(),children:(0,G.jsx)(ee,{className:`w-3.5 h-3.5`,"aria-hidden":`true`})})]},e.name)})})})]}),S&&(0,K.createPortal)((0,G.jsx)(`div`,{className:`fixed z-50 pointer-events-none animate-in fade-in duration-150`,style:{left:Math.max(8,S.x),top:S.y},children:(0,G.jsx)(`div`,{className:`w-60 rounded-2xl overflow-hidden shadow-2xl ring-1 ring-black/10 dark:ring-white/10 bg-md-light-surface-2 dark:bg-md-dark-surface-2`,children:S.loading?(0,G.jsx)(`div`,{className:`w-60 h-60 flex items-center justify-center`,children:(0,G.jsx)(r,{className:`w-5 h-5`})}):S.url?(0,G.jsx)(`img`,{src:S.url,alt:``,className:`w-full h-auto block`}):(0,G.jsx)(`div`,{className:`w-60 h-32 flex items-center justify-center text-xs text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant opacity-40`,children:p(`results.noPreview`)})})}),document.body),b&&(0,K.createPortal)((0,G.jsx)(`div`,{className:`fixed bottom-8 left-1/2 -translate-x-1/2 z-50 animate-in fade-in slide-in-from-bottom-4 duration-200`,role:`status`,"aria-live":`polite`,children:(0,G.jsxs)(`div`,{className:`bg-stone-950/90 dark:bg-white/90 text-white dark:text-stone-900 px-4 py-2 rounded-full shadow-lg backdrop-blur-sm flex items-center gap-2 text-sm font-medium`,children:[(0,G.jsx)(_,{className:`w-4 h-4 text-green-500 dark:text-green-600`,"aria-hidden":`true`}),b]})}),document.body)]})},$e=`/kaloscope/infer`,et=async(e,t,n=10)=>{let r=Z(t,$e),i=new FormData;i.append(`file`,e);let a=await fetch(`${r}?top_k=${n}`,{method:`POST`,body:i});if(!a.ok)throw new J(`errors.kaloscopeError`,{status:a.status,statusText:a.statusText});let o=await a.json();return Array.isArray(o?.artists)?o.artists.filter(e=>e&&typeof e.name==`string`).map(e=>({name:e.name,score:Number(e.score)||0})):[]};function tt(){let[e,t]=(0,U.useState)(()=>typeof window<`u`&&localStorage.getItem(`theme`)||`auto`);return(0,U.useEffect)(()=>{let t=window.document.documentElement;if(t.classList.remove(`light`,`dark`),e===`auto`){let e=window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`;t.classList.add(e)}else t.classList.add(e);localStorage.setItem(`theme`,e)},[e]),(0,U.useEffect)(()=>{if(e!==`auto`)return;let t=window.matchMedia(`(prefers-color-scheme: dark)`),n=()=>{let e=window.document.documentElement;e.classList.remove(`light`,`dark`),e.classList.add(t.matches?`dark`:`light`)};return t.addEventListener(`change`,n),()=>t.removeEventListener(`change`,n)},[e]),{theme:e,setTheme:t}}var nt=new Date().getFullYear(),rt=nt>2025?`2025-${nt}`:`2025`,it={taggerModel:`wd-swinv2-v3`,taggerBaseUrl:typeof window<`u`?window.location.origin:``},at={wd:`wd-eva02-large-v3`,pixai:`pixai-v0.9`,camie:`camie-v2`,taggerine:`animetimm-caformer-b36`},ot=()=>{let{t:e,i18n:t}=T(),[n,i]=(0,U.useState)(!1),[a,o]=(0,U.useState)(q.IDLE),[s,c]=(0,U.useState)([]),[l,u]=(0,U.useState)(null),[m,g]=(0,U.useState)(null),[_,v]=(0,U.useState)(null),[y,b]=(0,U.useState)(!1);(0,U.useEffect)(()=>{document.documentElement.lang=t.language},[t.language]),(0,U.useEffect)(()=>{Be()},[]);let[x,S]=(0,U.useState)(()=>{try{let e=localStorage.getItem(`taggingSettings`);if(e){let t=JSON.parse(e);return t.whitelist===void 0&&(t.whitelist=t.triggerPhrase??``),t.blacklist===void 0&&(t.blacklist=``),delete t.triggerPhrase,t.useEscape===void 0&&(t.useEscape=!0),t.includeRanks===void 0&&(t.includeRanks=!1),t.scoreDescend===void 0&&(t.scoreDescend=!0),t}}catch{}return{thresholds:{general:.7,character:.7,copyright:.7,artist:.7,meta:.7,rating:.8},topK:50,maxTags:0,whitelist:``,blacklist:``,randomize:!1,removeUnderscores:!1,useEscape:!0,includeRanks:!1,scoreDescend:!0}});(0,U.useEffect)(()=>{let e=setTimeout(()=>{localStorage.setItem(`taggingSettings`,JSON.stringify(x))},300);return()=>clearTimeout(e)},[x]);let[w,E]=(0,U.useState)(()=>{try{let e=localStorage.getItem(`backendConfig`);if(e){let t=JSON.parse(e);if(t.taggerModel&&t.taggerBaseUrl)return t.taggerModel=at[t.taggerModel]??t.taggerModel,t}}catch{}return it});(0,U.useEffect)(()=>{let e=setTimeout(()=>{localStorage.setItem(`backendConfig`,JSON.stringify(w))},300);return()=>clearTimeout(e)},[w]);let[O,A]=(0,U.useState)(null),[j,N]=(0,U.useState)(`unknown`),P=(0,U.useCallback)(async e=>{try{A(await Je(e))}catch(e){console.warn(`Failed to load model list:`,e)}},[]);(0,U.useEffect)(()=>{let e=w.taggerBaseUrl?.trim();if(!e){N(`unknown`);return}let t=setTimeout(()=>{P(e),qe(e).then(N)},500);return()=>clearTimeout(t)},[w.taggerBaseUrl,P]),(0,U.useEffect)(()=>{if(!(!O||O.length===0)&&!O.some(e=>e.id===w.taggerModel)){let e=O.find(e=>e.recommended)??O[0];E(t=>({...t,taggerModel:e.id}))}},[O]);let[F,I]=(0,U.useState)(null),[L,R]=(0,U.useState)(w.taggerModel),[ee,z]=(0,U.useState)({tags:!1,progress:0,status:``}),{theme:B,setTheme:V}=tt();return(0,G.jsxs)(d,{theme:`material`,className:`h-full selection:bg-red-500/30`,children:[(0,G.jsx)(p,{position:`center`,opened:n,button:(0,G.jsx)(f,{rounded:!0,clear:!0,small:!0,inline:!0,onClick:()=>i(!1),children:e(`common.close`)}),children:(0,G.jsx)(`div`,{className:`shrink`,children:e(`app.modelsNotice`)})}),(0,G.jsxs)(C,{className:`flex flex-col min-h-screen`,children:[(0,G.jsx)(we,{theme:B,setTheme:V}),(0,G.jsxs)(`main`,{className:`flex-1 max-w-7xl w-full mx-auto p-3 sm:p-5 lg:p-8 gap-4 sm:gap-6 lg:gap-8 flex flex-col lg:grid lg:grid-cols-[380px_1fr] xl:grid-cols-[440px_1fr] lg:items-start pb-4`,children:[(0,G.jsxs)(`div`,{className:`w-full flex flex-col gap-4 sm:gap-6 shrink-0 order-1 lg:col-start-1 lg:row-start-1`,children:[(0,G.jsxs)(`div`,{className:`space-y-2`,children:[(0,G.jsx)(`h2`,{className:`text-base sm:text-lg font-semibold text-md-light-on-surface dark:text-md-dark-on-surface px-1`,children:e(`upload.inputImage`)}),(0,G.jsx)(je,{onFilesSelect:e=>{c(e),o(q.IDLE),u(null),g(null),v(null),I(null)},selectedFiles:s,onClear:()=>{c([]),u(null),g(null),v(null),o(q.IDLE),I(null)}})]}),(0,G.jsx)(f,{large:!0,rounded:!0,onClick:async()=>{if(s.length!==0){if(!w.taggerBaseUrl?.trim()){I(e(`errors.taggerRequired`)),o(q.ERROR);return}o(q.ANALYZING),z({tags:!0,progress:0,status:e(`status.starting`)}),I(null),u(null),g(null),v(null);try{if(s.length===1){let n=s[0];b(!0);let r=et(n,w.taggerBaseUrl).then(e=>v(e)).catch(e=>{console.warn(`Kaloscope artist matching unavailable:`,e),v(null)}).finally(()=>b(!1));u(await Ze(n,w,x,t.language,(t,n)=>{z(r=>({...r,status:e(t),progress:n}))})),R(w.taggerModel),o(q.SUCCESS),await r}else z(t=>({...t,status:e(`results.analyzing`),progress:50})),g(await Xe(s,w,x)),R(w.taggerModel),o(q.SUCCESS);P(w.taggerBaseUrl)}catch(t){console.error(t),o(q.ERROR),I(t instanceof J?e(t.key,t.params):t instanceof Error?t.message:e(`errors.unknown`)),t instanceof J&&t.params?.status===404&&P(w.taggerBaseUrl),qe(w.taggerBaseUrl).then(N)}finally{z({tags:!1,progress:100,status:e(`status.done`)})}}},disabled:s.length===0||a===q.ANALYZING||j===`down`,className:`h-12! sm:h-14! text-base font-semibold gap-2 shadow-md disabled:opacity-40`,children:a===q.ANALYZING?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(r,{className:`w-5 h-5 text-current`}),e(`results.analyzing`)]}):(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(k,{className:`w-5 h-5`,"aria-hidden":`true`}),e(`upload.interrogate`)]})})]}),(0,G.jsx)(`div`,{className:`w-full order-2 lg:col-start-1 lg:row-start-2`,children:(0,G.jsx)(Me,{settings:x,backendConfig:w,models:O,health:j,onSettingsChange:S,onBackendChange:E,disabled:a===q.ANALYZING})}),(0,G.jsxs)(`div`,{className:`w-full flex-1 flex flex-col min-h-[360px] sm:min-h-[480px] lg:h-auto animate-in fade-in slide-in-from-bottom-4 duration-500 order-3 lg:col-start-2 lg:row-start-1 lg:row-span-3`,children:[(0,G.jsx)(`div`,{className:`flex items-center gap-3 mb-2 px-1`,children:(0,G.jsx)(`h2`,{className:`text-base sm:text-lg font-semibold text-md-light-on-surface dark:text-md-dark-on-surface`,children:e(`results.title`)})}),(0,G.jsxs)(`div`,{className:`flex-1 bg-md-light-surface-1 dark:bg-md-dark-surface-1 rounded-3xl sm:rounded-[28px] p-2 transition-colors duration-300 relative min-h-[360px] sm:min-h-[480px]`,children:[!l&&!m&&a!==q.ERROR&&(0,G.jsxs)(`div`,{className:`absolute inset-0 m-3 rounded-3xl border-2 border-dashed border-md-light-outline-variant dark:border-md-dark-outline-variant flex flex-col items-center justify-center text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant`,children:[(0,G.jsx)(M,{className:`w-10 h-10 sm:w-12 sm:h-12 mb-3 opacity-20`}),(0,G.jsx)(`p`,{className:`font-medium opacity-60`,children:e(`results.ready`)}),(0,G.jsx)(`p`,{className:`text-sm opacity-40 mt-1`,children:e(`results.readySub`)})]}),a===q.ERROR&&(0,G.jsxs)(`div`,{className:`h-full flex flex-col items-center justify-center text-red-500 dark:text-red-400 p-6 sm:p-8 text-center`,children:[(0,G.jsx)(h,{className:`w-10 h-10 sm:w-12 sm:h-12 mb-4 opacity-50`}),(0,G.jsx)(`h3`,{className:`text-lg font-bold mb-2`,children:e(`results.failed`)}),(0,G.jsx)(`p`,{className:`text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant max-w-md text-sm sm:text-base`,children:F}),(0,G.jsxs)(`div`,{className:`mt-4 p-3 bg-md-light-surface-2 dark:bg-md-dark-surface-2 rounded-xl text-xs text-left w-full max-w-sm`,children:[(0,G.jsx)(`p`,{className:`font-semibold mb-1`,children:e(`results.troubleshoot`)}),(0,G.jsx)(`ul`,{className:`list-disc list-inside opacity-70 space-y-1`,children:(0,G.jsx)(`li`,{className:`break-all`,children:e(`results.troubleshootTagger`,{endpoint:w.taggerBaseUrl})})})]})]}),l&&s.length===1&&(0,G.jsx)(`div`,{className:`h-full p-2 sm:p-4`,children:(0,G.jsx)(Qe,{result:l,settings:x,taggerModel:O?.find(e=>e.id===L)?.label??L,loadingState:ee,selectedFile:s[0],artistMatches:_,isMatchingArtists:y})}),m&&(0,G.jsxs)(`div`,{className:`h-full p-3 sm:p-4 overflow-auto`,children:[(0,G.jsx)(`h3`,{className:`text-lg font-bold mb-4`,children:e(`results.batchResults`)}),(0,G.jsx)(`div`,{className:`space-y-4`,children:Object.entries(m).map(([e,t])=>(0,G.jsxs)(`div`,{className:`p-3 sm:p-4 bg-md-light-surface-2 dark:bg-md-dark-surface-2 rounded-2xl`,children:[(0,G.jsx)(`h4`,{className:`font-semibold mb-2 text-sm break-all`,children:e}),(0,G.jsx)(`div`,{className:`bg-md-light-surface dark:bg-md-dark-surface p-3 rounded-xl font-mono text-xs break-all`,children:t.tag_string})]},e))})]})]})]}),(0,G.jsx)(`div`,{className:`w-full order-4 lg:col-start-1 lg:row-start-3`,children:(0,G.jsx)(Ne,{settings:x,onSettingsChange:S,disabled:a===q.ANALYZING})})]}),(0,G.jsxs)(`footer`,{className:`px-3 pb-2.5 pt-1 flex flex-wrap items-center justify-between gap-3 text-xs text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant`,children:[(0,G.jsxs)(`a`,{href:`https://gpu.garden`,target:`_blank`,rel:`noopener noreferrer`,className:`group flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-md-light-surface-2/70 dark:bg-md-dark-surface-2/70 backdrop-blur-md active:scale-95 transition-transform shrink-0`,title:`GPU Garden`,"aria-label":`GPU Garden`,children:[(0,G.jsx)(`img`,{src:`/gpu-garden-logo.webp`,alt:``,className:`w-4 h-4 sm:w-5 sm:h-5 transition-transform duration-300 group-hover:scale-110`,"aria-hidden":`true`}),(0,G.jsxs)(`span`,{className:`relative font-bold text-xs overflow-hidden`,children:[(0,G.jsx)(`span`,{className:`block text-md-light-on-surface-variant dark:text-md-dark-on-surface-variant transition-opacity duration-250 group-hover:opacity-0`,"aria-hidden":`true`,children:`gpu.garden`}),(0,G.jsx)(`span`,{className:`absolute inset-0 bg-clip-text text-transparent bg-linear-to-r from-red-600 to-red-400 dark:from-red-400 dark:to-red-300 -translate-x-full group-hover:translate-x-0 transition-transform duration-300 ease-out`,"aria-hidden":`true`,children:`gpu.garden`})]})]}),(0,G.jsx)(`p`,{className:`opacity-50 px-3 py-1 rounded-full bg-md-light-surface-2/70 dark:bg-md-dark-surface-2/70 backdrop-blur-md text-center shrink-0 order-3 sm:order-2 basis-full sm:basis-auto whitespace-normal break-words`,children:e(`app.copyright`,{year:rt})}),(0,G.jsx)(`span`,{className:`px-3 py-1 rounded-full bg-md-light-surface-2/70 dark:bg-md-dark-surface-2/70 backdrop-blur-md opacity-60 shrink-0 order-2 sm:order-3`,children:(0,G.jsx)(D,{i18nKey:`app.madeBy`,components:{mooshieblob:(0,G.jsx)(`a`,{href:`https://mooshieblob.com/`,target:`_blank`,rel:`noopener noreferrer`,className:`hover:text-md-light-primary dark:hover:text-md-dark-primary hover:opacity-100 transition-colors`}),ashtaka:(0,G.jsx)(`a`,{href:`https://github.com/AshtakaOOf`,target:`_blank`,rel:`noopener noreferrer`,className:`hover:text-md-light-primary dark:hover:text-md-dark-primary hover:opacity-100 transition-colors`})}})})]})]})]})},st=document.getElementById(`root`);if(!st)throw Error(`Could not find root element to mount to`);ge.createRoot(st).render((0,G.jsx)(U.StrictMode,{children:(0,G.jsx)(U.Suspense,{fallback:(0,G.jsx)(`div`,{className:`flex items-center justify-center h-screen`,children:(0,G.jsx)(`div`,{className:`animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500`})}),children:(0,G.jsx)(ot,{})})}));
|
dist/assets/it-CJ48uQvE.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
var e={title:`Farterrogator`,subtitle:`Interrogatore di Immagini IA`,copyright:`Farterrogator © {{year}} Fartcore. Tutti i diritti riservati. I modelli non sono di proprietà di Fartcore e sono forniti gratuitamente.`,logoAlt:`Logo di Farterrogator`,modelsNotice:`Novità: ora sono disponibili più modelli di tagging! Scegline uno nelle impostazioni.`,madeBy:`creato da <mooshieblob>mooshieblob</mooshieblob> e <ashtaka>ashtaka</ashtaka>`},t={close:`Chiudi`,changeLanguage:`Cambia lingua`,languageSelection:`Selezione della lingua`},n={whatIsThis:`Cos'è questo?`,poweredBy:`Modello: {{model}}`,nothingYet:`Nessuno`},r={inputImage:`Immagine di input`,dragDrop:`Trascina un'immagine qui o clicca per selezionare`,dropHere:`Rilascia i file qui`,supports:`Supporta PNG, JPG, WEBP, GIF`,supportsArchives:`(+ ZIP, TAR)`,clear:`Rimuovi immagine`,interrogate:`Interroga`,previewAlt:`Anteprima dell'immagine caricata`,filesSelected:`{{num}} file selezionati`,batchReady:`Pronto per l'elaborazione in batch`},i={title:`Risultato dell'analisi`,ready:`Pronto a interrogare`,readySub:`Carica un'immagine per iniziare il tagging`,failed:`Analisi non riuscita`,troubleshoot:`Risoluzione dei problemi:`,troubleshootTagger:`Assicurati che il tagger sia raggiungibile su {{endpoint}}`,processing:`Elaborazione...`,analyzing:`Analisi in corso...`,technicalTags:`Tag`,noTags:`Nessun tag trovato con la soglia attuale.`,copyAll:`Copia tutto`,copied:`Copiato!`,copiedItem:`Copiato: {{item}}`,naiReady:`NAI Ready`,downloadNai:`Scarica con i tag incorporati`,tagsCopied:`Tutti i tag copiati negli appunti!`,embedFailed:`Impossibile creare l'immagine NAI Ready.`,score:`Punteggio`,batchResults:`Risultati batch`,artistSimilarity:`Somiglianza artista`,matchingArtists:`Confronto degli stili artistici...`,copyArtist:`Copia il nome dell'artista`,noPreview:`Nessuna anteprima`,openOnDanbooru:`Apri su Danbooru`,openArtistOnDanbooru:`Apri {{artist}} su Danbooru`},a={starting:`Avvio...`,analyzingImage:`Analisi dell'immagine...`,done:`Fatto`},o={title:`Impostazioni`,thresholds:`Soglie`,outputSettings:`Output`,topK:`Top K tag`,randomize:`Ordine casuale`,removeUnderscores:`Rimuovi underscore`,scoreDescend:`Ordina per punteggio`,includeRanks:`Aggiungi punteggi ai tag`,useEscape:`Esegui escape delle parentesi`,advancedThresholds:`Avanzato`,backend:{model:`Modello di tagging`,baseUrl:`URL API`,baseUrlHint:`URL endpoint API, es. https://localtagger.gpu.garden o http://localhost:8000`,families:{wd14:`Famiglia WD`,animetimm:`AnimeTimm`,camie:`Camie`},models:{},gatedHint:`Richiede un token Hugging Face sul server.`,warmupHint:`Modello non ancora caricato: la prima richiesta potrebbe richiedere più tempo.`,onlineHint:`Backend online.`,offlineHint:`Backend non raggiungibile. Controlla l'URL dell'API o che il server sia in esecuzione.`,resetToDefault:`Ripristina predefinito`},categories:{general:`Generale`,character:`Personaggio`,copyright:`Copyright`,artist:`Artista`,meta:`Meta`,rating:`Classificazione`},maxTags:`Max tag (0 = illimitato)`,whitelist:`Whitelist dei tag`,whitelistPlaceholder:`es. masterpiece, best quality`,blacklist:`Blacklist dei tag`,blacklistPlaceholder:`es. watermark, signature`},s={taggerRequired:`È richiesto l'URL di base del tagger. Configuralo nelle impostazioni del backend.`,taggerError:`Errore del tagger: {{status}} {{statusText}}`,batchTaggerError:`Errore del tagger in batch: {{status}} {{statusText}}`,kaloscopeError:`Errore di Kaloscope: {{status}} {{statusText}}`,unknown:`Si è verificato un errore sconosciuto`},c={title:`Cos'è Farterrogator?`,description:`<strong>Farterrogator</strong> è un tagger di immagini locale e veloce in stile Booru. Analizza le immagini con modelli della famiglia WD EVA 02 e modelli incentrati sull'illustrazione per estrarre tag compatibili con Danbooru, per la creazione di dataset e il prompt engineering.`,features:{models:{title:`Più modelli di tagging`,description:`Scegli tra i modelli <strong>WD SwinV2</strong>, <strong>WD EVA02</strong>, <strong>AnimeTimm</strong> e <strong>Camie</strong> — più la somiglianza di stile artistico Kaloscope.`},naiReady:{title:`Incorporamento NAI Ready`,description:`Incorpora automaticamente i tag generati nei metadati PNG. Le immagini risultanti sono "NAI Ready": trascinale in NovelAI per compilare automaticamente i prompt.`},privacy:{title:`Privacy e prestazioni`,description:`Tutta l'inferenza viene eseguita sul backend configurato (gpu.garden o locale). Nessuna chiave API cloud richiesta.`},gpuGarden:{title:`Integrazione GPU Garden`,description:`Ottimizzato per l'infrastruttura gpu.garden con instradamento automatico del proxy CORS.`}},howTo:{title:`Come si usa`,step1:`Carica un'immagine o trascinala sull'area.`,step2:`Seleziona un modello di tagging: l'elenco viene caricato dal backend.`,step3:`Regola le soglie di confidenza per filtrare i tag.`,step4:`Clicca su <strong>Interroga</strong>.`,step5:`Copia i tag o scarica un PNG <strong>NAI Ready</strong>.`},madeBy:`Creato da`},l={label:`Selezione del tema`,light:`Modalità chiara`,auto:`Auto di sistema`,dark:`Modalità scura`},u={app:e,common:t,header:n,upload:r,results:i,status:a,settings:o,errors:s,info:c,theme:l};export{e as app,t as common,u as default,s as errors,n as header,c as info,i as results,o as settings,a as status,l as theme,r as upload};
|
dist/assets/ja-Bu_r5epl.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
var e={title:`Farterrogator`,subtitle:`AI画像解析ツール`,copyright:`Farterrogator © {{year}} Fartcore. All rights reserved. モデルはFartcoreの所有物ではなく、無償で提供されています。`,logoAlt:`Farterrogatorのロゴ`,modelsNotice:`新機能:複数のタガーモデルが利用可能になりました!設定から選択してください。`,madeBy:`制作: <mooshieblob>mooshieblob</mooshieblob> と <ashtaka>ashtaka</ashtaka>`},t={close:`閉じる`,changeLanguage:`言語を変更`,languageSelection:`言語の選択`},n={whatIsThis:`これは何?`,poweredBy:`モデル: {{model}}`,nothingYet:`なし`},r={inputImage:`入力画像`,dragDrop:`ここに画像をドラッグ&ドロップ、またはクリックして選択`,dropHere:`ここにファイルをドロップ`,supports:`PNG、JPG、WEBP、GIF に対応`,supportsArchives:`(+ ZIP、TAR)`,clear:`画像をクリア`,interrogate:`解析開始`,previewAlt:`アップロードした画像のプレビュー`,filesSelected:`{{num}} 件のファイルを選択中`,batchReady:`バッチ処理の準備完了`},i={title:`解析結果`,ready:`解析の準備完了`,readySub:`画像をアップロードしてタグ付けを開始`,failed:`解析に失敗しました`,troubleshoot:`トラブルシューティング:`,troubleshootTagger:`タガーが {{endpoint}} で利用可能か確認してください`,processing:`処理中...`,analyzing:`解析中...`,technicalTags:`タグ`,noTags:`現在のしきい値ではタグが見つかりませんでした。`,copyAll:`すべてコピー`,copied:`コピーしました!`,copiedItem:`コピー: {{item}}`,naiReady:`NAI Ready`,downloadNai:`タグを埋め込んでダウンロード`,tagsCopied:`すべてのタグをクリップボードにコピーしました!`,embedFailed:`NAI Ready 画像の作成に失敗しました。`,score:`スコア`,batchResults:`バッチ結果`,artistSimilarity:`絵師の類似度`,matchingArtists:`絵師のスタイルを照合中...`,copyArtist:`絵師名をコピー`,noPreview:`プレビューなし`,openOnDanbooru:`Danbooruで開く`,openArtistOnDanbooru:`{{artist}}をDanbooruで開く`},a={starting:`開始中...`,analyzingImage:`画像を解析中...`,done:`完了`},o={title:`設定`,thresholds:`しきい値`,outputSettings:`出力`,topK:`上位Kタグ`,randomize:`順序をランダム化`,removeUnderscores:`アンダースコアを削除`,scoreDescend:`スコア順に並べ替え`,includeRanks:`タグにスコアを付加`,useEscape:`括弧をエスケープ`,advancedThresholds:`詳細`,backend:{model:`タガーモデル`,baseUrl:`API URL`,baseUrlHint:`APIエンドポイントURL。例: https://localtagger.gpu.garden または http://localhost:8000`,families:{wd14:`WD ファミリー`,animetimm:`AnimeTimm`,camie:`Camie`},models:{},gatedHint:`サーバー側に Hugging Face トークンが必要です。`,warmupHint:`モデルはまだ読み込まれていません。最初のリクエストには時間がかかる場合があります。`,onlineHint:`バックエンドはオンラインです。`,offlineHint:`バックエンドに接続できません。API URL を確認するか、サーバーが起動しているか確認してください。`,resetToDefault:`デフォルトにリセット`},categories:{general:`一般`,character:`キャラクター`,copyright:`作品`,artist:`絵師`,meta:`メタ`,rating:`レーティング`},maxTags:`最大タグ数 (0 = 無制限)`,whitelist:`タグホワイトリスト`,whitelistPlaceholder:`例: masterpiece, best quality`,blacklist:`タグブラックリスト`,blacklistPlaceholder:`例: watermark, signature`},s={taggerRequired:`タガーのベースURLが必要です。バックエンド設定で構成してください。`,taggerError:`タガーエラー: {{status}} {{statusText}}`,batchTaggerError:`バッチタガーエラー: {{status}} {{statusText}}`,kaloscopeError:`Kaloscopeエラー: {{status}} {{statusText}}`,unknown:`不明なエラーが発生しました`},c={title:`Farterrogator とは?`,description:`<strong>Farterrogator</strong> は高速なローカル Booru 系画像タガーです。WD EVA 02 系およびイラスト特化モデルで画像を解析し、データセット作成やプロンプトエンジニアリングのための Danbooru 互換タグを抽出します。`,features:{models:{title:`複数のタガーモデル`,description:`<strong>WD SwinV2</strong>、<strong>WD EVA02</strong>、<strong>AnimeTimm</strong>、<strong>Camie</strong> のモデルから選択可能。さらに Kaloscope による絵師スタイル類似度も。`},naiReady:{title:`NAI Ready 埋め込み`,description:`生成されたタグを PNG メタデータに自動的に埋め込みます。出来上がった画像は「NAI Ready」— NovelAI にドラッグするだけでプロンプトが自動入力されます。`},privacy:{title:`プライバシーとパフォーマンス`,description:`すべての推論は設定されたバックエンド (gpu.garden またはローカル) で実行されます。クラウド API キーは不要です。`},gpuGarden:{title:`GPU Garden 連携`,description:`自動 CORS プロキシルーティングにより gpu.garden インフラ向けに最適化されています。`}},howTo:{title:`使い方`,step1:`画像をアップロードするか、キャンバスにドラッグ&ドロップします。`,step2:`タガーモデルを選択します。モデル一覧はバックエンドから読み込まれます。`,step3:`信頼度のしきい値を調整してタグをフィルタリングします。`,step4:`<strong>解析開始</strong>をクリックします。`,step5:`タグをコピーするか、<strong>NAI Ready</strong> PNG をダウンロードします。`},madeBy:`作者`},l={label:`テーマの選択`,light:`ライトモード`,auto:`システム設定に従う`,dark:`ダークモード`},u={app:e,common:t,header:n,upload:r,results:i,status:a,settings:o,errors:s,info:c,theme:l};export{e as app,t as common,u as default,s as errors,n as header,c as info,i as results,o as settings,a as status,l as theme,r as upload};
|
dist/assets/ko-Ccvowmxl.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
var e={title:`Farterrogator`,subtitle:`AI 이미지 분석기`,copyright:`Farterrogator © {{year}} Fartcore. 모든 권리 보유. 모델은 Fartcore의 소유가 아니며 무료로 제공됩니다.`,logoAlt:`Farterrogator 로고`,modelsNotice:`신규: 이제 여러 태거 모델을 사용할 수 있습니다! 설정에서 하나를 선택하세요.`,madeBy:`제작: <mooshieblob>mooshieblob</mooshieblob> 및 <ashtaka>ashtaka</ashtaka>`},t={close:`닫기`,changeLanguage:`언어 변경`,languageSelection:`언어 선택`},n={whatIsThis:`이게 뭔가요?`,poweredBy:`모델: {{model}}`,nothingYet:`없음`},r={inputImage:`입력 이미지`,dragDrop:`이미지를 여기에 드래그 앤 드롭하거나 클릭하여 선택하세요`,dropHere:`여기에 파일을 놓으세요`,supports:`PNG, JPG, WEBP, GIF 지원`,supportsArchives:`(+ ZIP, TAR)`,clear:`이미지 지우기`,interrogate:`분석 시작`,previewAlt:`업로드된 이미지 미리보기`,filesSelected:`{{num}}개 파일 선택됨`,batchReady:`일괄 처리 준비 완료`},i={title:`분석 결과`,ready:`분석 준비 완료`,readySub:`이미지를 업로드하여 태깅을 시작하세요`,failed:`분석 실패`,troubleshoot:`문제 해결:`,troubleshootTagger:`태거가 {{endpoint}}에서 접근 가능한지 확인하세요`,processing:`처리 중...`,analyzing:`분석 중...`,technicalTags:`태그`,noTags:`현재 임계값에서 태그를 찾을 수 없습니다.`,copyAll:`모두 복사`,copied:`복사됨!`,copiedItem:`복사됨: {{item}}`,naiReady:`NAI Ready`,downloadNai:`태그가 포함된 이미지 다운로드`,tagsCopied:`모든 태그가 클립보드에 복사되었습니다!`,embedFailed:`NAI Ready 이미지를 만들지 못했습니다.`,score:`점수`,batchResults:`일괄 처리 결과`,artistSimilarity:`작가 유사도`,matchingArtists:`작가 스타일 매칭 중...`,copyArtist:`작가 이름 복사`,noPreview:`미리보기 없음`,openOnDanbooru:`Danbooru에서 열기`,openArtistOnDanbooru:`Danbooru에서 {{artist}} 열기`},a={starting:`시작 중...`,analyzingImage:`이미지 분석 중...`,done:`완료`},o={title:`설정`,thresholds:`임계값`,outputSettings:`출력`,topK:`상위 K개 태그`,randomize:`순서 무작위화`,removeUnderscores:`밑줄 제거`,scoreDescend:`점수순 정렬`,includeRanks:`태그에 점수 추가`,useEscape:`괄호 이스케이프`,advancedThresholds:`고급`,backend:{model:`태거 모델`,baseUrl:`API URL`,baseUrlHint:`API 엔드포인트 URL, 예: https://localtagger.gpu.garden 또는 http://localhost:8000`,families:{wd14:`WD 계열`,animetimm:`AnimeTimm`,camie:`Camie`},models:{},gatedHint:`서버에 Hugging Face 토큰이 필요합니다.`,warmupHint:`모델이 아직 로드되지 않았습니다. 첫 요청은 시간이 더 걸릴 수 있습니다.`,onlineHint:`백엔드 온라인.`,offlineHint:`백엔드에 연결할 수 없습니다. API URL을 확인하거나 서버가 실행 중인지 확인하세요.`,resetToDefault:`기본값으로 초기화`},categories:{general:`일반`,character:`캐릭터`,copyright:`저작권`,artist:`작가`,meta:`메타`,rating:`등급`},maxTags:`최대 태그 수 (0 = 무제한)`,whitelist:`태그 화이트리스트`,whitelistPlaceholder:`예: masterpiece, best quality`,blacklist:`태그 블랙리스트`,blacklistPlaceholder:`예: watermark, signature`},s={taggerRequired:`태거 기본 URL이 필요합니다. 백엔드 설정에서 구성해 주세요.`,taggerError:`태거 오류: {{status}} {{statusText}}`,batchTaggerError:`일괄 태거 오류: {{status}} {{statusText}}`,kaloscopeError:`Kaloscope 오류: {{status}} {{statusText}}`,unknown:`알 수 없는 오류가 발생했습니다`},c={title:`Farterrogator란?`,description:`<strong>Farterrogator</strong>는 빠른 로컬 Booru 스타일 이미지 태거입니다. WD EVA 02 계열 및 일러스트 중심 모델로 이미지를 분석하여 데이터셋 제작과 프롬프트 엔지니어링을 위한 Danbooru 호환 태그를 추출합니다.`,features:{models:{title:`다양한 태거 모델`,description:`<strong>WD SwinV2</strong>, <strong>WD EVA02</strong>, <strong>AnimeTimm</strong>, <strong>Camie</strong> 모델 중에서 선택할 수 있으며, Kaloscope 작가 스타일 유사도도 제공합니다.`},naiReady:{title:`NAI Ready 임베딩`,description:`생성된 태그를 PNG 메타데이터에 자동으로 임베딩합니다. 결과 이미지는 "NAI Ready"로, NovelAI에 드래그하기만 하면 프롬프트가 자동 입력됩니다.`},privacy:{title:`개인정보 보호 및 성능`,description:`모든 추론은 구성된 백엔드(gpu.garden 또는 로컬)에서 실행됩니다. 클라우드 API 키가 필요하지 않습니다.`},gpuGarden:{title:`GPU Garden 통합`,description:`자동 CORS 프록시 라우팅으로 gpu.garden 인프라에 최적화되어 있습니다.`}},howTo:{title:`사용 방법`,step1:`이미지를 업로드하거나 캔버스에 드래그 앤 드롭하세요.`,step2:`태거 모델을 선택하세요. 목록은 백엔드에서 불러옵니다.`,step3:`신뢰도 임계값을 조정하�� 태그를 필터링하세요.`,step4:`<strong>분석 시작</strong>을 클릭하세요.`,step5:`태그를 복사하거나 <strong>NAI Ready</strong> PNG를 다운로드하세요.`},madeBy:`제작:`},l={label:`테마 선택`,light:`라이트 모드`,auto:`시스템 자동`,dark:`다크 모드`},u={app:e,common:t,header:n,upload:r,results:i,status:a,settings:o,errors:s,info:c,theme:l};export{e as app,t as common,u as default,s as errors,n as header,c as info,i as results,o as settings,a as status,l as theme,r as upload};
|
dist/assets/pt-BpqmNNtz.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
var e={title:`Farterrogator`,subtitle:`Interrogador de Imagem IA`,copyright:`Farterrogator © {{year}} Fartcore. Todos os direitos reservados. Os modelos não são propriedade da Fartcore e são fornecidos gratuitamente.`,logoAlt:`Logotipo do Farterrogator`,modelsNotice:`Novidade: vários modelos de tagging já estão disponíveis! Escolha um nas configurações.`,madeBy:`feito por <mooshieblob>mooshieblob</mooshieblob> e <ashtaka>ashtaka</ashtaka>`},t={close:`Fechar`,changeLanguage:`Mudar idioma`,languageSelection:`Seleção de idioma`},n={whatIsThis:`O que é isto?`,poweredBy:`Modelo: {{model}}`,nothingYet:`Nenhum`},r={inputImage:`Imagem de entrada`,dragDrop:`Arraste e solte uma imagem aqui, ou clique para selecionar`,dropHere:`Solte os arquivos aqui`,supports:`Suporta PNG, JPG, WEBP, GIF`,supportsArchives:`(+ ZIP, TAR)`,clear:`Remover imagem`,interrogate:`Interrogar`,previewAlt:`Pré-visualização da imagem enviada`,filesSelected:`{{num}} arquivos selecionados`,batchReady:`Pronto para processamento em lote`},i={title:`Resultado da análise`,ready:`Pronto para interrogar`,readySub:`Envie uma imagem para começar o tagging`,failed:`Falha na análise`,troubleshoot:`Solução de problemas:`,troubleshootTagger:`Verifique se o tagger está acessível em {{endpoint}}`,processing:`Processando...`,analyzing:`Analisando...`,technicalTags:`Tags`,noTags:`Nenhuma tag encontrada no limiar atual.`,copyAll:`Copiar tudo`,copied:`Copiado!`,copiedItem:`Copiado: {{item}}`,naiReady:`NAI Ready`,downloadNai:`Baixar com tags incorporadas`,tagsCopied:`Todas as tags copiadas para a área de transferência!`,embedFailed:`Falha ao criar a imagem NAI Ready.`,score:`Pontuação`,batchResults:`Resultados em lote`,artistSimilarity:`Similaridade de artista`,matchingArtists:`Comparando estilos de artistas...`,copyArtist:`Copiar nome do artista`,noPreview:`Sem pré-visualização`,openOnDanbooru:`Abrir no Danbooru`,openArtistOnDanbooru:`Abrir {{artist}} no Danbooru`},a={starting:`Iniciando...`,analyzingImage:`Analisando imagem...`,done:`Concluído`},o={title:`Configurações`,thresholds:`Limiares`,outputSettings:`Saída`,topK:`Top K tags`,randomize:`Ordem aleatória`,removeUnderscores:`Remover underscores`,scoreDescend:`Ordenar por pontuação`,includeRanks:`Anexar pontuações às tags`,useEscape:`Escapar parênteses`,advancedThresholds:`Avançado`,backend:{model:`Modelo de tagging`,baseUrl:`URL da API`,baseUrlHint:`URL do endpoint API, ex.: https://localtagger.gpu.garden ou http://localhost:8000`,families:{wd14:`Família WD`,animetimm:`AnimeTimm`,camie:`Camie`},models:{},gatedHint:`Requer um token do Hugging Face no servidor.`,warmupHint:`Modelo ainda não carregado — a primeira solicitação pode demorar mais.`,onlineHint:`Backend online.`,offlineHint:`Backend inacessível. Verifique a URL da API ou se o servidor está em execução.`,resetToDefault:`Redefinir padrão`},categories:{general:`Geral`,character:`Personagem`,copyright:`Copyright`,artist:`Artista`,meta:`Meta`,rating:`Classificação`},maxTags:`Máx. de tags (0 = ilimitado)`,whitelist:`Lista branca de tags`,whitelistPlaceholder:`ex.: masterpiece, best quality`,blacklist:`Lista negra de tags`,blacklistPlaceholder:`ex.: watermark, signature`},s={taggerRequired:`A URL base do tagger é obrigatória. Configure-a nas configurações do backend.`,taggerError:`Erro do tagger: {{status}} {{statusText}}`,batchTaggerError:`Erro do tagger em lote: {{status}} {{statusText}}`,kaloscopeError:`Erro do Kaloscope: {{status}} {{statusText}}`,unknown:`Ocorreu um erro desconhecido`},c={title:`O que é o Farterrogator?`,description:`<strong>Farterrogator</strong> é um tagger de imagens local e rápido no estilo Booru. Ele analisa imagens com modelos da família WD EVA 02 e modelos focados em ilustração para extrair tags compatíveis com o Danbooru, para criação de datasets e prompt engineering.`,features:{models:{title:`Vários modelos de tagging`,description:`Escolha entre os modelos <strong>WD SwinV2</strong>, <strong>WD EVA02</strong>, <strong>AnimeTimm</strong> e <strong>Camie</strong> — além da similaridade de estilo de artista Kaloscope.`},naiReady:{title:`Incorporação NAI Ready`,description:`Incorpora automaticamente as tags geradas nos metadados PNG. As imagens resultantes são "NAI Ready" — basta arrastá-las para o NovelAI para preencher os prompts automaticamente.`},privacy:{title:`Privacidade e desempenho`,description:`Toda a inferência roda no backend configurado (gpu.garden ou local). Nenhuma chave de API na nuvem é necessária.`},gpuGarden:{title:`Integração com GPU Garden`,description:`Otimizado para a infraestrutura gpu.garden com roteamento automático de proxy CORS.`}},howTo:{title:`Como usar`,step1:`Envie uma imagem ou arraste-a para a área.`,step2:`Selecione um modelo de tagging — a lista é carregada do backend.`,step3:`Ajuste os limiares de confiança para filtrar as tags.`,step4:`Clique em <strong>Interrogar</strong>.`,step5:`Copie as tags ou baixe um PNG <strong>NAI Ready</strong>.`},madeBy:`Feito por`},l={label:`Seleção de tema`,light:`Modo claro`,auto:`Automático do sistema`,dark:`Modo escuro`},u={app:e,common:t,header:n,upload:r,results:i,status:a,settings:o,errors:s,info:c,theme:l};export{e as app,t as common,u as default,s as errors,n as header,c as info,i as results,o as settings,a as status,l as theme,r as upload};
|
dist/assets/rolldown-runtime-BHe-jwch.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(n,r,a)=>(a=n==null?{}:e(i(n)),s(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n)),l=(e=>typeof require<`u`?require:typeof Proxy<`u`?new Proxy(e,{get:(e,t)=>(typeof require<`u`?require:e)[t]}):e)(function(e){if(typeof require<`u`)return require.apply(this,arguments);throw Error('Calling `require` for "'+e+"\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.")});export{l as n,c as r,o as t};
|
dist/assets/ru-CbpyFmXE.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
var e={title:`Farterrogator`,subtitle:`ИИ-анализатор изображений`,copyright:`Farterrogator © {{year}} Fartcore. Все права защищены. Модели не являются собственностью Fartcore и предоставляются бесплатно.`,logoAlt:`Логотип Farterrogator`,modelsNotice:`Новое: теперь доступно несколько моделей теггера! Выберите одну в настройках.`,madeBy:`сделано <mooshieblob>mooshieblob</mooshieblob> и <ashtaka>ashtaka</ashtaka>`},t={close:`Закрыть`,changeLanguage:`Сменить язык`,languageSelection:`Выбор языка`},n={whatIsThis:`Что это?`,poweredBy:`Модель: {{model}}`,nothingYet:`Нет`},r={inputImage:`Входное изображение`,dragDrop:`Перетащите изображение сюда или нажмите для выбора`,dropHere:`Отпустите файлы здесь`,supports:`Поддерживаются PNG, JPG, WEBP, GIF`,supportsArchives:`(+ ZIP, TAR)`,clear:`Убрать изображение`,interrogate:`Анализировать`,previewAlt:`Предпросмотр загруженного изображения`,filesSelected:`Выбрано файлов: {{num}}`,batchReady:`Готово к пакетной обработке`},i={title:`Результат анализа`,ready:`Готово к анализу`,readySub:`Загрузите изображение, чтобы начать тегирование`,failed:`Ошибка анализа`,troubleshoot:`Устранение неполадок:`,troubleshootTagger:`Убедитесь, что теггер доступен по адресу {{endpoint}}`,processing:`Обработка...`,analyzing:`Анализ...`,technicalTags:`Теги`,noTags:`При текущем пороге теги не найдены.`,copyAll:`Копировать всё`,copied:`Скопировано!`,copiedItem:`Скопировано: {{item}}`,naiReady:`NAI Ready`,downloadNai:`Скачать со встроенными тегами`,tagsCopied:`Все теги скопированы в буфер обмена!`,embedFailed:`Не удалось создать изображение NAI Ready.`,score:`Оценка`,batchResults:`Результаты пакетной обработки`,artistSimilarity:`Сходство с художниками`,matchingArtists:`Подбор стилей художников...`,copyArtist:`Скопировать имя художника`,noPreview:`Нет превью`,openOnDanbooru:`Открыть на Danbooru`,openArtistOnDanbooru:`Открыть {{artist}} на Danbooru`},a={starting:`Запуск...`,analyzingImage:`Анализ изображения...`,done:`Готово`},o={title:`Настройки`,thresholds:`Пороги`,outputSettings:`Вывод`,topK:`Топ-K тегов`,randomize:`Случайный порядок`,removeUnderscores:`Убрать подчёркивания`,scoreDescend:`Сортировать по оценке`,includeRanks:`Добавлять оценки к тегам`,useEscape:`Экранировать скобки`,advancedThresholds:`Расширенный`,backend:{model:`Модель теггера`,baseUrl:`API URL`,baseUrlHint:`URL API-эндпоинта, напр. https://localtagger.gpu.garden или http://localhost:8000`,families:{wd14:`Семейство WD`,animetimm:`AnimeTimm`,camie:`Camie`},models:{},gatedHint:`Требуется токен Hugging Face на сервере.`,warmupHint:`Модель ещё не загружена — первый запрос может занять больше времени.`,onlineHint:`Бэкенд в сети.`,offlineHint:`Бэкенд недоступен. Проверьте URL API или работает ли сервер.`,resetToDefault:`Сбросить на умолчание`},categories:{general:`Общие`,character:`Персонаж`,copyright:`Копирайт`,artist:`Художник`,meta:`Мета`,rating:`Рейтинг`},maxTags:`Макс. тегов (0 = без ограничений)`,whitelist:`Белый список тегов`,whitelistPlaceholder:`напр. masterpiece, best quality`,blacklist:`Чёрный список тегов`,blacklistPlaceholder:`напр. watermark, signature`},s={taggerRequired:`Требуется базовый URL теггера. Настройте его в параметрах бэкенда.`,taggerError:`Ошибка теггера: {{status}} {{statusText}}`,batchTaggerError:`Ошибка пакетного теггера: {{status}} {{statusText}}`,kaloscopeError:`Ошибка Kaloscope: {{status}} {{statusText}}`,unknown:`Произошла неизвестная ошибка`},c={title:`Что такое Farterrogator?`,description:`<strong>Farterrogator</strong> — это быстрый локальный теггер изображений в стиле Booru. Он анализирует изображения с помощью моделей семейства WD EVA 02 и моделей, ориентированных на иллюстрации, извлекая совместимые с Danbooru теги для создания датасетов и инженерии промптов.`,features:{models:{title:`Несколько моделей теггера`,description:`Выбирайте между моделями <strong>WD SwinV2</strong>, <strong>WD EVA02</strong>, <strong>AnimeTimm</strong> и <strong>Camie</strong> — плюс определение сходства стиля художника Kaloscope.`},naiReady:{title:`Встраивание NAI Ready`,description:`Автоматически встраивает сгенерированные теги в метаданные PNG. Полученные изображения «NAI Ready» — просто перетащите их в NovelAI, и промпты заполнятся автоматически.`},privacy:{title:`Конфиденциальность и производительность`,description:`Вся инференция выполняется на настроенном бэкенде (gpu.garden или локально). Облачные API-ключи не требуются.`},gpuGarden:{title:`Интеграция с GPU Garden`,description:`Оптимизировано для инфраструктуры gpu.garden с автоматической маршрутизацией CORS-прокси.`}},howTo:{title:`Как пользоваться`,step1:`Загрузите изображение или перетащите его на холст.`,step2:`Выберите модель теггера — список загружается с бэкенда.`,step3:`Настройте пороги уверенности для фильтрации тегов.`,step4:`Нажмите <strong>Анализировать</strong>.`,step5:`Скопируйте теги или скачайте PNG <strong>NAI Ready</strong>.`},madeBy:`Сделано`},l={label:`Выбор темы`,light:`Светлая тема`,auto:`Как в системе`,dark:`Тёмная тема`},u={app:e,common:t,header:n,upload:r,results:i,status:a,settings:o,errors:s,info:c,theme:l};export{e as app,t as common,u as default,s as errors,n as header,c as info,i as results,o as settings,a as status,l as theme,r as upload};
|
dist/assets/vendor-_ab0A6TJ.js
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
dist/assets/vendor-files-BrsAlTsV.js
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
dist/assets/zh-CN-juOm4LJT.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
var e={title:`Farterrogator`,subtitle:`AI 图像反推工具`,copyright:`Farterrogator © {{year}} Fartcore。版权所有。模型不属于 Fartcore,且免费提供。`,logoAlt:`Farterrogator 标志`,modelsNotice:`新功能:现已支持多个标注模型!请在设置中选择。`,madeBy:`由 <mooshieblob>mooshieblob</mooshieblob> 和 <ashtaka>ashtaka</ashtaka> 制作`},t={close:`关闭`,changeLanguage:`切换语言`,languageSelection:`语言选择`},n={whatIsThis:`这是什么?`,poweredBy:`模型: {{model}}`,nothingYet:`无`},r={inputImage:`输入图像`,dragDrop:`将图像拖放到此处,或点击选择`,dropHere:`将文件放到这里`,supports:`支持 PNG、JPG、WEBP、GIF`,supportsArchives:`(+ ZIP、TAR)`,clear:`清除图像`,interrogate:`开始反推`,previewAlt:`已上传图像预览`,filesSelected:`已选择 {{num}} 个文件`,batchReady:`已准备好批量处理`},i={title:`分析结果`,ready:`准备就绪`,readySub:`上传图像以开始标注`,failed:`分析失败`,troubleshoot:`故障排查:`,troubleshootTagger:`请确认标注器可在 {{endpoint}} 访问`,processing:`处理中...`,analyzing:`分析中...`,technicalTags:`标签`,noTags:`在当前阈值下未找到标签。`,copyAll:`全部复制`,copied:`已复制!`,copiedItem:`已复制: {{item}}`,naiReady:`NAI Ready`,downloadNai:`下载含嵌入标签的图像`,tagsCopied:`所有标签已复制到剪贴板!`,embedFailed:`创建 NAI Ready 图像失败。`,score:`置信度`,batchResults:`批量结果`,artistSimilarity:`画师相似度`,matchingArtists:`正在匹配画师风格...`,copyArtist:`复制画师名称`,noPreview:`无预览`,openOnDanbooru:`在 Danbooru 上打开`,openArtistOnDanbooru:`在 Danbooru 上打开 {{artist}}`},a={starting:`正在启动...`,analyzingImage:`正在分析图像...`,done:`完成`},o={title:`设置`,thresholds:`阈值`,outputSettings:`输出`,topK:`前 K 个标签`,randomize:`随机排序`,removeUnderscores:`移除下划线`,scoreDescend:`按分数排序`,includeRanks:`在标签后附加分数`,useEscape:`转义括号`,advancedThresholds:`高级`,backend:{model:`标注模型`,baseUrl:`API 地址`,baseUrlHint:`API 端点地址,例如 https://localtagger.gpu.garden 或 http://localhost:8000`,families:{wd14:`WD 系列`,animetimm:`AnimeTimm`,camie:`Camie`},models:{},gatedHint:`需要服务器端配置 Hugging Face 令牌。`,warmupHint:`模型尚未加载——首次请求可能需要更长时间。`,onlineHint:`后端在线。`,offlineHint:`无法连接后端。请检查 API URL 或服务器是否在运行。`,resetToDefault:`重置为默认`},categories:{general:`一般`,character:`角色`,copyright:`版权作品`,artist:`画师`,meta:`元数据`,rating:`分级`},maxTags:`最大标签数 (0 = 不限)`,whitelist:`标签白名单`,whitelistPlaceholder:`例如 masterpiece, best quality`,blacklist:`标签黑名单`,blacklistPlaceholder:`例如 watermark, signature`},s={taggerRequired:`需要标注器的基础 URL。请在后端设置中配置。`,taggerError:`标签器错误:{{status}} {{statusText}}`,batchTaggerError:`批量标签器错误:{{status}} {{statusText}}`,kaloscopeError:`Kaloscope 错误:{{status}} {{statusText}}`,unknown:`发生未知错误`},c={title:`Farterrogator 是什么?`,description:`<strong>Farterrogator</strong> 是一款快速的本地 Booru 风格图像标注工具。它使用 WD EVA 02 系列和插画特化模型分析图像,提取兼容 Danbooru 的标签,用于数据集制作和提示词工程。`,features:{models:{title:`多种标注模型`,description:`可在 <strong>WD SwinV2</strong>、<strong>WD EVA02</strong>、<strong>AnimeTimm</strong> 和 <strong>Camie</strong> 模型之间选择,另有 Kaloscope 画师风格相似度。`},naiReady:{title:`NAI Ready 嵌入`,description:`自动将生成的标签嵌入 PNG 元数据。生成的图像即为 "NAI Ready"——直接拖入 NovelAI 即可自动填充提示词。`},privacy:{title:`隐私与性能`,description:`所有推理都在配置的后端 (gpu.garden 或本地) 上运行。无需云端 API 密钥。`},gpuGarden:{title:`GPU Garden 集成`,description:`针对 gpu.garden 基础设施优化,自动进行 CORS 代理路由。`}},howTo:{title:`使用方法`,step1:`上传图像,或将其拖放到画布上。`,step2:`选择标注模型——列表从后端加载。`,step3:`调整置信度阈值以过滤标签。`,step4:`点击<strong>开始反推</strong>。`,step5:`复制标签,或下载 <strong>NAI Ready</strong> PNG。`},madeBy:`制作者`},l={label:`主题选择`,light:`浅色模式`,auto:`跟随系统`,dark:`深色模式`},u={app:e,common:t,header:n,upload:r,results:i,status:a,settings:o,errors:s,info:c,theme:l};export{e as app,t as common,u as default,s as errors,n as header,c as info,i as results,o as settings,a as status,l as theme,r as upload};
|
dist/assets/zh-TW-DcQy6Mhc.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
var e={title:`Farterrogator`,subtitle:`AI 圖像反推工具`,copyright:`Farterrogator © {{year}} Fartcore。版權所有。模型不屬於 Fartcore,且免費提供。`,logoAlt:`Farterrogator 標誌`,modelsNotice:`新功能:現已支援多個標註模型!請在設定中選擇。`,madeBy:`由 <mooshieblob>mooshieblob</mooshieblob> 和 <ashtaka>ashtaka</ashtaka> 製作`},t={close:`關閉`,changeLanguage:`切換語言`,languageSelection:`語言選擇`},n={whatIsThis:`這是什麼?`,poweredBy:`模型: {{model}}`,nothingYet:`無`},r={inputImage:`輸入圖像`,dragDrop:`將圖像拖放到此處,或點擊選擇`,dropHere:`將檔案放到這裡`,supports:`支援 PNG、JPG、WEBP、GIF`,supportsArchives:`(+ ZIP、TAR)`,clear:`清除圖像`,interrogate:`開始反推`,previewAlt:`已上傳圖像預覽`,filesSelected:`已選擇 {{num}} 個檔案`,batchReady:`已準備好批次處理`},i={title:`分析結果`,ready:`準備就緒`,readySub:`上傳圖像以開始標註`,failed:`分析失敗`,troubleshoot:`疑難排解:`,troubleshootTagger:`請確認標註器可在 {{endpoint}} 存取`,processing:`處理中...`,analyzing:`分析中...`,technicalTags:`標籤`,noTags:`在目前閾值下未找到標籤。`,copyAll:`全部複製`,copied:`已複製!`,copiedItem:`已複製: {{item}}`,naiReady:`NAI Ready`,downloadNai:`下載含嵌入標籤的圖像`,tagsCopied:`所有標籤已複製到剪貼簿!`,embedFailed:`建立 NAI Ready 圖像失敗。`,score:`信賴度`,batchResults:`批次結果`,artistSimilarity:`繪師相似度`,matchingArtists:`正在比對繪師風格...`,copyArtist:`複製繪師名稱`,noPreview:`無預覽`,openOnDanbooru:`在 Danbooru 上開啟`,openArtistOnDanbooru:`在 Danbooru 上開啟 {{artist}}`},a={starting:`正在啟動...`,analyzingImage:`正在分析圖像...`,done:`完成`},o={title:`設定`,thresholds:`閾值`,outputSettings:`輸出`,topK:`前 K 個標籤`,randomize:`隨機排序`,removeUnderscores:`移除底線`,scoreDescend:`依分數排序`,includeRanks:`在標籤後附加分數`,useEscape:`跳脫括號`,advancedThresholds:`進階`,backend:{model:`標註模型`,baseUrl:`API 地址`,baseUrlHint:`API 端點地址,例如 https://localtagger.gpu.garden 或 http://localhost:8000`,families:{wd14:`WD 系列`,animetimm:`AnimeTimm`,camie:`Camie`},models:{},gatedHint:`需要伺服器端設定 Hugging Face 權杖。`,warmupHint:`模型尚未載入——首次請求可能需要更長時間。`,onlineHint:`後端在線。`,offlineHint:`無法連線後端。請檢查 API URL 或伺服器是否正在執行。`,resetToDefault:`重設為預設`},categories:{general:`一般`,character:`角色`,copyright:`版權作品`,artist:`繪師`,meta:`中繼資料`,rating:`分級`},maxTags:`最大標籤數 (0 = 不限)`,whitelist:`標籤白名單`,whitelistPlaceholder:`例如 masterpiece, best quality`,blacklist:`標籤黑名單`,blacklistPlaceholder:`例如 watermark, signature`},s={taggerRequired:`需要標註器的基礎 URL。請在後端設定中設定。`,taggerError:`標籤器錯誤:{{status}} {{statusText}}`,batchTaggerError:`批次標籤器錯誤:{{status}} {{statusText}}`,kaloscopeError:`Kaloscope 錯誤:{{status}} {{statusText}}`,unknown:`發生未知錯誤`},c={title:`Farterrogator 是什麼?`,description:`<strong>Farterrogator</strong> 是一款快速的本機 Booru 風格圖像標註工具。它使用 WD EVA 02 系列與插畫特化模型分析圖像,擷取相容 Danbooru 的標籤,用於資料集製作與提示詞工程。`,features:{models:{title:`多種標註模型`,description:`可在 <strong>WD SwinV2</strong>、<strong>WD EVA02</strong>、<strong>AnimeTimm</strong> 與 <strong>Camie</strong> 模型之間選擇,另有 Kaloscope 繪師風格相似度。`},naiReady:{title:`NAI Ready 嵌入`,description:`自動將產生的標籤嵌入 PNG 中繼資料。產生的圖像即為 "NAI Ready"——直接拖入 NovelAI 即可自動填入提示詞。`},privacy:{title:`隱私與效能`,description:`所有推論都在設定的後端 (gpu.garden 或本機) 上執行。無需雲端 API 金鑰。`},gpuGarden:{title:`GPU Garden 整合`,description:`針對 gpu.garden 基礎設施最佳化,自動進行 CORS 代理路由。`}},howTo:{title:`使用方法`,step1:`上傳圖像,或將其拖放到畫布上。`,step2:`選擇標註模型——清單從後端載入。`,step3:`調整信賴度閾值以過濾標籤。`,step4:`點擊<strong>開始反推</strong>。`,step5:`複製標籤,或下載 <strong>NAI Ready</strong> PNG。`},madeBy:`製作者`},l={label:`主題選擇`,light:`淺色模式`,auto:`跟隨系統`,dark:`深色模式`},u={app:e,common:t,header:n,upload:r,results:i,status:a,settings:o,errors:s,info:c,theme:l};export{e as app,t as common,u as default,s as errors,n as header,c as info,i as results,o as settings,a as status,l as theme,r as upload};
|
dist/danbooru_tags.csv
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
dist/favicon.png
ADDED
|
|
dist/favicon.webp
ADDED
|
|
dist/gpu-garden-logo.png
ADDED
|
dist/gpu-garden-logo.webp
ADDED
|
dist/index.html
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!doctype html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8" />
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 6 |
+
<title>Farterrogator</title>
|
| 7 |
+
<meta
|
| 8 |
+
name="description"
|
| 9 |
+
content="Use the best new and proved Danbooru AI image taggers for free in less than 10 seconds."
|
| 10 |
+
/>
|
| 11 |
+
|
| 12 |
+
<!-- Open Graph / Facebook -->
|
| 13 |
+
<meta property="og:type" content="website" />
|
| 14 |
+
<meta property="og:url" content="https://tagger.gpu.garden/" />
|
| 15 |
+
<meta property="og:title" content="Farterrogator" />
|
| 16 |
+
<meta
|
| 17 |
+
property="og:description"
|
| 18 |
+
content="Use the best new and proved Danbooru AI image taggers for free in less than 10 seconds."
|
| 19 |
+
/>
|
| 20 |
+
<meta
|
| 21 |
+
property="og:image"
|
| 22 |
+
content="https://tagger.gpu.garden/favicon.png"
|
| 23 |
+
/>
|
| 24 |
+
|
| 25 |
+
<!-- Twitter -->
|
| 26 |
+
<meta property="twitter:card" content="summary" />
|
| 27 |
+
<meta property="twitter:url" content="https://tagger.gpu.garden/" />
|
| 28 |
+
<meta property="twitter:title" content="Farterrogator" />
|
| 29 |
+
<meta
|
| 30 |
+
property="twitter:description"
|
| 31 |
+
content="Use the best new and proved Danbooru AI image taggers for free in less than 10 seconds."
|
| 32 |
+
/>
|
| 33 |
+
<meta
|
| 34 |
+
property="twitter:image"
|
| 35 |
+
content="https://tagger.gpu.garden/favicon.png"
|
| 36 |
+
/>
|
| 37 |
+
|
| 38 |
+
<link rel="icon" type="image/webp" href="/favicon.webp" />
|
| 39 |
+
|
| 40 |
+
<!-- Preconnects -->
|
| 41 |
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
| 42 |
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
| 43 |
+
<link rel="preconnect" href="https://gpu.garden" />
|
| 44 |
+
|
| 45 |
+
<!-- Fonts: Non-blocking load -->
|
| 46 |
+
<link
|
| 47 |
+
href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap"
|
| 48 |
+
rel="stylesheet"
|
| 49 |
+
media="print"
|
| 50 |
+
onload="this.media = 'all'"
|
| 51 |
+
/>
|
| 52 |
+
<noscript>
|
| 53 |
+
<link
|
| 54 |
+
href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap"
|
| 55 |
+
rel="stylesheet"
|
| 56 |
+
/>
|
| 57 |
+
</noscript>
|
| 58 |
+
|
| 59 |
+
<link
|
| 60 |
+
href="https://fonts.googleapis.com/css2?family=Noto+Sans+Devanagari:wght@400;500;700&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+TC:wght@400;500;700&display=swap"
|
| 61 |
+
rel="stylesheet"
|
| 62 |
+
media="print"
|
| 63 |
+
onload="this.media = 'all'"
|
| 64 |
+
/>
|
| 65 |
+
<noscript>
|
| 66 |
+
<link
|
| 67 |
+
href="https://fonts.googleapis.com/css2?family=Noto+Sans+Devanagari:wght@400;500;700&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+TC:wght@400;500;700&display=swap"
|
| 68 |
+
rel="stylesheet"
|
| 69 |
+
/>
|
| 70 |
+
</noscript>
|
| 71 |
+
<style>
|
| 72 |
+
body {
|
| 73 |
+
font-family: "Inter", sans-serif;
|
| 74 |
+
}
|
| 75 |
+
.font-mono {
|
| 76 |
+
font-family: "JetBrains Mono", monospace;
|
| 77 |
+
}
|
| 78 |
+
/* Custom scrollbar for tag lists */
|
| 79 |
+
::-webkit-scrollbar {
|
| 80 |
+
width: 8px;
|
| 81 |
+
height: 8px;
|
| 82 |
+
}
|
| 83 |
+
::-webkit-scrollbar-track {
|
| 84 |
+
background: transparent;
|
| 85 |
+
}
|
| 86 |
+
::-webkit-scrollbar-thumb {
|
| 87 |
+
background: #cbd5e1;
|
| 88 |
+
border-radius: 4px;
|
| 89 |
+
}
|
| 90 |
+
.dark ::-webkit-scrollbar-thumb {
|
| 91 |
+
background: #475569;
|
| 92 |
+
}
|
| 93 |
+
::-webkit-scrollbar-thumb:hover {
|
| 94 |
+
background: #f87171; /* red-400 */
|
| 95 |
+
}
|
| 96 |
+
.dark ::-webkit-scrollbar-thumb:hover {
|
| 97 |
+
background: #991b1b; /* red-800 */
|
| 98 |
+
}
|
| 99 |
+
</style>
|
| 100 |
+
<script type="module" crossorigin src="/assets/index-BQRSZhA2.js"></script>
|
| 101 |
+
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-BHe-jwch.js">
|
| 102 |
+
<link rel="modulepreload" crossorigin href="/assets/vendor-_ab0A6TJ.js">
|
| 103 |
+
<link rel="modulepreload" crossorigin href="/assets/vendor-files-BrsAlTsV.js">
|
| 104 |
+
<link rel="stylesheet" crossorigin href="/assets/index-BPgEO71u.css">
|
| 105 |
+
</head>
|
| 106 |
+
<body>
|
| 107 |
+
<div id="root"></div>
|
| 108 |
+
</body>
|
| 109 |
+
</html>
|
dist/robots.txt
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
User-agent: *
|
| 2 |
+
Allow: /
|