+ {#if versions.length && item}
+ {@const original = versions[0]}
+
+ restore(original.hash, 'Original')}>Restore original
+
+
+
Kept on this device: the original and the last {19} saves. Peers get the saved image, not this list.
+ {:else}
+
No saved versions yet. The first Save keeps the original here, so you can always go back to it.
+ {/if}
+
+{/snippet}
+
+{#snippet editPanel()}
+ !!v, close: () => void close(), minW: 420, minH: 320 }}
+ use:ownKeys
+ style="z-index: var(--z-window); width: 820px; height: 560px"
+ >
+
void close()}
+ closeAttrs={{ title: 'Close', id: 'image-editor-close' }}
+ >
+ {#snippet heading()}
+ Image editor
+ {item?.name ?? ''}{dirty ? ' •' : ''}
+
+ {/snippet}
+
+
+
+ {#snippet topbar()}
+
+
+
+
+
+
+ zoomAt(1 / 1.25)} />
+ {Math.round(scale * 100)}%
+ zoomAt(1.25)} />
+ Fit
+ 1:1
+
+ {work ? work.width + ' × ' + work.height : ''} · {formatLabel}
+ {#if usedBy}
+
+ {usedBy} texture{usedBy === 1 ? '' : 's'}
+
+ {/if}
+
+ Save as copy
+ Save
+
+
+
+ {/snippet}
+
+ {#snippet main()}
+
+
+
+ {#if loading}
+
Loading…
+ {:else if loadError}
+
{loadError}
+ {:else if !item}
+
This image is no longer in the library.
+ {/if}
+ {#if cropping}
+
Crop {crop.w} × {crop.h} — Enter applies, Esc cancels
+ {/if}
+
+ {/snippet}
+
+ {#snippet secondary(mode)}
+ {#if mode === 'history'}
+ {@render versionsPanel()}
+ {:else}
+ {@render editPanel()}
+ {/if}
+ {/snippet}
+
+
+
+{/if}
+
+
diff --git a/src/components/menu/Inspector.svelte b/src/components/menu/Inspector.svelte
index 6d1105e9d..a3fa27360 100644
--- a/src/components/menu/Inspector.svelte
+++ b/src/components/menu/Inspector.svelte
@@ -3968,6 +3968,19 @@
role="presentation"
onclick={() => document.getElementById('texture-file')?.click()}
/>
+
+