@enslo/sd-metadata 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ja.md CHANGED
@@ -11,7 +11,7 @@ AI生成画像に埋め込まれたメタデータを読み書きするための
11
11
  ## 特徴
12
12
 
13
13
  - **マルチフォーマット対応**: PNG (tEXt / iTXt)、JPEG (COM / Exif)、WebP (Exif)
14
- - **統一API**: シンプルな `read()` と `write()` 関数で全フォーマットに対応
14
+ - **シンプルAPI**: `read()`、`write()`、`embed()`、`stringify()` — 4つの関数で全ユースケースをカバー
15
15
  - **TypeScriptネイティブ**: TypeScriptで書かれており、型定義を完全同梱
16
16
  - **ゼロ依存**: Node.jsとブラウザで外部依存なしで動作
17
17
  - **フォーマット変換**: PNG、JPEG、WebP間でメタデータをシームレスに変換
@@ -95,10 +95,9 @@ const { read } = require('@enslo/sd-metadata');
95
95
  ### Node.jsでの使用
96
96
 
97
97
  ```typescript
98
- import { read, write } from '@enslo/sd-metadata';
99
- import { readFileSync, writeFileSync } from 'fs';
98
+ import { read, stringify } from '@enslo/sd-metadata';
99
+ import { readFileSync } from 'fs';
100
100
 
101
- // サポートされている任意のフォーマットからメタデータを読み込み
102
101
  const imageData = readFileSync('image.png');
103
102
  const result = read(imageData);
104
103
 
@@ -108,41 +107,50 @@ if (result.status === 'success') {
108
107
  console.log('Model:', result.metadata.model?.name);
109
108
  console.log('Size:', result.metadata.width, 'x', result.metadata.height);
110
109
  }
110
+
111
+ // 読みやすいテキストにフォーマット(任意のstatusで動作)
112
+ const text = stringify(result);
113
+ if (text) {
114
+ console.log(text);
115
+ }
111
116
  ```
112
117
 
113
118
  ### ブラウザでの使用
114
119
 
115
120
  ```typescript
116
- import { read } from '@enslo/sd-metadata';
121
+ import { read, softwareLabels } from '@enslo/sd-metadata';
117
122
 
118
123
  // ファイル入力を処理
119
124
  const fileInput = document.querySelector('input[type="file"]');
120
125
  fileInput.addEventListener('change', async (e) => {
121
126
  const file = e.target.files[0];
122
127
  if (!file) return;
123
-
128
+
124
129
  const arrayBuffer = await file.arrayBuffer();
125
130
  const result = read(arrayBuffer);
126
-
131
+
127
132
  if (result.status === 'success') {
128
- document.getElementById('tool').textContent = result.metadata.software;
133
+ document.getElementById('tool').textContent = softwareLabels[result.metadata.software];
129
134
  document.getElementById('prompt').textContent = result.metadata.prompt;
130
135
  document.getElementById('model').textContent = result.metadata.model?.name || 'N/A';
131
136
  }
132
137
  });
133
138
  ```
134
139
 
135
- ### CDN使用(ユーザースクリプト)
140
+ ### ユーザースクリプトでの使用
136
141
 
137
- ユーザースクリプト(Tampermonkey、Violentmonkeyなど)では、jsDelivr CDNから読み込みます:
142
+ ユーザースクリプト(Tampermonkey、Violentmonkeyなど)では、IIFEビルドを `@require` で読み込みます:
138
143
 
139
144
  ```javascript
140
- // CDNからインポート
141
- import { read } from 'https://cdn.jsdelivr.net/npm/@enslo/sd-metadata@latest/dist/index.js';
145
+ // ==UserScript==
146
+ // @name My Script
147
+ // @namespace https://example.com
148
+ // @require https://cdn.jsdelivr.net/npm/@enslo/sd-metadata@2.1.0/dist/index.global.js
149
+ // ==/UserScript==
142
150
 
143
151
  const response = await fetch(imageUrl);
144
152
  const arrayBuffer = await response.arrayBuffer();
145
- const result = read(arrayBuffer);
153
+ const result = sdMetadata.read(arrayBuffer);
146
154
 
147
155
  if (result.status === 'success') {
148
156
  console.log('Tool:', result.metadata.software);
@@ -151,11 +159,7 @@ if (result.status === 'success') {
151
159
  ```
152
160
 
153
161
  > [!TIP]
154
- > 本番環境では `@latest` の代わりに特定のバージョンを指定してください:
155
- >
156
- > ```text
157
- > https://cdn.jsdelivr.net/npm/@enslo/sd-metadata@2.0.0/dist/index.js
158
- > ```
162
+ > 安定性のため、`@require` では常に特定のバージョンを指定してください。
159
163
 
160
164
  ### 応用例
161
165
 
@@ -185,8 +189,7 @@ if (parseResult.status === 'success') {
185
189
  }
186
190
  ```
187
191
 
188
- > [!TIP]
189
- > このライブラリはメタデータの読み書きのみを扱います。実際の画像フォーマット変換(ピクセルのデコード/エンコード)には、[sharp](https://www.npmjs.com/package/sharp)、[jimp](https://www.npmjs.com/package/jimp)、ブラウザCanvas APIなどの画像処理ライブラリを使用してください。
192
+ > **Tip:** このライブラリはメタデータの読み書きのみを扱います。実際の画像フォーマット変換(ピクセルのデコード/エンコード)には、[sharp](https://www.npmjs.com/package/sharp)、[jimp](https://www.npmjs.com/package/jimp)、ブラウザCanvas APIなどの画像処理ライブラリを使用してください。
190
193
 
191
194
  </details>
192
195
 
@@ -309,8 +312,7 @@ const result = embed(imageData, {
309
312
  });
310
313
  ```
311
314
 
312
- > [!TIP]
313
- > extras のキーが構造化フィールド(例:`Steps`)と一致する場合、extras の値が元の位置で構造化フィールドを上書きします。新しいキーは末尾に追加されます。
315
+ > **Tip:** extras のキーが構造化フィールド(例:`Steps`)と一致する場合、extras の値が元の位置で構造化フィールドを上書きします。新しいキーは末尾に追加されます。
314
316
 
315
317
  `EmbedMetadata` はすべての `GenerationMetadata` バリアントのサブセットなので、パース結果のメタデータをそのまま渡せます — `characterPrompts` を持つ NovelAI も含めて:
316
318
 
