A tool for archiving & converting scans of postcards, and information about them.

fix: Switches the HTML and CSS "codecs" to be support files of the web output (which they are), so that they can be affected by the choices within it (eg. the image format being used).

+104 -243
-5
.goreleaser.yaml
··· 42 42 - wasm 43 43 ldflags: 44 44 - "" 45 - hooks: 46 - pre: 47 - # This dir needs to be made manually because TinyGo doesn't create output directories 48 - # like Go does. https://github.com/tinygo-org/tinygo/issues/4687 49 - - mkdir -p {{ dir .Path }} 50 45 # It's important the postoffice native binary is built after the WASM blob 51 46 # As the WASM blob is baked into this server as part of an embed directive. 52 47 # This needs to be done by calling goreleaser twice, specifying IDs to build.
+7 -2
TODO.md
··· 1 1 # TODO 2 2 3 - - [ ] Get HTML format to output the _right_ image extension (fill out ImageExt argument) 4 - - [ ] Read XMP data from generic JPEG format (eg. with EXIF APP1 chunk before XMP APP1 chunk) 3 + - [ ] Created USDZs are technically invalid (byte alignment) — can I tweak the output of archive/zip? Or do I need for fork it? 4 + - [ ] Determine what this `usdchecker` error means & fix it: 5 + - `Found material bindings but no MaterialBindingAPI applied on the prim </Postcard/Geom/Front>. (fails 'MaterialBindingAPIAppliedChecker')` 5 6 - [ ] Don't re-encode same-same format. (eg. USDZ to Web(no alpha, lossy); Web to Web) 7 + - [ ] Read XMP data from generic JPEG format (eg. with EXIF APP1 chunk before XMP APP1 chunk) 6 8 - [ ] Show warning when using fallback size to generate USDZ 7 9 - [ ] Show warning when losing information on conversion (are there any of these cases now?) 8 10 - [ ] Store number of sides in the Metadata ··· 11 13 - [ ] Coregistration of front and back (slight rotation & translation differences) 12 14 - [ ] Allow uploading/choice of SVGs for the back side, to make a "blank" postcard 13 15 - [ ] Responsive layout for the back — in physical units 16 + - [ ] Rendering SVG inside go/wasm 14 17 - [ ] Allow secrets to be unselected in #PostOffice UI 15 18 - [ ] Figure out why secrets dragging is janky #PostOffice 19 + - [ ] Allow secrets region selection on touch devices #PostOffice 16 20 - [ ] Only one postcards.css per group/directory 17 21 18 22 ## Done ··· 50 54 - [x] Show useful errors on build fail #PostOffice 51 55 - [x] Read XMP data from png `web` format 52 56 - [x] Transparent bordered #USD postcards 57 + - [x] Get HTML format to output the _right_ image extension (fill out ImageExt argument)
+3 -2
cmd/postcards/main.go
··· 47 47 } 48 48 decOpts := formats.DecodeOptions{RemoveBorder: removeBorder, IgnoreTransparency: ignoreTransparency} 49 49 50 - codecs, err := postcards.CodecsByFormat(formatList) 50 + codecs, incSupportFiles, err := postcards.CodecsByFormat(formatList) 51 51 if err != nil { 52 52 return err 53 53 } 54 54 55 55 encOpts := formats.EncodeOptions{ 56 - Archival: archival, 56 + Archival: archival, 57 + IncludeSupportFiles: incSupportFiles, 57 58 } 58 59 59 60 bundles, err := postcards.MakeBundles(inputPaths)
+14 -8
formats.go
··· 3 3 import ( 4 4 "embed" 5 5 "fmt" 6 + "slices" 6 7 "strings" 7 8 8 9 "github.com/jphastings/dotpostcard/formats" 9 10 "github.com/jphastings/dotpostcard/formats/component" 10 - "github.com/jphastings/dotpostcard/formats/css" 11 - "github.com/jphastings/dotpostcard/formats/html" 12 11 "github.com/jphastings/dotpostcard/formats/metadata" 13 12 "github.com/jphastings/dotpostcard/formats/usd" 14 13 "github.com/jphastings/dotpostcard/formats/usdz" ··· 26 25 "usdz": usdz.Codec(), 27 26 "json": metadata.Codec(metadata.AsJSON), 28 27 "yaml": metadata.Codec(metadata.AsYAML), 29 - "css": css.Codec(), 30 - "html": html.Codec(), 31 28 "xmp": xmp.Codec(), 32 29 } 33 30 34 - var Codecs = []string{"component", "web", "usdz", "usd", "json", "yaml", "css", "html", "xmp"} 31 + var Codecs = []string{"component", "web", "usdz", "usd", "json", "yaml", "xmp"} 32 + 33 + // These 'formats' will trigger the IncludeSupportFiles encoder option instead of a different codec 34 + var supportFiles = []string{"css", "html"} 35 35 36 36 func init() { 37 37 if len(Codecs) != len(codecs) { ··· 44 44 } 45 45 } 46 46 47 - func CodecsByFormat(names []string) ([]formats.Codec, error) { 47 + func CodecsByFormat(names []string) ([]formats.Codec, bool, error) { 48 48 var outCodecs []formats.Codec 49 + var incSupportFiles bool 49 50 50 51 for _, name := range names { 52 + if slices.Contains(supportFiles, name) { 53 + incSupportFiles = true 54 + continue 55 + } 56 + 51 57 codec, ok := codecs[name] 52 58 if !ok { 53 - return nil, fmt.Errorf("the format '%s' isn't one of those available: %s", name, strings.Join(Codecs, ", ")) 59 + return nil, false, fmt.Errorf("the format '%s' isn't one of those available: %s", name, strings.Join(Codecs, ", ")) 54 60 } 55 61 56 62 outCodecs = append(outCodecs, codec) 57 63 } 58 64 59 - return outCodecs, nil 65 + return outCodecs, incSupportFiles, nil 60 66 } 61 67 62 68 // Returns markdown docs for the named format
-32
formats/css/codec.go
··· 1 - package css 2 - 3 - import ( 4 - _ "embed" 5 - "io" 6 - "io/fs" 7 - 8 - "github.com/jphastings/dotpostcard/formats" 9 - "github.com/jphastings/dotpostcard/types" 10 - ) 11 - 12 - //go:embed postcards.css 13 - var postcardCSS string 14 - 15 - func Codec() formats.Codec { return codec{} } 16 - 17 - type codec struct{} 18 - 19 - func (c codec) Name() string { return "CSS" } 20 - 21 - func (c codec) Bundle(group formats.FileGroup) ([]formats.Bundle, []fs.File, error) { 22 - return nil, group.Files, nil 23 - } 24 - 25 - func (c codec) Encode(_ types.Postcard, _ *formats.EncodeOptions) ([]formats.FileWriter, error) { 26 - writer := func(w io.Writer) error { 27 - _, err := w.Write([]byte(postcardCSS)) 28 - return err 29 - } 30 - 31 - return []formats.FileWriter{formats.NewFileWriter("postcards.css", "text/css", writer)}, nil 32 - }
-34
formats/css/codec_test.go
··· 1 - package css_test 2 - 3 - import ( 4 - "strings" 5 - "testing" 6 - 7 - "github.com/jphastings/dotpostcard/formats/css" 8 - "github.com/jphastings/dotpostcard/internal/testhelpers" 9 - "github.com/jphastings/dotpostcard/types" 10 - "github.com/stretchr/testify/assert" 11 - ) 12 - 13 - func TestBundle(t *testing.T) { 14 - anyOldFilenames := []string{"any.jpg", "other.json", "files-meta.yaml"} 15 - group := testhelpers.TestFiles(anyOldFilenames) 16 - 17 - bundle, remaining, errs := css.Codec().Bundle(group) 18 - 19 - assert.Nil(t, bundle) 20 - assert.Equal(t, group.Files, remaining) 21 - assert.Empty(t, errs) 22 - } 23 - 24 - func TestEncode(t *testing.T) { 25 - fws, err := css.Codec().Encode(types.Postcard{}, nil) 26 - assert.NoError(t, err) 27 - 28 - assert.Len(t, fws, 1) 29 - 30 - content, err := fws[0].Bytes() 31 - assert.NoError(t, err) 32 - 33 - assert.True(t, strings.HasPrefix(string(content), "input[id^=postcard-]:checked ~ label.postcard {")) 34 - }
formats/css/postcards.css formats/web/postcards.css
+2
formats/filewriter.go
··· 17 17 MaxDimension int 18 18 // Forces an encode without transparency — filling ant in with the provided card colour. This destroys information, so it will be ignored if archival==true. 19 19 NoTransparency bool 20 + // Will produce support files alongside the postcard (eg. HTML & CSS with the web file) 21 + IncludeSupportFiles bool 20 22 } 21 23 22 24 func (opts *EncodeOptions) WantsLossless() bool {
-46
formats/html/codec.go
··· 1 - package html 2 - 3 - import ( 4 - "fmt" 5 - "io" 6 - "io/fs" 7 - 8 - "github.com/jphastings/dotpostcard/formats" 9 - "github.com/jphastings/dotpostcard/types" 10 - ) 11 - 12 - // TODO: Can this the HTML be simpler for non-flipping postcards? 13 - 14 - //go:generate qtc -file postcard.html.qtpl 15 - 16 - func Codec() formats.Codec { return codec{} } 17 - 18 - func (c codec) Name() string { return "HTML" } 19 - 20 - type codec struct{} 21 - 22 - func (c codec) Bundle(group formats.FileGroup) ([]formats.Bundle, []fs.File, error) { 23 - return nil, group.Files, nil 24 - } 25 - 26 - type htmlVars struct { 27 - types.Metadata 28 - ImageExt string 29 - } 30 - 31 - func (c codec) Encode(pc types.Postcard, _ *formats.EncodeOptions) ([]formats.FileWriter, error) { 32 - v := htmlVars{ 33 - Metadata: pc.Meta, 34 - ImageExt: ".jpeg", 35 - } 36 - v.Metadata.Name = pc.Name 37 - 38 - writer := func(w io.Writer) error { 39 - WriteHTML(w, v) 40 - return nil 41 - } 42 - 43 - return []formats.FileWriter{ 44 - formats.NewFileWriter(fmt.Sprintf("%s.html", pc.Name), "text/html", writer), 45 - }, nil 46 - }
-42
formats/html/codec_test.go
··· 1 - package html_test 2 - 3 - import ( 4 - "testing" 5 - 6 - "github.com/jphastings/dotpostcard/formats/html" 7 - "github.com/jphastings/dotpostcard/internal/testhelpers" 8 - "github.com/stretchr/testify/assert" 9 - ) 10 - 11 - func TestBundle(t *testing.T) { 12 - anyOldFilenames := []string{"any.jpg", "other.json", "files-meta.yaml"} 13 - group := testhelpers.TestFiles(anyOldFilenames) 14 - 15 - bundle, remaining, errs := html.Codec().Bundle(group) 16 - 17 - assert.Nil(t, bundle) 18 - assert.Equal(t, group.Files, remaining) 19 - assert.Empty(t, errs) 20 - } 21 - 22 - func TestEncode(t *testing.T) { 23 - fws, err := html.Codec().Encode(testhelpers.SamplePostcard, nil) 24 - assert.NoError(t, err) 25 - 26 - assert.Len(t, fws, 1) 27 - 28 - content, err := fws[0].Bytes() 29 - assert.NoError(t, err) 30 - 31 - assert.Equal(t, `<!-- Make sure you reference postcards.css in your <head> --> 32 - <link rel="stylesheet" type="text/css" href="postcards.css"> 33 - <!-- You can set the width of .postcard in CSS to limit the size of all postcards on your page --> 34 - <style>.postcard { max-width: 50vw; margin: auto; } body { margin: 1em; }</style> 35 - <!-- Put the lines following this wherever you want your postcard --> 36 - 37 - <input type="checkbox" id="postcard-some-postcard" style="display:none"> 38 - <label for="postcard-some-postcard" class="postcard flip-book landscape" style="--postcard: url('some-postcard.postcard.jpeg'); --aspect-ratio: 1480 / 1050"> 39 - <img src="some-postcard.postcard.jpeg" loading="lazy" alt="The word &#39;Front&#39; in large blue letters"> 40 - <div class="shadow"></div> 41 - </label>`, string(content)) 42 - }
formats/html/postcard.html.qtpl formats/web/postcard.html.qtpl
+1 -1
formats/html/postcard.html.qtpl.go formats/web/postcard.html.qtpl.go
··· 4 4 // Generates the HTML needed to display a web postcard. 5 5 6 6 //line postcard.html.qtpl:2 7 - package html 7 + package web 8 8 9 9 //line postcard.html.qtpl:2 10 10 import (
+20
formats/web/css.go
··· 1 + package web 2 + 3 + import ( 4 + _ "embed" 5 + "io" 6 + 7 + "github.com/jphastings/dotpostcard/formats" 8 + ) 9 + 10 + //go:embed postcards.css 11 + var postcardCSS string 12 + 13 + func createCSS() formats.FileWriter { 14 + writer := func(w io.Writer) error { 15 + _, err := w.Write([]byte(postcardCSS)) 16 + return err 17 + } 18 + 19 + return formats.NewFileWriter("postcards.css", "text/css", writer) 20 + }
+6 -1
formats/web/encode.go
··· 97 97 return err 98 98 } 99 99 100 - return []formats.FileWriter{formats.NewFileWriter(name, mimetype, writer)}, nil 100 + fws := []formats.FileWriter{formats.NewFileWriter(name, mimetype, writer)} 101 + if opts != nil && opts.IncludeSupportFiles { 102 + fws = append(fws, createCSS(), createHTML(pc, format)) 103 + } 104 + 105 + return fws, nil 101 106 } 102 107 103 108 func rotateForWeb(img image.Image, flip types.Flip) (image.Image, image.Rectangle) {
+33
formats/web/html.go
··· 1 + package web 2 + 3 + import ( 4 + "fmt" 5 + "io" 6 + 7 + "github.com/jphastings/dotpostcard/formats" 8 + "github.com/jphastings/dotpostcard/types" 9 + ) 10 + 11 + // TODO: Can this the HTML be simpler for non-flipping postcards? 12 + 13 + //go:generate qtc -file postcard.html.qtpl 14 + 15 + type htmlVars struct { 16 + types.Metadata 17 + ImageExt string 18 + } 19 + 20 + func createHTML(pc types.Postcard, format string) formats.FileWriter { 21 + v := htmlVars{ 22 + Metadata: pc.Meta, 23 + ImageExt: "." + format, 24 + } 25 + v.Metadata.Name = pc.Name 26 + 27 + writer := func(w io.Writer) error { 28 + WriteHTML(w, v) 29 + return nil 30 + } 31 + 32 + return formats.NewFileWriter(fmt.Sprintf("%s.html", pc.Name), "text/html", writer) 33 + }
+13 -59
go.sum
··· 4 4 git.sr.ht/~sbinet/cmpimg v0.1.0/go.mod h1:FU12psLbF4TfNXkKH2ZZQ29crIqoiqTZmeQ7dkp/pxE= 5 5 git.sr.ht/~sbinet/gg v0.6.0 h1:RIzgkizAk+9r7uPzf/VfbJHBMKUr0F5hRFxTUGMnt38= 6 6 git.sr.ht/~sbinet/gg v0.6.0/go.mod h1:uucygbfC9wVPQIfrmwM2et0imr8L7KQWywX0xpFMm94= 7 - github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= 8 7 github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= 9 8 github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= 10 - github.com/alecthomas/chroma/v2 v2.15.0 h1:LxXTQHFoYrstG2nnV9y2X5O94sOBzf0CIUpSTbpxvMc= 11 - github.com/alecthomas/chroma/v2 v2.15.0/go.mod h1:gUhVLrPDXPtp/f+L1jo9xepo9gL4eLwRuGAunSZMkio= 12 9 github.com/alecthomas/chroma/v2 v2.16.0 h1:QC5ZMizk67+HzxFDjQ4ASjni5kWBTGiigRG1u23IGvA= 13 10 github.com/alecthomas/chroma/v2 v2.16.0/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk= 14 11 github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= 15 12 github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= 16 - github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= 17 13 github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= 18 14 github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= 19 15 github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8= ··· 26 22 github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8= 27 23 github.com/charmbracelet/colorprofile v0.3.0 h1:KtLh9uuu1RCt+Hml4s6Hz+kB1PfV3wi++1h5ia65yKQ= 28 24 github.com/charmbracelet/colorprofile v0.3.0/go.mod h1:oHJ340RS2nmG1zRGPmhJKJ/jf4FPNNk0P39/wBPA1G0= 29 - github.com/charmbracelet/glamour v0.8.0 h1:tPrjL3aRcQbn++7t18wOpgLyl8wrOHUEDS7IZ68QtZs= 30 - github.com/charmbracelet/glamour v0.8.0/go.mod h1:ViRgmKkf3u5S7uakt2czJ272WSg2ZenlYEZXT2x7Bjw= 31 25 github.com/charmbracelet/glamour v0.9.1 h1:11dEfiGP8q1BEqvGoIjivuc2rBk+5qEXdPtaQ2WoiCM= 32 26 github.com/charmbracelet/glamour v0.9.1/go.mod h1:+SHvIS8qnwhgTpVMiXwn7OfGomSqff1cHBCI8jLOetk= 33 - github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg= 34 - github.com/charmbracelet/lipgloss v1.0.0/go.mod h1:U5fy9Z+C38obMs+T+tJqst9VGzlOYGj4ri9reL3qUlo= 35 27 github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= 36 28 github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= 37 29 github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE= ··· 91 83 github.com/ebitengine/purego v0.8.2/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= 92 84 github.com/ernyoke/imger v1.0.0 h1:v+vnOpZwCfet5AUruwhN54g9v8CnhKOB3ZCsMIa5AZ0= 93 85 github.com/ernyoke/imger v1.0.0/go.mod h1:Ft4UQ3taMpn8EVVLWRlT0ijOvMTKZZqhXXR4VzCsAT4= 94 - github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= 95 - github.com/gen2brain/jpegli v0.3.3 h1:ryCOQpmGuVk6FA+QBe9st6cW48jsRdVOPiNrAJ50m+k= 96 - github.com/gen2brain/jpegli v0.3.3/go.mod h1:6Dbgr+ni1IUBqGVOKHn8lY+6DvwSGfAfC7pPQiSK6uA= 97 86 github.com/gen2brain/jpegli v0.3.4 h1:wFoUHIjfPJGGeuW3r9dqy0MTT1TtvJuWf6EqfHPPGFM= 98 87 github.com/gen2brain/jpegli v0.3.4/go.mod h1:tVnF7NPyufTo8noFlW5lurUUwZW8trwBENOItzuk2BM= 99 88 github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= ··· 110 99 github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= 111 100 github.com/golang/geo v0.0.0-20200319012246-673a6f80352d/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= 112 101 github.com/golang/geo v0.0.0-20210211234256-740aa86cb551/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= 113 - github.com/golang/geo v0.0.0-20230421003525-6adc56603217 h1:HKlyj6in2JV6wVkmQ4XmG/EIm+SCYlPZ+V4GWit7Z+I= 114 - github.com/golang/geo v0.0.0-20230421003525-6adc56603217/go.mod h1:8wI0hitZ3a1IxZfeH3/5I97CI8i5cLGsYe7xNhQGs9U= 115 102 github.com/golang/geo v0.0.0-20250404181303-07d601f131f3 h1:8COTSTFIIXnaD81+kfCw4dRANNAKuCp06EdYLqwX30g= 116 103 github.com/golang/geo v0.0.0-20250404181303-07d601f131f3/go.mod h1:J+F9/3Ofc8ysEOY2/cNjxTMl2eB1gvPIywEHUplPgDA= 117 - github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 118 - github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 104 + github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= 105 + github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= 119 106 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 120 107 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 121 108 github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= ··· 130 117 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= 131 118 github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 132 119 github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= 133 - github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= 134 - github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= 135 - github.com/kolesa-team/go-webp v1.0.1/go.mod h1:oMvdivD6K+Q5qIIkVC2w4k2ZUnI1H+MyP7inwgWq9aA= 136 - github.com/kolesa-team/goexiv v1.1.0/go.mod h1:njKLWYFnmazfoR/82lj4RBGbKSN6ie0fV180/GlxSFU= 137 120 github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 138 121 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 139 122 github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= ··· 150 133 github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 151 134 github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= 152 135 github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA= 153 - github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= 154 136 github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= 155 137 github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= 156 - github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a h1:2MaM6YC3mGu54x+RKAA6JiFFHlHDY1UbkxqppT7wYOg= 157 - github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a/go.mod h1:hxSnBBYLK21Vtq/PHd0S2FYCxBXzBua8ov5s1RobyRQ= 158 138 github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= 159 139 github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= 160 140 github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= ··· 179 159 github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= 180 160 github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= 181 161 github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 182 - github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= 183 162 github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 184 163 github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 185 164 github.com/sunshineplan/tiff v0.0.0-20220128141034-29b9d69bd906 h1:+yYRCj+PGQNnnen4+/Q7eKD2J87RJs+O39bjtHhPauk= 186 165 github.com/sunshineplan/tiff v0.0.0-20220128141034-29b9d69bd906/go.mod h1:O+Ar7ouRbdfxLgoZLFz447/dvdM1NVKk1VpOQaijvAU= 187 166 github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I= 188 167 github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM= 189 - github.com/tmaxmax/go-sse v0.8.0/go.mod h1:HLoxqxdH+7oSUItjtnpxjzJedfr/+Rrm/dNWBcTxJFM= 190 168 github.com/trimmer-io/go-xmp v1.0.0 h1:zY8bolSga5kOjBAaHS6hrdxLgEoYuT875xTy0QDwZWs= 191 169 github.com/trimmer-io/go-xmp v1.0.0/go.mod h1:Aaptr9sp1lLv7UnCAdQ+gSHZyY2miYaKmcNVj7HRBwA= 192 170 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= 193 171 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= 194 - github.com/valyala/fasthttp v1.55.0/go.mod h1:NkY9JtkrpPKmgwV3HTaS2HWaJss9RSIsRVfcxxoHiOM= 195 172 github.com/valyala/quicktemplate v1.8.0 h1:zU0tjbIqTRgKQzFY1L42zq0qR3eh4WoQQdIdqCysW5k= 196 173 github.com/valyala/quicktemplate v1.8.0/go.mod h1:qIqW8/igXt8fdrUln5kOSb+KWMaJ4Y8QUsfd1k6L2jM= 197 174 github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= ··· 199 176 github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= 200 177 github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= 201 178 github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= 202 - github.com/yuin/goldmark-emoji v1.0.4 h1:vCwMkPZSNefSUnOW2ZKRUjBSD5Ok3W78IXhGxxAEF90= 203 - github.com/yuin/goldmark-emoji v1.0.4/go.mod h1:tTkZEbwu5wkPmgTcitqddVxY9osFZiavD+r4AzQrh1U= 204 179 github.com/yuin/goldmark-emoji v1.0.5 h1:EMVWyCGPlXJfUXBXpuMu+ii3TIaxbVBnEX9uaDC4cIk= 205 180 github.com/yuin/goldmark-emoji v1.0.5/go.mod h1:tTkZEbwu5wkPmgTcitqddVxY9osFZiavD+r4AzQrh1U= 206 181 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 207 - golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= 208 - golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4= 209 - golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= 210 182 golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw= 211 183 golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM= 212 - golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ= 213 - golang.org/x/image v0.24.0/go.mod h1:4b/ITuLfqYq1hqZcjofwctIhi7sZh2WaCjvsBNjjya8= 214 184 golang.org/x/image v0.25.0 h1:Y6uW6rH1y5y/LK1J8BPWZtr6yZ7hrsy6hFrXjgsc2fQ= 215 185 golang.org/x/image v0.25.0/go.mod h1:tCAmOEGthTtkalusGp1g3xa2gke8J6c2N565dTyl9Rs= 216 - golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= 217 - golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= 186 + golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= 187 + golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= 218 188 golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 219 189 golang.org/x/net v0.0.0-20200320220750-118fecf932d8/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 220 190 golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 221 191 golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 222 192 golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 223 193 golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= 224 - golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= 225 - golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= 226 194 golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= 227 195 golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= 228 - golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= 229 - golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 230 196 golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= 197 + golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 231 198 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 232 199 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 233 200 golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= ··· 235 202 golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 236 203 golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 237 204 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 238 - golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= 239 - golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 240 205 golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= 241 206 golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 242 207 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 243 - golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= 244 - golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= 245 208 golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o= 246 209 golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= 247 210 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 248 211 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 249 - golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= 250 - golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= 251 212 golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= 252 213 golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= 253 214 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 254 - golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= 255 - golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= 215 + golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU= 216 + golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ= 256 217 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 257 218 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 258 219 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= ··· 262 223 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 263 224 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 264 225 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 265 - lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= 266 - modernc.org/cc/v3 v3.41.0/go.mod h1:Ni4zjJYJ04CDOhG7dn640WGfwBzfE0ecX8TyMB0Fv0Y= 267 - modernc.org/cc/v4 v4.24.4 h1:TFkx1s6dCkQpd6dKurBNmpo+G8Zl4Sq/ztJ+2+DEsh0= 268 - modernc.org/cc/v4 v4.24.4/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= 269 - modernc.org/ccgo/v3 v3.17.0/go.mod h1:Sg3fwVpmLvCUTaqEUjiBDAvshIaKDB0RXaf+zgqFu8I= 270 - modernc.org/ccgo/v4 v4.23.16 h1:Z2N+kk38b7SfySC1ZkpGLN2vthNJP1+ZzGZIlH7uBxo= 271 - modernc.org/ccgo/v4 v4.23.16/go.mod h1:nNma8goMTY7aQZQNTyN9AIoJfxav4nvTnvKThAeMDdo= 226 + modernc.org/cc/v4 v4.25.2 h1:T2oH7sZdGvTaie0BRNFbIYsabzCxUQg8nLqCdQ2i0ic= 227 + modernc.org/cc/v4 v4.25.2/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= 228 + modernc.org/ccgo/v4 v4.25.1 h1:TFSzPrAGmDsdnhT9X2UrcPMI3N/mJ9/X9ykKXwLhDsU= 229 + modernc.org/ccgo/v4 v4.25.1/go.mod h1:njjuAYiPflywOOrm3B7kCB444ONP5pAVr8PIEoE0uDw= 272 230 modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= 273 231 modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= 274 - modernc.org/gc/v2 v2.6.3 h1:aJVhcqAte49LF+mGveZ5KPlsp4tdGdAOT4sipJXADjw= 275 - modernc.org/gc/v2 v2.6.3/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= 276 - modernc.org/libc v1.61.13 h1:3LRd6ZO1ezsFiX1y+bHd1ipyEHIJKvuprv0sLTBwLW8= 277 - modernc.org/libc v1.61.13/go.mod h1:8F/uJWL/3nNil0Lgt1Dpz+GgkApWh04N3el3hxJcA6E= 232 + modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= 233 + modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= 278 234 modernc.org/libc v1.62.1 h1:s0+fv5E3FymN8eJVmnk0llBe6rOxCu/DEU+XygRbS8s= 279 235 modernc.org/libc v1.62.1/go.mod h1:iXhATfJQLjG3NWy56a6WVU73lWOcdYVxsvwCgoPljuo= 280 236 modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= 281 237 modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= 282 - modernc.org/memory v1.8.2 h1:cL9L4bcoAObu4NkxOlKWBWtNHIsnnACGF/TbqQ6sbcI= 283 - modernc.org/memory v1.8.2/go.mod h1:ZbjSvMO5NQ1A2i3bWeDiVMxIorXwdClKE/0SZ+BMotU= 284 238 modernc.org/memory v1.9.1 h1:V/Z1solwAVmMW1yttq3nDdZPJqV1rM05Ccq6KMSZ34g= 285 239 modernc.org/memory v1.9.1/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= 286 240 modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
+1 -6
internal/www/postoffice/postoffice.js
··· 82 82 document.querySelector('#output .code').classList.toggle('irrelevant', false) 83 83 document.querySelector('#output .code-explain').classList.toggle('irrelevant', false) 84 84 85 - // TODO: fix this hack to replace the filename 86 - const toReplace = image.filename.replace(/\.[^/.]+$/, '.jpeg') 87 - outHTML.innerHTML = uniqueHTML.replaceAll(toReplace, image.blobURL) 85 + outHTML.innerHTML = uniqueHTML.replaceAll(image.filename, image.blobURL) 88 86 outDownload.href = image.blobURL 89 87 outDownload.download = image.filename 90 88 } ··· 299 297 output.classList.toggle('irrelevant', true) 300 298 removeError() 301 299 }) 302 - 303 - // Now the submit listener is registered, swap to showing the postcard on the page, instead of downloading 304 - document.querySelector('input[name="codec-choice"][value="web"]').value = "web-js" 305 300 306 301 document.querySelectorAll('#front-image,#back-image') 307 302 .forEach((input) => {
+2 -5
pkg/postoffice/choices.go
··· 2 2 3 3 import ( 4 4 "github.com/jphastings/dotpostcard/formats" 5 - "github.com/jphastings/dotpostcard/formats/css" 6 - "github.com/jphastings/dotpostcard/formats/html" 7 5 "github.com/jphastings/dotpostcard/formats/usdz" 8 6 "github.com/jphastings/dotpostcard/formats/web" 9 7 ) ··· 15 13 } 16 14 17 15 return map[string][]formats.Codec{ 18 - "web-js": {webCodec, html.Codec(), css.Codec()}, 19 - "web": {webCodec}, 20 - "usdz": {usdz.Codec()}, 16 + "web": {webCodec}, 17 + "usdz": {usdz.Codec()}, 21 18 }, nil 22 19 }
+2
pkg/postoffice/http.go
··· 101 101 } 102 102 encOpts := formats.EncodeOptions{ 103 103 Archival: checkboxBool(r.FormValue("archival")), 104 + 105 + IncludeSupportFiles: true, 104 106 } 105 107 106 108 var meta types.Metadata