@@ -353,10 +355,15 @@ if (text) {
353
355
 
354
356
  ## APIリファレンス
355
357
 
356
- ### `read(input: Uint8Array | ArrayBuffer): ParseResult`
358
+ ### `read(input: Uint8Array | ArrayBuffer, options?: ReadOptions): ParseResult`
357
359
 
358
360
  画像ファイルからメタデータを読み込み、パースします。
359
361
 
362
+ **パラメータ:**
363
+
364
+ - `input` - 画像ファイルデータ(PNG、JPEG、またはWebP)
365
+ - `options` - オプションの読み込み設定(詳細は[型ドキュメント](./docs/types.ja.md)を参照)
366
+
360
367
  **戻り値:**
361
368
 
362
369
  - `{ status: 'success', metadata, raw }` - パース成功
@@ -575,45 +582,28 @@ type RawMetadata =
575
582
  | { format: 'webp'; segments: MetadataSegment[] };
576
583
  ```
577
584
 
578
- > [!TIP]
579
- > TypeScriptユーザー向け:全ての型はエクスポートされており、インポートして使用できます。
580
- >
581
- > ```typescript
582
- > import type {
583
- > BaseMetadata,
584
- > EmbedMetadata,
585
- > ParseResult,
586
- > GenerationMetadata,
587
- > GenerationSoftware,
588
- > ModelSettings,
589
- > SamplingSettings
590
- > } from '@enslo/sd-metadata';
591
- > ```
592
- >
593
- > IDEのIntelliSenseを使用して自動補完とインラインドキュメントを活用してください。
594
-
595
585
  `ModelSettings`、`SamplingSettings`、フォーマット固有の型を含む全てのエクスポート型の詳細なドキュメントについては、[型ドキュメント](./docs/types.ja.md)を参照してください。
596
586
 
597
587
  ## 開発
598
588
 
599
589
  ```bash
600
590
  # 依存関係をインストール
601
- npm install
591
+ pnpm install
602
592
 
603
593
  # テストを実行
604
- npm test
605
-
606
- # ウォッチモード
607
- npm run test:watch
608
-
609
- # テストカバレッジ
610
- npm run test:coverage
594
+ pnpm test
611
595
 
612
596
  # ビルド
613
- npm run build
597
+ pnpm build
614
598
 
615
599
  # リント
616
- npm run lint
600
+ pnpm lint
601
+
602
+ # 型チェック
603
+ pnpm typecheck
604
+
605
+ # デモサイト起動
606
+ pnpm demo
617
607
  ```
618
608
 
619
609
  ## ライセンス
package/README.md CHANGED
@@ -11,7 +11,7 @@ A TypeScript library to read and write metadata embedded in AI-generated images.
11
11
  ## Features
12
12
 
13
13
  - **Multi-format Support**: PNG (tEXt / iTXt), JPEG (COM / Exif), WebP (Exif)
14
- - **Unified API**: Simple `read()` and `write()` functions work across all formats
14
+ - **Simple API**: `read()`, `write()`, `embed()`, `stringify()` — four functions cover all use cases
15
15
  - **TypeScript Native**: Written in TypeScript with full type definitions included
16
16
  - **Zero Dependencies**: Works in Node.js and browsers without any external dependencies
17
17
  - **Format Conversion**: Seamlessly convert metadata between PNG, JPEG, and WebP
@@ -95,8 +95,8 @@ const { read } = require('@enslo/sd-metadata');
95
95
  ### Node.js Usage
96
96
 
97
97
  ```typescript
98
- import { read, write } from '@enslo/sd-metadata';
99
- import { readFileSync, writeFileSync } from 'fs';
98
+ import { read, stringify } from '@enslo/sd-metadata';
99
+ import { readFileSync } from 'fs';
100
100
 
101
101
  const imageData = readFileSync('image.png');
102
102
  const result = read(imageData);
@@ -107,41 +107,50 @@ if (result.status === 'success') {
107
107
  console.log('Model:', result.metadata.model?.name);
108
108
  console.log('Size:', result.metadata.width, 'x', result.metadata.height);
109
109
  }
110
+
111
+ // Format as human-readable text (works with any status)
112
+ const text = stringify(result);
113
+ if (text) {
114
+ console.log(text);
115
+ }
110
116
  ```
111
117
 
112
118
  ### Browser Usage
113
119
 
114
120
  ```typescript
115
- import { read } from '@enslo/sd-metadata';
121
+ import { read, softwareLabels } from '@enslo/sd-metadata';
116
122
 
117
123
  // Handle file input
118
124
  const fileInput = document.querySelector('input[type="file"]');
119
125
  fileInput.addEventListener('change', async (e) => {
120
126
  const file = e.target.files[0];
121
127
  if (!file) return;
122
-
128
+
123
129
  const arrayBuffer = await file.arrayBuffer();
124
130
  const result = read(arrayBuffer);
125
-
131
+
126
132
  if (result.status === 'success') {
127
- document.getElementById('tool').textContent = result.metadata.software;
133
+ document.getElementById('tool').textContent = softwareLabels[result.metadata.software];
128
134
  document.getElementById('prompt').textContent = result.metadata.prompt;
129
135
  document.getElementById('model').textContent = result.metadata.model?.name || 'N/A';
130
136
  }
131
137
  });
132
138
  ```
133
139
 
134
- ### CDN Usage (Userscript)
140
+ ### Userscript Usage
135
141
 
136
- For userscripts (Tampermonkey, Violentmonkey, etc.), load from jsDelivr CDN:
142
+ For userscripts (Tampermonkey, Violentmonkey, etc.), load the IIFE build via `@require`:
137
143
 
138
144
  ```javascript
139
- // Import from CDN
140
- import { read } from 'https://cdn.jsdelivr.net/npm/@enslo/sd-metadata@latest/dist/index.js';
145
+ // ==UserScript==
146
+ // @name My Script
147
+ // @namespace https://example.com
148
+ // @require https://cdn.jsdelivr.net/npm/@enslo/sd-metadata@2.1.0/dist/index.global.js
149
+ // ==/UserScript==
141
150
 
142
151
  const response = await fetch(imageUrl);
143
152
  const arrayBuffer = await response.arrayBuffer();
144
- const result = read(arrayBuffer);
153
+ const result = sdMetadata.read(arrayBuffer);
145
154
 
146
155
  if (result.status === 'success') {
147
156
  console.log('Tool:', result.metadata.software);
@@ -150,11 +159,7 @@ if (result.status === 'success') {
150
159
  ```
151
160
 
152
161
  > [!TIP]
153
- > For production use, pin to a specific version instead of `@latest`:
154
- >
155
- > ```text
156
- > https://cdn.jsdelivr.net/npm/@enslo/sd-metadata@2.0.0/dist/index.js
157
- > ```
162
+ > Always pin to a specific version in `@require` for stability.
158
163
 
159
164
  ### Advanced Examples
160
165
 
@@ -184,8 +189,7 @@ if (parseResult.status === 'success') {
184
189
  }
185
190
  ```
186
191
 
187
- > [!TIP]
188
- > This library handles metadata read/write only. For actual image format conversion (decoding/encoding pixels), use image processing libraries like [sharp](https://www.npmjs.com/package/sharp), [jimp](https://www.npmjs.com/package/jimp), or browser Canvas API.
192
+ > **Tip:** This library handles metadata read/write only. For actual image format conversion (decoding/encoding pixels), use image processing libraries like [sharp](https://www.npmjs.com/package/sharp), [jimp](https://www.npmjs.com/package/jimp), or browser Canvas API.
189
193
 
190
194
  </details>
191
195
 
@@ -305,8 +309,7 @@ const result = embed(imageData, {
305
309
  });
306
310
  ```
307
311
 
308
- > [!TIP]
309
- > If an extras key matches a structured field (e.g., `Steps`), the extras value overrides the structured value at its original position. New keys are appended at the end.
312
+ > **Tip:** If an extras key matches a structured field (e.g., `Steps`), the extras value overrides the structured value at its original position. New keys are appended at the end.
310
313
 
311
314
  Since `EmbedMetadata` is a subset of all `GenerationMetadata` variants, you can pass parsed metadata directly — including NovelAI with its `characterPrompts`:
312
315
 
@@ -349,10 +352,15 @@ if (text) {
349
352
 
350
353
  ## API Reference
351
354
 
352
- ### `read(input: Uint8Array | ArrayBuffer): ParseResult`
355
+ ### `read(input: Uint8Array | ArrayBuffer, options?: ReadOptions): ParseResult`
353
356
 
354
357
  Reads and parses metadata from an image file.
355
358
 
359
+ **Parameters:**
360
+
361
+ - `input` - Image file data (PNG, JPEG, or WebP)
362
+ - `options` - Optional read options (see [Type Documentation](./docs/types.md) for details)
363
+
356
364
  **Returns:**
357
365
 
358
366
  - `{ status: 'success', metadata, raw }` - Successfully parsed
@@ -574,45 +582,28 @@ type RawMetadata =
574
582
  | { format: 'webp'; segments: MetadataSegment[] };
575
583
  ```
576
584
 
577
- > [!TIP]
578
- > For TypeScript users: All types are exported and available for import.
579
- >
580
- > ```typescript
581
- > import type {
582
- > BaseMetadata,
583
- > EmbedMetadata,
584
- > ParseResult,
585
- > GenerationMetadata,
586
- > GenerationSoftware,
587
- > ModelSettings,
588
- > SamplingSettings
589
- > } from '@enslo/sd-metadata';
590
- > ```
591
- >
592
- > Use your IDE's IntelliSense for auto-completion and inline documentation.
593
-
594
585
  For detailed documentation of all exported types including `ModelSettings`, `SamplingSettings`, and format-specific types, see the [Type Documentation](./docs/types.md).
595
586
 
596
587
  ## Development
597
588
 
598
589
  ```bash
599
590
  # Install dependencies
600
- npm install
591
+ pnpm install
601
592
 
602
593
  # Run tests
603
- npm test
604
-
605
- # Watch mode
606
- npm run test:watch
607
-
608
- # Test coverage
609
- npm run test:coverage
594
+ pnpm test
610
595
 
611
596
  # Build
612
- npm run build
597
+ pnpm build
613
598
 
614
599
  # Lint
615
- npm run lint
600
+ pnpm lint
601
+
602
+ # Type check
603
+ pnpm typecheck
604
+
605
+ # Start demo site
606
+ pnpm demo
616
607
  ```
617
608
 
618
609
  ## License
@@ -0,0 +1,11 @@
1
+ "use strict";var sdMetadata=(()=>{var ge=Object.defineProperty;var rr=Object.getOwnPropertyDescriptor;var nr=Object.getOwnPropertyNames;var or=Object.prototype.hasOwnProperty;var sr=(e,t)=>{for(var r in t)ge(e,r,{get:t[r],enumerable:!0})},ir=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of nr(t))!or.call(e,o)&&o!==r&&ge(e,o,{get:()=>t[o],enumerable:!(n=rr(t,o))||n.enumerable});return e};var ar=e=>ir(ge({},"__esModule",{value:!0}),e);var go={};sr(go,{embed:()=>Te,formatAsWebUI:()=>L,formatRaw:()=>ve,read:()=>It,softwareLabels:()=>Zt,stringify:()=>Je,write:()=>qt,writeAsWebUI:()=>Te});var E=(e,t)=>t!==void 0?[{type:"tEXt",keyword:e,text:t}]:[],_e=(e,t)=>t!==void 0?[{type:"iTXt",keyword:e,compressionFlag:0,compressionMethod:0,languageTag:"",translatedKeyword:"",text:t}]:[],S=(e,t)=>e.find(r=>r.source.type===t),k=e=>{if(e!==void 0)return typeof e=="string"?e:JSON.stringify(e)};function ur(e){return e.replace(/[\u0100-\uffff]/g,t=>`\\u${t.charCodeAt(0).toString(16).padStart(4,"0")}`)}function D(e){return e.replace(/\\u([0-9a-fA-F]{4})/g,(t,r)=>String.fromCharCode(Number.parseInt(r,16)))}function cr(e){return/[^\x00-\xFF]/.test(e)}function h(e,t,r){if(t===void 0)return[];switch(r){case"dynamic":return(cr(t)?"iTXt":"tEXt")==="iTXt"?_e(e,t):E(e,t);case"text-unicode-escape":{let n=ur(t);return E(e,n)}case"text-utf8-raw":return E(e,t)}}function ne(e,t){return e.flatMap(([r,n])=>{let o=t[r]??t.default;return h(r,n,o)})}var a={ok:e=>({ok:!0,value:e}),error:e=>({ok:!1,error:e})};function G(e){return e instanceof ArrayBuffer?new Uint8Array(e):e}function ye(e,t){return(e[t]??0)|(e[t+1]??0)<<8|(e[t+2]??0)<<16}function U(e,t){return(e[t]??0)<<24|(e[t+1]??0)<<16|(e[t+2]??0)<<8|(e[t+3]??0)}function z(e,t){return(e[t]??0)|(e[t+1]??0)<<8|(e[t+2]??0)<<16|(e[t+3]??0)<<24}function he(e,t,r){e[t]=r>>>24&255,e[t+1]=r>>>16&255,e[t+2]=r>>>8&255,e[t+3]=r&255}function A(e,t){return String.fromCharCode(e[t]??0,e[t+1]??0,e[t+2]??0,e[t+3]??0)}function I(e,t,r){return r?(e[t]??0)|(e[t+1]??0)<<8:(e[t]??0)<<8|(e[t+1]??0)}function X(e,t,r){return r?(e[t]??0)|(e[t+1]??0)<<8|(e[t+2]??0)<<16|(e[t+3]??0)<<24:(e[t]??0)<<24|(e[t+1]??0)<<16|(e[t+2]??0)<<8|(e[t+3]??0)}function J(e,t){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++)if(e[r]!==t[r])return!1;return!0}function j(e,t,r,n){n?(e[t]=r&255,e[t+1]=r>>>8&255):(e[t]=r>>>8&255,e[t+1]=r&255)}function _(e,t,r,n){n?(e[t]=r&255,e[t+1]=r>>>8&255,e[t+2]=r>>>16&255,e[t+3]=r>>>24&255):(e[t]=r>>>24&255,e[t+1]=r>>>16&255,e[t+2]=r>>>8&255,e[t+3]=r&255)}function xe(e,t,r){e[t]=r&255,e[t+1]=r>>>8&255,e[t+2]=r>>>16&255,e[t+3]=r>>>24&255}function B(e){return e.length<8?!1:e[0]===137&&e[1]===80&&e[2]===78&&e[3]===71&&e[4]===13&&e[5]===10&&e[6]===26&&e[7]===10}function K(e){return e.length<2?!1:e[0]===255&&e[1]===216}function V(e){return e.length<12?!1:e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70&&e[8]===87&&e[9]===69&&e[10]===66&&e[11]===80}function W(e){return B(e)?"png":K(e)?"jpeg":V(e)?"webp":null}function se(e){let t=e.filter(f=>f.source.type==="exifImageDescription"||f.source.type==="exifMake"),r=e.filter(f=>f.source.type==="exifUserComment");if(t.length===0&&r.length===0)return new Uint8Array(0);let n=!0,o=[],s=[];for(let f of t)if(f.source.type==="exifImageDescription"){let C=Ne(f.data,f.source.prefix);o.push({tag:270,type:2,data:C})}else if(f.source.type==="exifMake"){let C=Ne(f.data,f.source.prefix);o.push({tag:271,type:2,data:C})}for(let f of r)if(f.source.type==="exifUserComment"){let C=pr(f.data);s.push({tag:37510,type:7,data:C})}let i=s.length>0;i&&o.push({tag:34665,type:4,data:new Uint8Array(4)}),o.sort((f,C)=>f.tag-C.tag),s.sort((f,C)=>f.tag-C.tag);let u=8,c=o.length,p=2+12*c+4,g=s.length,y=i?2+12*g+4:0,l=u,P=l+p,x=P+y;if(i){let f=o.find(C=>C.tag===34665);f&&_(f.data,0,P,n)}let b=new Map;for(let f of[...o,...s])f.data.length>4&&(b.set(f,x),x+=f.data.length,f.data.length%2!==0&&(x+=1));let le=x,w=new Uint8Array(le);w[0]=73,w[1]=73,j(w,2,42,n),_(w,4,l,n);let v=l;j(w,v,c,n),v+=2;for(let f of o)Re(w,v,f,b.get(f),n),v+=12;if(_(w,v,0,n),v+=4,i){j(w,v,g,n),v+=2;for(let f of s)Re(w,v,f,b.get(f),n),v+=12;_(w,v,0,n)}for(let[f,C]of b)w.set(f.data,C);return w}function Re(e,t,r,n,o){j(e,t,r.tag,o),j(e,t+2,r.type,o),_(e,t+4,r.data.length,o),r.data.length<=4?e.set(r.data,t+8):_(e,t+8,n??0,o)}function pr(e){let t=[];for(let n=0;n<e.length;n++){let o=e.charCodeAt(n);t.push(o&255),t.push(o>>8&255)}let r=new Uint8Array(8+t.length);return r[0]=85,r[1]=78,r[2]=73,r[3]=67,r[4]=79,r[5]=68,r[6]=69,r[7]=0,r.set(new Uint8Array(t),8),r}function Ne(e,t){let r=t?`${t}: ${e}`:e,n=new TextEncoder().encode(r),o=new Uint8Array(n.length+1);return o.set(n,0),o[n.length]=0,o}var Fe=225,Oe=254,mr=218,fr=217,be=new Uint8Array([69,120,105,102,0,0]);function $(e,t){if(!K(e))return a.error({type:"invalidSignature"});let r=t.filter(l=>l.source.type==="jpegCom"),n=t.filter(l=>l.source.type==="exifUserComment"||l.source.type==="exifImageDescription"||l.source.type==="exifMake"),o=dr(e);if(!o.ok)return o;let{beforeSos:s,scanData:i}=o.value,u=n.length>0?lr(n):null,c=r.map(l=>gr(l.data)),p=2;u&&(p+=u.length);for(let l of s)p+=l.length;for(let l of c)p+=l.length;p+=i.length;let g=new Uint8Array(p),y=0;g[y++]=255,g[y++]=216,u&&(g.set(u,y),y+=u.length);for(let l of s)g.set(l,y),y+=l.length;for(let l of c)g.set(l,y),y+=l.length;return g.set(i,y),a.ok(g)}function dr(e){let t=[],r=2;for(;r<e.length-1;){if(e[r]!==255)return a.error({type:"corruptedStructure",message:`Expected marker at offset ${r}`});for(;e[r]===255&&r<e.length-1;)r++;let n=e[r];if(r++,n===mr){let p=e.slice(r-2);return a.ok({beforeSos:t,scanData:p})}if(n===fr)return a.ok({beforeSos:t,scanData:new Uint8Array([255,217])});if(r+2>e.length)return a.error({type:"corruptedStructure",message:"Unexpected end of file"});let o=(e[r]??0)<<8|(e[r+1]??0),s=r-2,i=r+o;if(i>e.length)return a.error({type:"corruptedStructure",message:"Segment extends beyond file"});!(n===Fe&&r+2+6<=e.length&&e[r+2]===69&&e[r+3]===120&&e[r+4]===105&&e[r+5]===102&&e[r+6]===0&&e[r+7]===0)&&!(n===Oe)&&t.push(e.slice(s,i)),r=i}return a.error({type:"corruptedStructure",message:"No SOS marker found"})}function lr(e){let t=se(e);if(t.length===0)return new Uint8Array(0);let r=2+be.length+t.length,n=new Uint8Array(2+r);return n[0]=255,n[1]=Fe,n[2]=r>>8&255,n[3]=r&255,n.set(be,4),n.set(t,4+be.length),n}function gr(e){let t=new TextEncoder().encode(e),r=2+t.length,n=new Uint8Array(2+r);return n[0]=255,n[1]=Oe,n[2]=r>>8&255,n[3]=r&255,n.set(t,4),n}var q=new Uint8Array([137,80,78,71,13,10,26,10]);function Z(e,t){if(!B(e))return a.error({type:"invalidSignature"});if(yr(e)===-1)return a.error({type:"noIhdrChunk"});let n=hr(e),o=t.map(c=>c.type==="tEXt"?xr(c):Sr(c)),s=q.length+n.ihdr.length+o.reduce((c,p)=>c+p.length,0)+n.others.reduce((c,p)=>c+p.length,0),i=new Uint8Array(s),u=0;i.set(q,u),u+=q.length,i.set(n.ihdr,u),u+=n.ihdr.length;for(let c of o)i.set(c,u),u+=c.length;for(let c of n.others)i.set(c,u),u+=c.length;return a.ok(i)}function yr(e){let t=q.length;if(t+8>e.length)return-1;let r=U(e,t);return A(e,t+4)!=="IHDR"?-1:t+4+4+r+4}function hr(e){let t=[],r=q.length,n=new Uint8Array(0);for(;r<e.length;){let o=r;if(r+4>e.length)break;let s=U(e,r);if(r+=4,r+4>e.length)break;let i=A(e,r);r+=4,r+=s,r+=4;let u=r,c=e.slice(o,u);if(i==="IHDR"?n=c:i!=="tEXt"&&i!=="iTXt"&&t.push(c),i==="IEND")break}return{ihdr:n,others:t}}function xr(e){let t=Cr(e.keyword),r=Y(e.text),n=new Uint8Array(t.length+1+r.length);return n.set(t,0),n[t.length]=0,n.set(r,t.length+1),De("tEXt",n)}function Sr(e){let t=Y(e.keyword),r=Y(e.languageTag),n=Y(e.translatedKeyword),o=Y(e.text),s=t.length+1+1+1+r.length+1+n.length+1+o.length,i=new Uint8Array(s),u=0;return i.set(t,u),u+=t.length,i[u++]=0,i[u++]=e.compressionFlag,i[u++]=e.compressionMethod,i.set(r,u),u+=r.length,i[u++]=0,i.set(n,u),u+=n.length,i[u++]=0,i.set(o,u),De("iTXt",i)}function De(e,t){let r=new Uint8Array(8+t.length+4);he(r,0,t.length);for(let s=0;s<4;s++)r[4+s]=e.charCodeAt(s);r.set(t,8);let n=r.slice(4,8+t.length),o=wr(n);return he(r,8+t.length,o),r}function Cr(e){let t=new Uint8Array(e.length);for(let r=0;r<e.length;r++)t[r]=e.charCodeAt(r)&255;return t}function Y(e){return new TextEncoder().encode(e)}var kr=br();function br(){let e=new Uint32Array(256);for(let t=0;t<256;t++){let r=t;for(let n=0;n<8;n++)r&1?r=3988292384^r>>>1:r=r>>>1;e[t]=r>>>0}return e}function wr(e){let t=4294967295;for(let r=0;r<e.length;r++)t=(kr[(t^(e[r]??0))&255]??0)^t>>>8;return(t^4294967295)>>>0}var vr=new Uint8Array([82,73,70,70]),Tr=new Uint8Array([87,69,66,80]),Ge=new Uint8Array([69,88,73,70]);function Q(e,t){if(!V(e))return a.error({type:"invalidSignature"});let r=Mr(e);if(!r.ok)return r;let{chunks:n}=r.value,o=Pr(t),s=4;for(let p of n)s+=p.length;o&&(s+=o.length);let i=new Uint8Array(8+s),u=0;i.set(vr,u),u+=4,xe(i,u,s),u+=4,i.set(Tr,u),u+=4;let c=!1;for(let p of n)i.set(p,u),u+=p.length,!c&&o&&Er(p)&&(i.set(o,u),u+=o.length,c=!0);return!c&&o&&i.set(o,u),a.ok(i)}function Er(e){if(e.length<4)return!1;let t=String.fromCharCode(e[0]??0,e[1]??0,e[2]??0,e[3]??0);return t==="VP8 "||t==="VP8L"||t==="VP8X"}function Mr(e){let t=[],r="",n=12;for(;n<e.length-8;){let o=e.slice(n,n+4),s=String.fromCharCode(o[0]??0,o[1]??0,o[2]??0,o[3]??0);r||(r=s);let i=(e[n+4]??0)|(e[n+5]??0)<<8|(e[n+6]??0)<<16|(e[n+7]??0)<<24;if(n+8+i>e.length)return a.error({type:"invalidRiffStructure",message:`Chunk extends beyond file at offset ${n}`});if(!J(o,Ge)){let c=i+i%2,p=e.slice(n,n+8+c);t.push(p)}let u=i+i%2;n+=8+u}return a.ok({chunks:t,firstChunkType:r})}function Pr(e){let t=e.filter(i=>i.source.type==="exifUserComment"||i.source.type==="exifImageDescription"||i.source.type==="exifMake");if(t.length===0)return null;let r=se(t);if(r.length===0)return null;let n=r.length,o=n+n%2,s=new Uint8Array(8+o);return s.set(Ge,0),xe(s,4,n),s.set(r,8),s}function we(e){return e.replace(/\r\n/g,`
2
+ `).replace(/\r/g,`
3
+ `)}function Ur(e){return e.flatMap((t,r)=>{let n=t.center?` [${t.center.x}, ${t.center.y}]`:"";return[`# Character ${r+1}${n}:`,we(t.prompt)]})}function Ar(e,t){let r=e.hires??e.upscale,n={Steps:e.sampling?.steps,Sampler:e.sampling?.sampler,"Schedule type":e.sampling?.scheduler,"CFG scale":e.sampling?.cfg,Seed:e.sampling?.seed,Size:e.width>0&&e.height>0?`${e.width}x${e.height}`:void 0,"Model hash":e.model?.hash,Model:e.model?.name,"Clip skip":e.sampling?.clipSkip,"Denoising strength":r?.denoise,"Hires upscale":r?.scale,"Hires steps":r?.steps,"Hires upscaler":r?.upscaler};return Object.entries({...n,...t}).filter(([,o])=>o!==void 0).map(([o,s])=>`${o}: ${s}`).join(", ")}function L(e){return[we(e.prompt),e.characterPrompts?.length?Ur(e.characterPrompts).join(`
4
+ `):void 0,e.negativePrompt?`Negative prompt: ${we(e.negativePrompt)}`:void 0,Ar(e,e.extras)||void 0].filter(t=>t!==void 0).join(`
5
+ `)}function ve(e){switch(e.format){case"png":return e.chunks.map(t=>t.text).join(`
6
+
7
+ `);case"jpeg":case"webp":return e.segments.map(t=>t.data).join(`
8
+
9
+ `)}}function Je(e){if("status"in e)switch(e.status){case"success":return L(e.metadata);case"unrecognized":return ve(e.raw);case"empty":case"invalid":return""}return L(e)}function Te(e,t){let r=G(e),n=W(r);if(!n)return a.error({type:"unsupportedFormat"});let o=L(t),s=Ir(n,r,o);return s.ok?a.ok(s.value):a.error({type:"writeFailed",message:s.error.type})}function Ir(e,t,r){switch(e){case"png":return Z(t,h("parameters",r,"dynamic"));case"jpeg":return $(t,[{source:{type:"exifUserComment"},data:r}]);case"webp":return Q(t,[{source:{type:"exifUserComment"},data:r}])}}function d(e){let t=Object.fromEntries(Object.entries(e).filter(([,r])=>r!==void 0));return Object.keys(t).length===0?void 0:t}function ee(e,t){let r=e.parameters??e.UserComment;if(!r)return a.error({type:"unsupportedFormat"});let{prompt:n,negativePrompt:o,settings:s}=_r(r),i=Rr(s),u=i.get("Size")??"0x0",[c,p]=je(u),g=i.get("Model"),y=i.get("Model hash"),l=i.get("Sampler"),P=i.get("Schedule type"),x=R(i.get("Steps")),b=R(i.get("CFG scale")??i.get("CFG Scale")),le=R(i.get("Seed")),w=R(i.get("Clip skip")),v=R(i.get("Hires upscale")),f=i.get("Hires upscaler"),C=R(i.get("Hires steps")),Qt=R(i.get("Denoising strength")),er=i.get("Hires size"),[Ie]=je(er??""),tr=v??(Ie>0?Ie/c:void 0);return a.ok({software:t,prompt:n,negativePrompt:o,width:c,height:p,model:d({name:g,hash:y}),sampling:d({sampler:l,scheduler:P,steps:x,cfg:b,seed:le,clipSkip:w}),hires:d({scale:tr,upscaler:f,steps:C,denoise:Qt})})}function _r(e){let t=e.indexOf("Negative prompt:"),r=e.indexOf("Steps:");if(t===-1&&r===-1)return{prompt:e.trim(),negativePrompt:"",settings:""};if(t===-1){let o=e.lastIndexOf(`
10
+ `,r);return{prompt:e.slice(0,o).trim(),negativePrompt:"",settings:e.slice(o).trim()}}if(r===-1)return{prompt:e.slice(0,t).trim(),negativePrompt:e.slice(t+16).trim(),settings:""};let n=e.lastIndexOf(`
11
+ `,r);return{prompt:e.slice(0,t).trim(),negativePrompt:e.slice(t+16,n).trim(),settings:e.slice(n).trim()}}function Rr(e){let t=new Map;if(!e)return t;let r=/([A-Za-z][A-Za-z0-9 ]*?):\s*([^,]+?)(?=,\s*[A-Za-z][A-Za-z0-9 ]*?:|$)/g;for(let n of e.matchAll(r)){let o=(n[1]??"").trim(),s=(n[2]??"").trim();t.set(o,s)}return t}function je(e){let t=e.match(/(\d+)x(\d+)/);return t?[Number.parseInt(t[1]??"0",10),Number.parseInt(t[2]??"0",10)]:[0,0]}function R(e){if(e===void 0)return;let t=Number.parseFloat(e);return Number.isNaN(t)?void 0:t}function m(e){try{let t=JSON.parse(e);return Nr(t)}catch{return{ok:!1,error:{type:"parseError",message:"Invalid JSON"}}}}function Nr(e){if(e===null)return{ok:!0,type:"null",value:null};if(Array.isArray(e))return{ok:!0,type:"array",value:e};switch(typeof e){case"object":return{ok:!0,type:"object",value:e};case"string":return{ok:!0,type:"string",value:e};case"number":return{ok:!0,type:"number",value:e};case"boolean":return{ok:!0,type:"boolean",value:e};default:return{ok:!1,error:{type:"parseError",message:"Unexpected JSON type"}}}}var We=["KSampler","KSamplerAdvanced","SamplerCustomAdvanced","SamplerCustom","DetailerForEach"],Fr=["EmptyLatentImage"],Or=["SDXL Empty Latent Image (rgthree)"],Dr=["CheckpointLoaderSimple","CheckpointLoader"],Gr=["UNETLoader"],Jr=["CLIPSetLastLayer"],jr=["UpscaleModelLoader"],Le=["ImageScale","ImageScaleBy"],He=["LatentUpscale","LatentUpscaleBy"],ze=["VAEEncode","VAEEncodeTiled"];function Xe(e){let t={};for(let r of Object.values(e)){let n=r.class_type;!t.sampler&&We.includes(n)?t.sampler=r:!t.latentImage&&Fr.includes(n)?t.latentImage=r:!t.latentImageRgthree&&Or.includes(n)?t.latentImageRgthree=r:!t.checkpoint&&Dr.includes(n)?t.checkpoint=r:!t.unetLoader&&Gr.includes(n)?t.unetLoader=r:!t.clipSetLastLayer&&Jr.includes(n)?t.clipSetLastLayer=r:!t.hiresModelUpscale&&jr.includes(n)?t.hiresModelUpscale=r:!t.hiresImageScale&&Le.includes(n)?t.hiresImageScale=r:!t.latentUpscale&&He.includes(n)?t.latentUpscale=r:!t.vaeEncode&&ze.includes(n)&&(t.vaeEncode=r)}return t}function N(e,t){if(M(t))return e[String(t[0])]}function M(e){return Array.isArray(e)&&e.length===2&&(typeof e[0]=="string"||typeof e[0]=="number")&&typeof e[1]=="number"}function Be(e,t,r=10){if(r<=0)return"";let n=e[t];if(!n)return"";let o=n.inputs.text??n.inputs.prompt??n.inputs.Text;return typeof o=="string"?o:M(o)?Be(e,String(o[0]),r-1):""}function Wr(e,t){let r=N(e,t.inputs.guider);return r||t}function Ke(e,t){if(!t)return{promptText:"",negativeText:""};let r=Wr(e,t);return{promptText:Ee(e,r.inputs.positive,"positive"),negativeText:Ee(e,r.inputs.negative,"negative")}}function Ee(e,t,r,n=10){if(n<=0||!M(t))return"";let o=String(t[0]),s=Be(e,o);if(s)return s;let i=e[o];if(!i)return"";let u=i.inputs[r];return Ee(e,u,r,n-1)}function Ve(e,t){if(e){let r=Number(e.inputs.width)||0,n=Number(e.inputs.height)||0;if(r>0&&n>0)return{width:r,height:n}}if(t&&typeof t.inputs.dimensions=="string"){let r=t.inputs.dimensions.match(/^(\d+)\s*x\s*(\d+)/);if(r?.[1]&&r[2])return{width:Number.parseInt(r[1],10),height:Number.parseInt(r[2],10)}}return{width:0,height:0}}function Me(e,t){if(!t)return;if(t.class_type==="SamplerCustomAdvanced")return Lr(e,t);if(t.class_type==="SamplerCustom")return Hr(e,t);let r=t.inputs.seed;return M(r)&&(r=e[String(r[0])]?.inputs.seed),{seed:r,steps:t.inputs.steps,cfg:t.inputs.cfg,sampler:t.inputs.sampler_name,scheduler:t.inputs.scheduler,denoise:t.inputs.denoise}}function Lr(e,t){let r=N(e,t.inputs.noise),n=N(e,t.inputs.guider),o=N(e,t.inputs.sampler),s=N(e,t.inputs.sigmas);return{seed:r?.inputs.noise_seed,steps:s?.inputs.steps,cfg:n?.inputs.cfg,sampler:o?.inputs.sampler_name,scheduler:s?.inputs.scheduler,denoise:s?.inputs.denoise}}function Hr(e,t){let r=N(e,t.inputs.sampler),n=N(e,t.inputs.sigmas),o=t.inputs.noise_seed;return M(o)&&(o=e[String(o[0])]?.inputs.seed),{seed:o,steps:n?.inputs.steps,cfg:t.inputs.cfg,sampler:r?.inputs.sampler_name,scheduler:n?.inputs.scheduler,denoise:n?.inputs.denoise}}function $e(e,t){if(e?.inputs?.ckpt_name)return{name:String(e.inputs.ckpt_name)};if(t?.inputs?.unet_name)return{name:String(t.inputs.unet_name)}}function Ye(e){if(!e)return;let t=e.inputs.stop_at_clip_layer;if(typeof t=="number")return-t}function ie(e,t){if(!(t<=0||e<=0))return Math.round(e/t*100)/100}function zr(e,t){let r=t.inputs.latent_image;if(!M(r))return!1;let n=e[String(r[0])];if(!n)return!1;if(He.includes(n.class_type))return!0;if(!ze.includes(n.class_type))return!1;let o=n.inputs.pixels;if(!M(o))return!1;let s=e[String(o[0])];return s?Le.includes(s.class_type):!1}function qe(e){return Object.values(e).find(t=>We.includes(t.class_type)&&zr(e,t))}function Ze(e,t){let r=e.extraMetadata;if(typeof r=="string"){let n=m(r);if(n.ok&&n.type==="object")return n.value}if(t?.extraMetadata){let n=m(t.extraMetadata);if(n.ok&&n.type==="object")return n.value}}function Qe(e){if(!e)return;let t=Xr(e),r=Br(e);return d({prompt:e.prompt,negativePrompt:e.negativePrompt,width:e.width,height:e.height,model:e.baseModel?{name:e.baseModel}:void 0,...r,...t})}function Xr(e){if(!e.transformations)return{};let t=e.transformations.find(n=>n.type==="upscale");if(!t?.upscaleWidth)return{};let r=ie(t.upscaleWidth,e.width??0);return r===void 0?{}:{upscale:{scale:r}}}function Br(e){return e.seed===void 0&&e.steps===void 0&&e.cfgScale===void 0&&e.sampler===void 0?{}:{sampling:{seed:e.seed,steps:e.steps,cfg:e.cfgScale,sampler:e.sampler}}}var Kr=["extra","extraMetadata","resource-stack"];function te(e){let t=Vr(e);if(!t)return a.error({type:"unsupportedFormat"});let r=m(t);if(!r.ok||r.type!=="object")return a.error({type:"parseError",message:"Invalid JSON in prompt entry"});let n=r.value,o=Pe(n),s=Qe(Ze(n,e)),i=qr(s,o);return a.ok({software:"comfyui",nodes:Object.fromEntries(Object.entries(n).filter(([u])=>!Kr.includes(u))),...i})}function et(e){if(!e||typeof e.denoise!="number")return e;if(e.denoise>=1){let{denoise:t,...r}=e;return r}return e}function tt(e){return e.replace(/\0+$/,"").replace(/:\s*NaN\b/g,": null")}function Vr(e){if(e.prompt)return tt(e.prompt);let t=[e.UserComment,e.ImageDescription,e.Make,e.Prompt,e.Workflow];for(let r of t)if(r&&r.startsWith("{")){let n=tt(r),o=m(n);if(!o.ok||o.type!=="object")continue;if(o.value.prompt&&typeof o.value.prompt=="object")return JSON.stringify(o.value.prompt);if(Object.values(o.value).some(i=>i&&typeof i=="object"&&"class_type"in i))return n}}function Pe(e){let t=Xe(e),{promptText:r,negativeText:n}=Ke(e,t.sampler),{width:o,height:s}=Ve(t.latentImage,t.latentImageRgthree),i=qe(e),u=et(i?Me(e,i):void 0),c=$r(e,t,o),p=t.hiresModelUpscale?.inputs.model_name,g=et(Me(e,t.sampler)),y=Ye(t.clipSetLastLayer);return d({prompt:r||void 0,negativePrompt:n||void 0,width:o>0?o:void 0,height:s>0?s:void 0,model:$e(t.checkpoint,t.unetLoader),sampling:d({...g,clipSkip:y}),...Yr(p,c,u)})}function $r(e,t,r){let n=t.latentUpscale?.inputs;if(n?.scale_by!==void 0)return n.scale_by;let o=t.hiresImageScale?.inputs.width;if(o!==void 0){if(M(o)){let s=e[String(o[0])];return typeof s?.inputs.clip_scale=="number"?s.inputs.clip_scale:void 0}if(typeof o=="number")return ie(o,r)}}function Yr(e,t,r){return!e&&t===void 0&&!r?{}:r?{hires:{upscaler:e,scale:t,steps:r.steps,denoise:r.denoise}}:e?{upscale:{upscaler:e,scale:t}}:{}}function rt(e,t){if(!e&&!t)return;let r={};for(let n of[e,t])if(n)for(let[o,s]of Object.entries(n))s!==void 0&&(r[o]=s);return Object.keys(r).length>0?r:void 0}function qr(e,t){let r=rt(e?.upscale,t?.upscale),n=rt(e?.hires,t?.hires);return{prompt:t?.prompt??e?.prompt??"",negativePrompt:t?.negativePrompt??e?.negativePrompt??"",width:t?.width??e?.width??0,height:t?.height??e?.height??0,...d({model:t?.model??e?.model,sampling:t?.sampling??e?.sampling,hires:n,upscale:r})}}var Zr="invokeai_metadata",Qr="generation_data",en="smproj",Ue="extraMetadata",H="sui_image_params",it="swarm_version",tn="class_type",nt="noise_schedule",ot="v4_prompt",rn="uncond_scale",nn="civitai:",on="Civitai resources:",st="RuinedFooocus",sn="use_stable_diffusion_model",an='"Model"',un='"resolution"',cn='"base_model"';function at(e){let t=pn(e);if(t)return t;let r=fn(e);if(r)return r;let n=e.parameters??e.UserComment??e.Comment;return n?dn(n):null}function ut(e){return Zr in e?"invokeai":Qr in e?"tensorart":en in e?"stability-matrix":Ue in e?"civitai":null}function pn(e){if(e.Software?.startsWith("NovelAI"))return"novelai";let t=ut(e);if(t)return t;if("fooocus_scheme"in e)return"fooocus";if("use_stable_diffusion_model"in e)return"easydiffusion";if(e.parameters?.includes(H))return"swarmui";let n=e.UserComment??e.Comment;return n?.startsWith("{")?mn(n):null}function mn(e){try{let t=JSON.parse(e),r=ut(t);if(r)return r;if("prompt"in t&&"workflow"in t){let n=t.workflow,o=t.prompt,s=typeof n=="object"||typeof o=="object",i=typeof n=="string"&&n.startsWith("{")||typeof o=="string"&&o.startsWith("{");if(s||i)return"comfyui"}if(H in t)return"swarmui";if("prompt"in t&&"parameters"in t){let n=String(t.parameters||"");if(n.includes(H)||n.includes(it))return"swarmui"}}catch{}return null}function fn(e){if("prompt"in e&&"workflow"in e||"Prompt"in e&&"Workflow"in e||"workflow"in e||"Workflow"in e)return"comfyui";let t=e.prompt??e.Prompt;if(t?.startsWith("{")){if(t.includes(H))return"swarmui";if(t.includes(`"${Ue}"`))return"civitai";if(t.includes(tn))return"comfyui"}return null}function dn(e){return e.startsWith("{")?ln(e):gn(e)}function ln(e){return e.includes(H)?"swarmui":e.includes(`"software":"${st}"`)||e.includes(`"software": "${st}"`)?"ruined-fooocus":e.includes(`"${sn}"`)?"easydiffusion":e.includes(nn)||e.includes(`"${Ue}"`)?"civitai":e.includes(`"${ot}"`)||e.includes(`"${nt}"`)||e.includes(`"${rn}"`)||e.includes('"Software":"NovelAI"')||e.includes(`\\"${nt}\\"`)||e.includes(`\\"${ot}\\"`)?"novelai":e.includes(an)&&e.includes(un)?"hf-space":e.includes('"prompt"')&&e.includes(cn)?"fooocus":e.includes('"prompt"')||e.includes('"nodes"')?"comfyui":null}function gn(e){if(e.includes(H)||e.includes(it))return"swarmui";let t=e.match(/Version:\s*([^\s,]+)/);if(t){let r=t[1];if(r&&/^v\d/.test(r))return"sd-webui";if(r==="classic")return"forge-classic";if(r==="neo"||r?.startsWith("neo"))return"forge-neo";if(r?.startsWith("f")&&/^f\d/.test(r))return/^f\d+\.\d+(\.\d+)?-v/.test(r)?"easy-reforge":/^f\d+\.\d+(\.\d+)?v\d+-v/.test(r)?"reforge":"forge";if(r?.startsWith("Fooocus"))return"fooocus";if(r==="ComfyUI")return"comfyui"}return e.includes("App: SD.Next")||e.includes("App:SD.Next")?"sd-next":e.includes(on)?"civitai":e.includes("Steps:")||e.includes("Sampler:")||e.includes("Negative prompt:")?"sd-webui":null}function yn(e){if(!e)return;let t=e.replace(/\\/g,"/").split("/");return t[t.length-1]}function pt(e){if("use_stable_diffusion_model"in e)return ct(e);let t=e.UserComment?.startsWith("{")?e.UserComment:e.parameters?.startsWith("{")?e.parameters:void 0;if(!t)return a.error({type:"unsupportedFormat"});let r=m(t);return!r.ok||r.type!=="object"?a.error({type:"parseError",message:"Invalid JSON in Easy Diffusion metadata"}):ct(r.value)}function ct(e){let t=c=>{let p=e[c];return typeof p=="string"?p:void 0},r=c=>Number(e[c])||void 0,n=(t("prompt")??"").trim(),o=(t("negative_prompt")??"").trim(),s=t("use_stable_diffusion_model"),i=d({upscaler:t("use_upscale"),scale:r("upscale_amount")}),u={software:"easydiffusion",prompt:n,negativePrompt:o,width:r("width")??0,height:r("height")??0,model:d({name:yn(s),vae:t("use_vae_model")}),sampling:d({sampler:t("sampler_name"),steps:r("num_inference_steps"),cfg:r("guidance_scale"),seed:r("seed"),clipSkip:r("clip_skip"),denoise:r("prompt_strength")}),...i?{upscale:i}:{}};return a.ok(u)}function hn(e){if(!e)return{width:0,height:0};let t=e.match(/\(\s*(\d+)\s*,\s*(\d+)\s*\)/);return!t?.[1]||!t[2]?{width:0,height:0}:{width:Number(t[1]),height:Number(t[2])}}function mt(e){let t=e.parameters??e.UserComment;if(!t||!t.startsWith("{"))return a.error({type:"unsupportedFormat"});let r=m(t);if(!r.ok||r.type!=="object")return a.error({type:"parseError",message:"Invalid JSON in Fooocus metadata"});let n=r.value,{width:o,height:s}=hn(n.resolution),i={software:"fooocus",prompt:n.prompt?.trim()??"",negativePrompt:n.negative_prompt?.trim()??"",width:o,height:s,model:d({name:n.base_model,hash:n.base_model_hash,vae:n.vae}),sampling:d({sampler:n.sampler,scheduler:n.scheduler,steps:n.steps,cfg:n.guidance_scale,seed:n.seed,clipSkip:n.clip_skip})};return a.ok(i)}function ft(e){let t=e.parameters??e.UserComment;if(!t)return a.error({type:"unsupportedFormat"});let r=m(t);if(!r.ok||r.type!=="object")return a.error({type:"parseError",message:"Invalid JSON in parameters entry"});let n=r.value,o=c=>{let p=c?.match(/(\d+)\s*x\s*(\d+)/);return p?.[1]&&p?.[2]?{width:Number.parseInt(p[1],10),height:Number.parseInt(p[2],10)}:{width:0,height:0}},{width:s,height:i}=o(n.resolution),u={software:"hf-space",prompt:n.prompt??"",negativePrompt:n.negative_prompt??"",width:s,height:i,model:d({name:n.Model,hash:n["Model hash"]}),sampling:d({sampler:n.sampler,steps:n.num_inference_steps,cfg:n.guidance_scale,seed:n.seed}),hires:n.use_upscaler?d({upscaler:n.use_upscaler.upscale_method,denoise:n.use_upscaler.upscaler_strength,scale:n.use_upscaler.upscale_by,steps:n.use_upscaler.upscale_steps}):void 0};return a.ok(u)}function F(e,t){if(!e.UserComment?.startsWith("{"))return;let r=m(e.UserComment);if(!r.ok||r.type!=="object")return;let n=r.value[t];if(typeof n=="string")return n;if(typeof n=="object"&&n!==null)return JSON.stringify(n)}function xn(e){return e.invokeai_metadata??F(e,"invokeai_metadata")}function dt(e){let t=xn(e);if(!t)return a.error({type:"unsupportedFormat"});let r=m(t);if(!r.ok||r.type!=="object")return a.error({type:"parseError",message:"Invalid JSON in invokeai_metadata entry"});let n=r.value,o=n.width??0,s=n.height??0,i=Sn(n);return a.ok({software:"invokeai",prompt:n.positive_prompt??"",negativePrompt:n.negative_prompt??"",width:o,height:s,model:d({name:n.model?.name,hash:n.model?.hash}),sampling:d({seed:n.seed,steps:n.steps,cfg:n.cfg_scale,sampler:n.scheduler}),...i})}function Sn(e){if(!e.upscale_model?.name&&e.upscale_scale===void 0)return{};let t=d({upscaler:e.upscale_model?.name,scale:e.upscale_scale});return t?{upscale:t}:{}}function lt(e){let t=e.UserComment??e.Comment;if(!t)return a.error({type:"parseError",message:"Missing Comment/UserComment entry"});let r=m(t);if(!r.ok||r.type!=="object")return a.error({type:"parseError",message:"Invalid JSON in Comment entry"});let n=r.value,o=n.width??0,s=n.height??0,i=n.v4_prompt?.caption?.base_caption??n.prompt??"",u=n.v4_negative_prompt?.caption?.base_caption??n.uc??"",c=n.v4_prompt?.caption?.char_captions,p=c&&c.length>0?c.map(g=>g.char_caption?{prompt:g.char_caption,center:g.centers?.[0]}:null).filter(g=>g!==null):void 0;return a.ok({software:"novelai",prompt:i,negativePrompt:u,width:o,height:s,sampling:d({steps:n.steps,cfg:n.scale,seed:n.seed,sampler:n.sampler,scheduler:n.noise_schedule}),characterPrompts:p,useCoords:p?n.v4_prompt?.use_coords:void 0,useOrder:p?n.v4_prompt?.use_order:void 0})}function gt(e){let t=e.parameters??e.UserComment;if(!t||!t.startsWith("{"))return a.error({type:"unsupportedFormat"});let r=m(t);if(!r.ok||r.type!=="object")return a.error({type:"parseError",message:"Invalid JSON in Ruined Fooocus metadata"});let n=r.value,o={software:"ruined-fooocus",prompt:n.Prompt?.trim()??"",negativePrompt:n.Negative?.trim()??"",width:n.width??0,height:n.height??0,model:{name:n.base_model_name,hash:n.base_model_hash},sampling:{sampler:n.sampler_name,scheduler:n.scheduler,steps:n.steps,cfg:n.cfg,seed:n.seed,clipSkip:n.clip_skip}};return a.ok(o)}function yt(e){let t=te(e);if(!t.ok||t.value.software!=="comfyui")return a.error({type:"unsupportedFormat"});let r=e["parameters-json"]??F(e,"parameters-json"),n=r?m(r):void 0,o=n?.ok&&n.type==="object"?n.value:void 0;return a.ok({...t.value,software:"stability-matrix",prompt:o?.PositivePrompt??t.value.prompt,negativePrompt:o?.NegativePrompt??t.value.negativePrompt,model:o?.ModelName!==void 0||o?.ModelHash!==void 0?{name:o?.ModelName,hash:o?.ModelHash}:t.value.model})}function Cn(e){if(e.parameters)return e.parameters;if(!e.UserComment)return;let t=m(e.UserComment);if(!(!t.ok||t.type!=="object")&&"sui_image_params"in t.value)return e.UserComment}function ht(e){let t=Cn(e);if(!t)return a.error({type:"unsupportedFormat"});let r=m(t);if(!r.ok||r.type!=="object")return a.error({type:"parseError",message:"Invalid JSON in parameters entry"});let n=r.value.sui_image_params;if(!n)return a.error({type:"unsupportedFormat"});let o=n.width??0,s=n.height??0,i=e.prompt||e.Make,u=i?m(i):void 0,c=u?.ok&&u.type==="object"?u.value:void 0;return a.ok({software:"swarmui",prompt:n.prompt??"",negativePrompt:n.negativeprompt??"",width:o,height:s,nodes:c,model:d({name:n.model}),sampling:d({seed:n.seed,steps:n.steps,cfg:n.cfgscale,sampler:n.sampler,scheduler:n.scheduler}),hires:d({scale:n.refinerupscale,upscaler:n.refinerupscalemethod,denoise:n.refinercontrolpercentage})})}function xt(e){let t=e.generation_data??F(e,"generation_data"),r=e.prompt??F(e,"prompt");if(!t)return a.error({type:"unsupportedFormat"});let n=t.replace(/\0+$/,""),o=m(n);if(!o.ok||o.type!=="object")return a.error({type:"parseError",message:"Invalid JSON in generation_data entry"});let s=o.value;if(!r)return a.error({type:"unsupportedFormat"});let i=m(r);if(!i.ok||i.type!=="object")return a.error({type:"parseError",message:"Invalid JSON in prompt chunk"});let u=i.value,c=Pe(u),p=d({name:s.baseModel?.modelFileName,hash:s.baseModel?.hash});return a.ok({software:"tensorart",nodes:u,prompt:s.prompt??c?.prompt??"",negativePrompt:s.negativePrompt??c?.negativePrompt??"",width:c?.width??0,height:c?.height??0,model:p??c?.model,sampling:c?.sampling,hires:c?.hires,upscale:c?.upscale})}function St(e){let t=at(e);switch(t){case"novelai":return lt(e);case"sd-webui":case"forge":case"forge-classic":case"forge-neo":case"reforge":case"easy-reforge":case"sd-next":return ee(e,t);case"hf-space":return ft(e);case"civitai":{let r=te(e);return r.ok?(r.value.software="civitai",r):ee(e,"civitai")}case"comfyui":{let r=te(e);return r.ok?r:ee(e,"sd-webui")}case"invokeai":return dt(e);case"swarmui":return ht(e);case"tensorart":return xt(e);case"stability-matrix":return yt(e);case"easydiffusion":return pt(e);case"fooocus":{let r=e.fooocus_scheme,n=e.parameters??e.UserComment;return r==="a1111"||n&&!n.startsWith("{")?ee(e,"fooocus"):mt(e)}case"ruined-fooocus":return gt(e);default:return a.error({type:"unsupportedFormat"})}}function Ct(e,t){return t==="png"?kn(e):t==="jpeg"?bn(e):wn(e)}function kn(e){return e.length<24?null:{width:U(e,16),height:U(e,20)}}function bn(e){let t=2;for(;t<e.length-4;){if(e[t]!==255){t++;continue}let r=e[t+1]??0;if(r===255){t++;continue}let n=(e[t+2]??0)<<8|(e[t+3]??0);if(r>=192&&r<=207&&r!==196&&r!==200&&r!==204){let o=(e[t+5]??0)<<8|(e[t+6]??0);return{width:(e[t+7]??0)<<8|(e[t+8]??0),height:o}}if(t+=2+n,r===218)break}return null}function wn(e){let t=12;for(;t<e.length&&!(t+8>e.length);){let r=A(e,t),n=z(e,t+4),o=n+n%2;if(r==="VP8X"){let s=ye(e,t+12),i=ye(e,t+15);return{width:s+1,height:i+1}}if(r==="VP8 "){let s=t+8;if(!(((e[s]??0)|(e[s+1]??0)<<8|(e[s+2]??0)<<16)&1)&&e[s+3]===157&&e[s+4]===1&&e[s+5]===42){let c=(e[s+6]??0)|(e[s+7]??0)<<8,p=(e[s+8]??0)|(e[s+9]??0)<<8;return{width:c&16383,height:p&16383}}}if(r==="VP8L"&&e[t+8]===47){let s=z(e,t+9),i=(s&16383)+1,u=(s>>14&16383)+1;return{width:i,height:u}}t+=8+o}return null}function ae(e){if(e.length<8)return[];let t=e[0]===73&&e[1]===73,r=e[0]===77&&e[1]===77;if(!t&&!r)return[];if(I(e,2,t)!==42)return[];let o=X(e,4,t),s=kt(e,o,t),i=Tn(e,o,t),u=i!==null?kt(e,i,t):[];return[...s,...u]}function kt(e,t,r){let n=[];if(t+2>e.length)return n;let o=I(e,t,r),s=t+2;for(let i=0;i<o;i++){if(s+12>e.length)return n;let u=I(e,s,r),c=I(e,s+2,r),p=X(e,s+4,r),g=vn(c),y=p*g,l;if(y<=4?l=s+8:l=X(e,s+8,r),l+y>e.length){s+=12;continue}let P=e.slice(l,l+y);if(u===270){let x=wt(P);if(x){let b=bt(x);n.push({source:{type:"exifImageDescription",prefix:b??void 0},data:b?x.slice(b.length+2):x})}}else if(u===271){let x=wt(P);if(x){let b=bt(x);n.push({source:{type:"exifMake",prefix:b??void 0},data:b?x.slice(b.length+2):x})}}else if(u===37510){let x=En(P);x&&n.push({source:{type:"exifUserComment"},data:x})}s+=12}return n}function bt(e){return e.match(/^([A-Za-z]+):\s/)?.[1]??null}function vn(e){switch(e){case 1:return 1;case 2:return 1;case 3:return 2;case 4:return 4;case 5:return 8;case 7:return 1;default:return 1}}function wt(e){try{let r=new TextDecoder("utf-8",{fatal:!1}).decode(e);return r.endsWith("\0")&&(r=r.slice(0,-1)),r.trim()||null}catch{return null}}function Tn(e,t,r){if(t+2>e.length)return null;let n=I(e,t,r),o=t+2;for(let s=0;s<n;s++){if(o+12>e.length)return null;if(I(e,o,r)===34665)return X(e,o+8,r);o+=12}return null}function En(e){if(e.length<8)return null;if(e[0]===85&&e[1]===78&&e[2]===73&&e[3]===67&&e[4]===79&&e[5]===68&&e[6]===69&&e[7]===0){let t=e.slice(8);return t.length>=2&&t[0]!==0&&t[1]===0?Mn(t):vt(t)}if(e[0]===65&&e[1]===83&&e[2]===67&&e[3]===73&&e[4]===73&&e[5]===0&&e[6]===0&&e[7]===0)return Pn(e.slice(8));try{let r=new TextDecoder("utf-8",{fatal:!0}).decode(e);return r.endsWith("\0")&&(r=r.slice(0,-1)),r}catch{return null}}function vt(e){let t=[];for(let r=0;r<e.length-1;r+=2){let n=(e[r]??0)<<8|(e[r+1]??0);if(n===0)break;t.push(String.fromCharCode(n))}return t.join("")}function Mn(e){let t=[];for(let r=0;r<e.length-1;r+=2){let n=(e[r]??0)|(e[r+1]??0)<<8;if(n===0)break;t.push(String.fromCharCode(n))}return t.join("")}function Pn(e){let t=[];for(let r=0;r<e.length&&e[r]!==0;r++)t.push(String.fromCharCode(e[r]??0));return t.join("")}var Un=225,An=254,In=new Uint8Array([69,120,105,102,0,0]);function Tt(e){if(!K(e))return a.error({type:"invalidSignature"});let t=[],r=_n(e);if(r){let o=e.slice(r.offset,r.offset+r.length),s=ae(o);t.push(...s)}let n=Rn(e);if(n){let o=e.slice(n.offset,n.offset+n.length),s=Nn(o);s!==null&&t.push({source:{type:"jpegCom"},data:s})}return a.ok(t)}function _n(e){let t=2;for(;t<e.length-4;){if(e[t]!==255){t++;continue}let r=e[t+1];if(r===255){t++;continue}let n=(e[t+2]??0)<<8|(e[t+3]??0);if(r===Un){let o=t+4;if(o+6<=e.length){let s=e.slice(o,o+6);if(J(s,In))return{offset:o+6,length:n-8}}}if(t+=2+n,r===218||r===217)break}return null}function Rn(e){let t=2;for(;t<e.length-4;){if(e[t]!==255){t++;continue}let r=e[t+1];if(r===255){t++;continue}let n=(e[t+2]??0)<<8|(e[t+3]??0);if(r===An)return{offset:t+4,length:n-2};if(t+=2+n,r===218||r===217)break}return null}function Nn(e){try{return new TextDecoder("utf-8",{fatal:!0}).decode(e)}catch{return null}}function Mt(e){if(!B(e))return a.error({type:"invalidSignature"});let t=On(e);return t.ok?a.ok(t.value):t}var Fn=8;function On(e){let t=[],r=Fn;for(;r<e.length;){if(r+4>e.length)return a.error({type:"corruptedChunk",message:"Unexpected end of file while reading chunk length"});let n=U(e,r);if(r+=4,r+4>e.length)return a.error({type:"corruptedChunk",message:"Unexpected end of file while reading chunk type"});let o=A(e,r);if(r+=4,r+n>e.length)return a.error({type:"corruptedChunk",message:`Unexpected end of file while reading chunk data (${o})`});let s=e.slice(r,r+n);if(r+=n,r+=4,o==="tEXt"){let i=Dn(s);i&&t.push(i)}else if(o==="iTXt"){let i=Jn(s);i&&t.push(i)}if(o==="IEND")break}return a.ok(t)}function Dn(e){let t=e.indexOf(0);if(t===-1)return null;let r=Et(e.slice(0,t)),n=e.slice(t+1),o=Gn(n)??Et(n);return{type:"tEXt",keyword:r,text:o}}function Gn(e){try{return new TextDecoder("utf-8",{fatal:!0}).decode(e)}catch{return null}}function Jn(e){let t=0,r=Ae(e,t);if(r===-1)return null;let n=re(e.slice(t,r));if(t=r+1,t>=e.length)return null;let o=e[t]??0;if(t+=1,t>=e.length)return null;let s=e[t]??0;t+=1;let i=Ae(e,t);if(i===-1)return null;let u=re(e.slice(t,i));t=i+1;let c=Ae(e,t);if(c===-1)return null;let p=re(e.slice(t,c));t=c+1;let g;if(o===1){let y=jn(e.slice(t));if(!y)return null;g=re(y)}else g=re(e.slice(t));return{type:"iTXt",keyword:n,compressionFlag:o,compressionMethod:s,languageTag:u,translatedKeyword:p,text:g}}function Ae(e,t){for(let r=t;r<e.length;r++)if(e[r]===0)return r;return-1}function Et(e){let t="";for(let r=0;r<e.length;r++)t+=String.fromCharCode(e[r]??0);return t}function re(e){return new TextDecoder("utf-8").decode(e)}function jn(e){return null}var Wn=new Uint8Array([69,88,73,70]);function Pt(e){if(!V(e))return a.error({type:"invalidSignature"});let t=Ln(e);if(!t)return a.ok([]);let r=e.slice(t.offset,t.offset+t.length),n=ae(r);return a.ok(n)}function Ln(e){let t=12;for(;t<e.length-8;){let r=e.slice(t,t+4),n=z(e,t+4);if(J(r,Wn))return{offset:t+8,length:n};let o=n+n%2;t+=8+o}return null}function Ut(e){return Object.fromEntries(e.map(t=>[t.keyword,t.text]))}function At(e){let t={};for(let r of e){let n=zn(r.source),o=r.data;if(r.source.type==="exifUserComment"&&o.startsWith("{")){let s=Hn(o);if(s){Object.assign(t,s);continue}}t[n]=o}return t}function Hn(e){let t=m(e);if(!t.ok||t.type!=="object")return null;let r=t.value;if(typeof r.Software=="string"&&!r.Software.startsWith("NovelAI")||typeof r.Comment!="string")return null;let n=m(r.Comment);return{Software:typeof r.Software=="string"?r.Software:"NovelAI",Comment:n.ok?JSON.stringify(n.value):r.Comment}}function zn(e){switch(e.type){case"jpegCom":return"Comment";case"exifUserComment":return"UserComment";case"exifImageDescription":return e.prefix??"ImageDescription";case"exifMake":return e.prefix??"Make"}}function It(e,t){let r=G(e),n=W(r);if(!n)return{status:"invalid",message:"Unknown image format"};let o=Xn(r,n);if(o.status!=="success")return o;let s=o.raw,i=s.format==="png"?Ut(s.chunks):At(s.segments),u=St(i);if(!u.ok)return{status:"unrecognized",raw:s};let c=u.value;if(!t?.strict&&(c.width===0||c.height===0)){let p=Ct(r,n);p&&(c.width=c.width||p.width,c.height=c.height||p.height)}return{status:"success",metadata:c,raw:s}}function Xn(e,t){let r=t==="png"?Mt(e):t==="jpeg"?Tt(e):Pt(e);return r.ok?r.value.length===0?{status:"empty"}:t==="png"?{status:"success",raw:{format:"png",chunks:r.value}}:{status:"success",raw:{format:t,segments:r.value}}:{status:"invalid",message:r.error.type==="invalidSignature"?`Invalid ${t.toUpperCase()} signature`:r.error.message}}function ue(e){let t=e.find(r=>r.keyword==="parameters");return t?[{source:{type:"exifUserComment"},data:t.text}]:[]}function ce(e){let t=e.find(r=>r.source.type==="exifUserComment");return t?h("parameters",t.data,"dynamic"):[]}function _t(e){let t=e.find(n=>n.keyword==="parameters");if(t&&!t.text.trimStart().startsWith("{"))return ue(e);let r={};for(let n of e)if(n.keyword==="prompt"){let o=m(n.text);o.ok&&o.type==="object"&&Object.assign(r,o.value)}else if(n.keyword==="extraMetadata")r[n.keyword]=n.text;else{let o=m(n.text);r[n.keyword]=o.ok?o.value:n.text}return[{source:{type:"exifUserComment"},data:JSON.stringify(r)}]}function Rt(e){let t=S(e,"exifUserComment");return t?t.data.trimStart().startsWith("{")?h("prompt",t.data,"text-unicode-escape"):ce(e):[]}function pe(e){let t={};for(let r of e){let n=m(r.text);n.ok?t[r.keyword]=n.value:t[r.keyword]=r.text}return[{source:{type:"exifUserComment"},data:JSON.stringify(t)}]}function me(e,t){let r=S(e,"exifUserComment");if(!r)return[];let n=m(r.data);return!n.ok||n.type!=="object"?[]:Object.entries(n.value).flatMap(([o,s])=>{let i=k(s);return h(o,i!==void 0?D(i):void 0,t)})}function Nt(e){return pe(e)}var Bn=e=>{let t=S(e,"exifImageDescription"),r=S(e,"exifMake");return!t&&!r?null:[...h("prompt",r?.data,"text-unicode-escape"),...h("workflow",t?.data,"text-unicode-escape")]},Kn=e=>{let t=me(e,"text-unicode-escape");return t.length>0?t:null};function Ft(e){return Bn(e)??Kn(e)??[]}function Ot(e){let t=Object.fromEntries(e.map(r=>[r.keyword,r.text]));return[{source:{type:"exifUserComment"},data:JSON.stringify(t)}]}function Dt(e){let t=S(e,"exifUserComment");if(!t)return[];let r=m(t.data);return!r.ok||r.type!=="object"?[]:Object.entries(r.value).flatMap(([n,o])=>h(n,k(o),"dynamic"))}function Gt(e){return pe(e)}function Jt(e){return me(e,"dynamic")}var Vn="NovelAI generated image",$n="NovelAI";function jt(e){let t=e.find(s=>s.keyword==="Description"),r=t&&{source:{type:"exifImageDescription"},data:`\0\0\0\0${t.text}`},n=Yn(e),o={source:{type:"exifUserComment"},data:JSON.stringify(n)};return[r,o].filter(s=>s!==void 0)}function Yn(e){return qn.map(t=>{let r=e.find(n=>n.keyword===t);return r?{[t]:r.text}:null}).filter(t=>t!==null).reduce((t,r)=>Object.assign(t,r),{})}var qn=["Comment","Description","Generation time","Software","Source","Title"];function Wt(e){let t=S(e,"exifUserComment"),r=S(e,"exifImageDescription");return Zn(t,r)}function Zn(e,t){if(!e||!t)return[];let r=m(e.data);if(!r.ok||r.type!=="object")return E("Comment",e.data);let n=r.value,o=Qn(t,k(n.Description));return[E("Title",k(n.Title)??Vn),h("Description",o,"dynamic"),E("Software",k(n.Software)??$n),E("Source",k(n.Source)),E("Generation time",k(n["Generation time"])),E("Comment",k(n.Comment))].flat()}function Qn(e,t){if(e?.data){let r=e.data;return r.startsWith("\0\0\0\0")?r.slice(4):r}if(t)return t.startsWith("\0\0\0\0")?t.slice(4):t}function fe(e){return t=>{let r=t.find(n=>n.keyword===e);return r?[{source:{type:"exifUserComment"},data:r.text}]:[]}}function de(e,t){return r=>{let n=r.find(o=>o.source.type==="exifUserComment");return n?h(e,n.data,t):[]}}var eo={parameters:"text-utf8-raw",default:"text-unicode-escape"};function Lt(e){let t={};for(let r of e){let n=m(r.text);t[r.keyword]=n.ok?n.value:r.text}return[{source:{type:"exifUserComment"},data:JSON.stringify(t)}]}function Ht(e){let t=S(e,"exifUserComment");if(!t)return[];let r=m(t.data);if(!r.ok||r.type!=="object")return[];let n=r.value,o=Object.entries(n).map(([s,i])=>{let u=k(i);return[s,u!==void 0?D(u):void 0]});return ne(o,eo)}function zt(e){let t=e.find(s=>s.keyword==="parameters");if(!t)return[];let r=m(t.text),n=[{source:{type:"exifUserComment"},data:r.ok?JSON.stringify(r.value):t.text}],o=e.find(s=>s.keyword==="prompt");return o&&n.push({source:{type:"exifMake"},data:o.text}),n}function Xt(e){let t=S(e,"exifUserComment"),r=S(e,"exifMake");return[h("prompt",r?.data,"text-unicode-escape"),h("parameters",t?.data,"text-unicode-escape")].flat()}var to={generation_data:"text-utf8-raw",default:"text-unicode-escape"};function Bt(e){let t={};for(let r of e){let n=m(r.text);t[r.keyword]=n.ok?n.value:r.text}return[{source:{type:"exifUserComment"},data:JSON.stringify(t)}]}function Kt(e){let t=S(e,"exifUserComment");if(!t)return[];let r=m(t.data);if(!r.ok||r.type!=="object")return[];let n=r.value,o=Object.entries(n).map(([s,i])=>{let u=k(i);return[s,u!==void 0?D(u):void 0]});return ne(o,to)}function Vt(e,t){if(e.status==="empty")return a.error({type:"missingRawData"});if(e.status==="invalid")return a.error({type:"invalidParseResult",status:e.status});if(e.status==="unrecognized")return a.error({type:"unsupportedSoftware",software:"unknown"});let r=e.raw;if(r.format===t)return a.ok(r);let n=e.metadata.software,o=lo[n];return o?o(r,t):a.error({type:"unsupportedSoftware",software:n})}function T(e,t){return(r,n)=>{if(r.format==="png"){if(n==="png")return a.ok(r);let s=e(r.chunks);return a.ok({format:n,segments:s})}if(n==="jpeg"||n==="webp")return a.ok({format:n,segments:r.segments});let o=t(r.segments);return a.ok({format:"png",chunks:o})}}var ro=T(jt,Wt),O=T(ue,ce),no=T(Nt,Ft),oo=T(Ot,Dt),so=T(fe("parameters"),de("parameters","text-unicode-escape")),io=T(fe("parameters"),de("parameters","text-unicode-escape")),ao=T(zt,Xt),uo=T(Gt,Jt),co=T(fe("parameters"),de("parameters","text-unicode-escape")),po=T(_t,Rt),mo=T(Lt,Ht),fo=T(Bt,Kt),lo={novelai:ro,"sd-webui":O,"sd-next":O,forge:O,"forge-classic":O,"forge-neo":O,reforge:O,"easy-reforge":O,civitai:po,comfyui:no,tensorart:fo,"stability-matrix":mo,easydiffusion:oo,fooocus:so,"ruined-fooocus":io,swarmui:ao,invokeai:uo,"hf-space":co};function qt(e,t){let r=G(e),n=W(r);if(!n)return{ok:!1,error:{type:"unsupportedFormat"}};if(t.status==="empty"){let s=Yt[n].writeEmpty(r,[]);return s.ok?{ok:!0,value:s.value}:{ok:!1,error:{type:"writeFailed",message:s.error.type}}}if(t.status==="invalid")return{ok:!1,error:{type:"writeFailed",message:"Cannot write invalid metadata"}};if(t.status==="unrecognized"){if(t.raw.format===n)return $t(r,n,t.raw);let i=Yt[n].writeEmpty(r,[]);return i.ok?{ok:!0,value:i.value,warning:{type:"metadataDropped",reason:"unrecognizedCrossFormat"}}:{ok:!1,error:{type:"writeFailed",message:i.error.type}}}let o=Vt(t,n);return o.ok?$t(r,n,o.value):{ok:!1,error:{type:"conversionFailed",message:`Failed to convert metadata: ${o.error.type}`}}}function $t(e,t,r){if(t==="png"&&r.format==="png"){let n=Z(e,r.chunks);return n.ok?{ok:!0,value:n.value}:{ok:!1,error:{type:"writeFailed",message:n.error.type}}}if(t==="jpeg"&&r.format==="jpeg"){let n=$(e,r.segments);return n.ok?{ok:!0,value:n.value}:{ok:!1,error:{type:"writeFailed",message:n.error.type}}}if(t==="webp"&&r.format==="webp"){let n=Q(e,r.segments);return n.ok?{ok:!0,value:n.value}:{ok:!1,error:{type:"writeFailed",message:n.error.type}}}return{ok:!1,error:{type:"writeFailed",message:"Internal error: format mismatch after conversion"}}}var Yt={png:{writeEmpty:Z},jpeg:{writeEmpty:$},webp:{writeEmpty:Q}};var Zt=Object.freeze({novelai:"NovelAI",comfyui:"ComfyUI",swarmui:"SwarmUI",tensorart:"TensorArt","stability-matrix":"Stability Matrix",invokeai:"InvokeAI","sd-webui":"Stable Diffusion WebUI",forge:"Forge","forge-classic":"Forge - Classic","forge-neo":"Forge - Neo",reforge:"reForge","easy-reforge":"EasyReforge","sd-next":"SD.Next",civitai:"Civitai","hf-space":"Hugging Face Space",easydiffusion:"Easy Diffusion",fooocus:"Fooocus","ruined-fooocus":"Ruined Fooocus"});return ar(go);})();
package/dist/index.js CHANGED
@@ -936,7 +936,13 @@ function toJsonResult(value) {
936
936
  }
937
937
 
938
938
  // src/parsers/comfyui-nodes.ts
939
- var SAMPLER_TYPES = ["KSampler", "KSamplerAdvanced", "SamplerCustomAdvanced"];
939
+ var SAMPLER_TYPES = [
940
+ "KSampler",
941
+ "KSamplerAdvanced",
942
+ "SamplerCustomAdvanced",
943
+ "SamplerCustom",
944
+ "DetailerForEach"
945
+ ];
940
946
  var LATENT_IMAGE_TYPES = ["EmptyLatentImage"];
941
947
  var LATENT_IMAGE_RGTHREE_TYPES = ["SDXL Empty Latent Image (rgthree)"];
942
948
  var CHECKPOINT_TYPES = ["CheckpointLoaderSimple", "CheckpointLoader"];
@@ -1004,13 +1010,29 @@ function extractPromptTexts(nodes, sampler) {
1004
1010
  return { promptText: "", negativeText: "" };
1005
1011
  }
1006
1012
  const conditioningSource = resolveConditioningSource(nodes, sampler);
1007
- const positiveRef = conditioningSource.inputs.positive;
1008
- const negativeRef = conditioningSource.inputs.negative;
1009
1013
  return {
1010
- promptText: isNodeReference(positiveRef) ? extractText(nodes, String(positiveRef[0])) : "",
1011
- negativeText: isNodeReference(negativeRef) ? extractText(nodes, String(negativeRef[0])) : ""
1014
+ promptText: extractTextFromConditioning(
1015
+ nodes,
1016
+ conditioningSource.inputs.positive,
1017
+ "positive"
1018
+ ),
1019
+ negativeText: extractTextFromConditioning(
1020
+ nodes,
1021
+ conditioningSource.inputs.negative,
1022
+ "negative"
1023
+ )
1012
1024
  };
1013
1025
  }
1026
+ function extractTextFromConditioning(nodes, ref, condKey, maxDepth = 10) {
1027
+ if (maxDepth <= 0 || !isNodeReference(ref)) return "";
1028
+ const nodeId = String(ref[0]);
1029
+ const text = extractText(nodes, nodeId);
1030
+ if (text) return text;
1031
+ const node = nodes[nodeId];
1032
+ if (!node) return "";
1033
+ const next = node.inputs[condKey];
1034
+ return extractTextFromConditioning(nodes, next, condKey, maxDepth - 1);
1035
+ }
1014
1036
  function extractDimensions(latentImage, latentImageRgthree) {
1015
1037
  if (latentImage) {
1016
1038
  const width = Number(latentImage.inputs.width) || 0;
@@ -1033,20 +1055,21 @@ function extractSampling(nodes, sampler) {
1033
1055
  if (sampler.class_type === "SamplerCustomAdvanced") {
1034
1056
  return extractAdvancedSampling(nodes, sampler);
1035
1057
  }
1058
+ if (sampler.class_type === "SamplerCustom") {
1059
+ return extractCustomSampling(nodes, sampler);
1060
+ }
1036
1061
  let seed = sampler.inputs.seed;
1037
1062
  if (isNodeReference(seed)) {
1038
1063
  const seedNode = nodes[String(seed[0])];
1039
1064
  seed = seedNode?.inputs.seed;
1040
1065
  }
1041
- const rawDenoise = sampler.inputs.denoise;
1042
- const denoise = typeof rawDenoise === "number" && rawDenoise < 1 ? rawDenoise : void 0;
1043
1066
  return {
1044
1067
  seed,
1045
1068
  steps: sampler.inputs.steps,
1046
1069
  cfg: sampler.inputs.cfg,
1047
1070
  sampler: sampler.inputs.sampler_name,
1048
1071
  scheduler: sampler.inputs.scheduler,
1049
- denoise
1072
+ denoise: sampler.inputs.denoise
1050
1073
  };
1051
1074
  }
1052
1075
  function extractAdvancedSampling(nodes, sampler) {
@@ -1054,15 +1077,30 @@ function extractAdvancedSampling(nodes, sampler) {
1054
1077
  const guiderNode = resolveNode(nodes, sampler.inputs.guider);
1055
1078
  const samplerSelectNode = resolveNode(nodes, sampler.inputs.sampler);
1056
1079
  const schedulerNode = resolveNode(nodes, sampler.inputs.sigmas);
1057
- const rawDenoise = schedulerNode?.inputs.denoise;
1058
- const denoise = typeof rawDenoise === "number" && rawDenoise < 1 ? rawDenoise : void 0;
1059
1080
  return {
1060
1081
  seed: noiseNode?.inputs.noise_seed,
1061
1082
  steps: schedulerNode?.inputs.steps,
1062
1083
  cfg: guiderNode?.inputs.cfg,
1063
1084
  sampler: samplerSelectNode?.inputs.sampler_name,
1064
1085
  scheduler: schedulerNode?.inputs.scheduler,
1065
- denoise
1086
+ denoise: schedulerNode?.inputs.denoise
1087
+ };
1088
+ }
1089
+ function extractCustomSampling(nodes, sampler) {
1090
+ const samplerSelectNode = resolveNode(nodes, sampler.inputs.sampler);
1091
+ const schedulerNode = resolveNode(nodes, sampler.inputs.sigmas);
1092
+ let seed = sampler.inputs.noise_seed;
1093
+ if (isNodeReference(seed)) {
1094
+ const seedNode = nodes[String(seed[0])];
1095
+ seed = seedNode?.inputs.seed;
1096
+ }
1097
+ return {
1098
+ seed,
1099
+ steps: schedulerNode?.inputs.steps,
1100
+ cfg: sampler.inputs.cfg,
1101
+ sampler: samplerSelectNode?.inputs.sampler_name,
1102
+ scheduler: schedulerNode?.inputs.scheduler,
1103
+ denoise: schedulerNode?.inputs.denoise
1066
1104
  };
1067
1105
  }
1068
1106
  function extractModel(checkpoint, unetLoader) {
@@ -1192,6 +1230,14 @@ function parseComfyUI(entries) {
1192
1230
  ...merged
1193
1231
  });
1194
1232
  }
1233
+ function normalizeDenoise(sampling) {
1234
+ if (!sampling || typeof sampling.denoise !== "number") return sampling;
1235
+ if (sampling.denoise >= 1) {
1236
+ const { denoise: _, ...rest } = sampling;
1237
+ return rest;
1238
+ }
1239
+ return sampling;
1240
+ }
1195
1241
  function cleanJsonString(json) {
1196
1242
  return json.replace(/\0+$/, "").replace(/:\s*NaN\b/g, ": null");
1197
1243
  }
@@ -1233,10 +1279,12 @@ function extractComfyUIMetadata(nodes) {
1233
1279
  c.latentImageRgthree
1234
1280
  );
1235
1281
  const hiresSamplerNode = findHiresSampler(nodes);
1236
- const hiresSampling = hiresSamplerNode ? extractSampling(nodes, hiresSamplerNode) : void 0;
1282
+ const hiresSampling = normalizeDenoise(
1283
+ hiresSamplerNode ? extractSampling(nodes, hiresSamplerNode) : void 0
1284
+ );
1237
1285
  const hiresScale = resolveHiresScale(nodes, c, width);
1238
1286
  const upscalerName = c.hiresModelUpscale?.inputs.model_name;
1239
- const rawSampling = extractSampling(nodes, c.sampler);
1287
+ const rawSampling = normalizeDenoise(extractSampling(nodes, c.sampler));
1240
1288
  const clipSkip = extractClipSkip(c.clipSetLastLayer);
1241
1289
  return trimObject({
1242
1290
  prompt: promptText || void 0,