From 3b8bc166cbf2df49dc5dd4d6589505cf5701426e Mon Sep 17 00:00:00 2001 From: cyber-dream Date: Mon, 1 May 2023 15:32:41 +0300 Subject: [PATCH] working binary images in mongo --- fileuploading/fileuploading.go | 105 ++++++++++++++++++++++ go.mod | 4 + go.sum | 9 ++ main.go | 62 ++++++++++++- resources/sys/wde/file-view.css | 2 +- resources/wde.js | 2 +- routewde/wde.go | 2 +- templates/finder/app.tmpl | 2 +- templates/img-viewer/app.tmpl | 4 +- templates/wde-widgets/file-tile-view.tmpl | 3 +- test-img/cat2-test.jpeg | Bin 0 -> 15516 bytes test-img/cat2-test_32px.jpeg | Bin 0 -> 1077 bytes test-img/cat2.jpeg | Bin 0 -> 15516 bytes test-img/cat2_32px.jpeg | Bin 0 -> 1077 bytes test-img/out_example.jpg | 3 + wde/imglib.go | 68 ++++++++++---- wde/wde.go | 20 +++++ webfilesystem/webfilesystem.go | 2 + websiteapp/img-viewer/imgviewer.go | 2 +- websiteapp/personalprops/personalprops.go | 14 +-- 20 files changed, 271 insertions(+), 33 deletions(-) create mode 100644 fileuploading/fileuploading.go create mode 100644 test-img/cat2-test.jpeg create mode 100644 test-img/cat2-test_32px.jpeg create mode 100644 test-img/cat2.jpeg create mode 100644 test-img/cat2_32px.jpeg create mode 100644 test-img/out_example.jpg diff --git a/fileuploading/fileuploading.go b/fileuploading/fileuploading.go new file mode 100644 index 0000000..658d2c1 --- /dev/null +++ b/fileuploading/fileuploading.go @@ -0,0 +1,105 @@ +package fileuploading + +//sudo apt-get install libvips-tools + +import ( + "encoding/base64" + "fmt" + "io/ioutil" + "log" + "net/http" + "os" + "path" + "personalwebsite/wde" + "personalwebsite/webfilesystem" + "strings" + + "github.com/disintegration/imaging" + "go.mongodb.org/mongo-driver/bson/primitive" +) + +type FileUploading struct { + fs *webfilesystem.WebFileSystem +} + +func NewFileUploading(webfs *webfilesystem.WebFileSystem) *FileUploading { + return &FileUploading{ + fs: webfs, + } +} + +func (f *FileUploading) CreateMiniatures(parentDir string, file string) error { + src, err := imaging.Open(path.Join(parentDir, file)) + if err != nil { + // log.Fatalf("failed to open image: %v", err) + return err + } + + // Resize the cropped image to width = 200px preserving the aspect ratio. + src = imaging.Resize(src, 32, 0, imaging.Lanczos) + + // Save the resulting image as JPEG. + splittedFileName := strings.Split(file, ".") + err = imaging.Save(src, path.Join(parentDir, splittedFileName[0]+"_32px."+splittedFileName[1])) + if err != nil { + // log.Fatalf("failed to save image: %v", err) + return err + } + + data, err := os.ReadFile(path.Join(parentDir, file)) + if err != nil { + return err + } + + min32Data, err := os.ReadFile(path.Join(parentDir, splittedFileName[0]+"_32px."+splittedFileName[1])) + if err != nil { + return err + } + imgData := wde.Img{ + Header: "", + Data: data, + Miniature32: min32Data, + } + newFile := webfilesystem.WebFSFile{ + MongoId: primitive.NewObjectID(), + Name: file, + Type: "picture", + Data: imgData, + Icon: "", + } + f.fs.CreateFile(&newFile, "/home/user/") + return nil +} + +func (f *FileUploading) EncodeToBase64(path string) (string, string) { + // Read the entire file into a byte slice + bytes, err := ioutil.ReadFile(path) + if err != nil { + log.Fatal(err) + } + + var base64Encoding string + + // Determine the content type of the image file + mimeType := http.DetectContentType(bytes) + + // Prepend the appropriate URI scheme header depending + // on the MIME type + switch mimeType { + case "image/jpeg": + base64Encoding += "image/jpeg;base64" + case "image/png": + base64Encoding += "image/png;base64" + } + + // Append the base64 encoded output + // base64Encoding += toBase64(bytes) + + // Print the full base64 representation of the image + fmt.Println(base64Encoding) + return base64Encoding, toBase64(bytes) +} + +func toBase64(b []byte) string { + return base64.StdEncoding.EncodeToString(b) +} diff --git a/go.mod b/go.mod index 1b644b7..d7a02a6 100644 --- a/go.mod +++ b/go.mod @@ -13,18 +13,21 @@ require ( github.com/xdg-go/scram v1.1.1 // indirect github.com/xdg-go/stringprep v1.0.3 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect + golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect ) require ( github.com/bytedance/sonic v1.8.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/disintegration/imaging v1.6.2 github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.11.2 // indirect github.com/goccy/go-json v0.10.0 // indirect github.com/google/uuid v1.3.0 + github.com/h2non/bimg v1.1.9 github.com/joho/godotenv v1.5.1 github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.0.9 // indirect @@ -33,6 +36,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.9 // indirect diff --git a/go.sum b/go.sum index 1de6cb5..e17d905 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,8 @@ github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhD github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= +github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8= @@ -26,6 +28,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/h2non/bimg v1.1.9 h1:WH20Nxko9l/HFm4kZCA3Phbgu2cbHvYzxwxn9YROEGg= +github.com/h2non/bimg v1.1.9/go.mod h1:R3+UiYwkK4rQl6KVFTOFJHitgLbZXBZNFh2cv3AEbp8= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -49,6 +53,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -83,6 +89,8 @@ golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUu golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= +golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U= +golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= @@ -95,6 +103,7 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= diff --git a/main.go b/main.go index 0713d37..a0da8b7 100644 --- a/main.go +++ b/main.go @@ -3,9 +3,11 @@ package main import ( "context" "errors" + "fmt" "log" "net/http" "os" + "personalwebsite/fileuploading" "personalwebsite/routewde" "personalwebsite/wde" "personalwebsite/webfilesystem" @@ -56,15 +58,18 @@ func main() { router := gin.New() router.LoadHTMLGlob("templates/**/*") router.Static("/res", "resources") + // Set a lower memory limit for multipart forms (default is 32 MiB) + router.MaxMultipartMemory = 8 << 20 // 8 MiB router.GET("/", func(ctx *gin.Context) { ctx.HTML(http.StatusOK, "index.tmpl", gin.H{}) }) webfs := webfilesystem.NewWebFileSystem(client, dBName, webFsCollection) - wde := wde.NewWDE(webfs) - persPropsApp := personalprops.NewPersPropsApp(webfs) + webde := wde.NewWDE(webfs) + fileUploading := fileuploading.NewFileUploading(webfs) + persPropsApp := personalprops.NewPersPropsApp(webfs) // finderApp := finder.FinderApplication{} finderApp := finder.NewFinderApplication(webfs) imgViewerApp := imgviewer.NewImgViewerApp(webfs) @@ -76,12 +81,63 @@ func main() { appsStorage.Apps["finder"] = finderApp appsStorage.Apps["img-viewer"] = &imgViewerApp appsStorage.Apps["blog-viewer"] = blogViewerApp + + router.POST("/upload", func(c *gin.Context) { + // single file + file, _ := c.FormFile("file") + // log.Println(file.Filename) + + // Upload the file to specific dst. + dst := "./test-img/" + file.Filename + c.SaveUploadedFile(file, dst) + + fileUploading.CreateMiniatures("./test-img/", file.Filename) + + // webfs.CreateFile(&img, "/home/user/") + + c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename)) + }) + + router.GET("/testimg", func(c *gin.Context) { + + // c.Data(200, "image/jpeg", data) + }) + system := router.Group("system") { + imgLibGroup := system.Group("imglib") + { + imgLibGroup.GET("get", func(ctx *gin.Context) { + path := ctx.Query("path") + if path == "" { + ctx.JSON(http.StatusBadRequest, "TODO") //TODO json error struct + return + } + min := ctx.Query("min") + file, err := webfs.Read(path) + if err != nil { + ctx.JSON(http.StatusInternalServerError, "TODO") //TODO json error struct + return + } + + img, err := wde.ReadImage(file) + if err != nil { + ctx.JSON(http.StatusInternalServerError, "TODO") //TODO json error struct + return + } + + if min == "min32" { + ctx.Data(http.StatusOK, "image/jpeg", []byte(img.Miniature32)) + } else { + ctx.Data(http.StatusOK, "image/jpeg", []byte(img.Data)) + } + + }) + } wdeGroup := system.Group("wde") { - routewde.Route(wdeGroup, wde) + routewde.Route(wdeGroup, webde) } apps := system.Group("applications") { diff --git a/resources/sys/wde/file-view.css b/resources/sys/wde/file-view.css index 293210f..dc12843 100644 --- a/resources/sys/wde/file-view.css +++ b/resources/sys/wde/file-view.css @@ -42,7 +42,7 @@ .FileTileView .Icon{ width: 32px; height: 32px; - background-image: url("./icons/folder.png"); + /* background-image: url("./icons/folder.png"); */ background-size: cover; image-rendering: optimizeSpeed; /* STOP SMOOTHING, GIVE ME SPEED */ diff --git a/resources/wde.js b/resources/wde.js index 5357bbd..fc757a7 100644 --- a/resources/wde.js +++ b/resources/wde.js @@ -6,7 +6,7 @@ document.addEventListener('DOMContentLoaded', function() { if (!WebDesktopEnvironment.isMobile){ // WebDesktopEnvironment.Open("finder", ["/home/user"]) // WebDesktopEnvironment.Open("blog-viewer", ["/home/user/blog/test-1.blog"]) - WebDesktopEnvironment.Open("personal-properties", ["kek"]) + // WebDesktopEnvironment.Open("personal-properties", ["kek"]) } else { WebDesktopEnvironment.Open("blog-viewer", ["/home/user/blog/test-1.blog"]) } diff --git a/routewde/wde.go b/routewde/wde.go index 0e7a20b..ed37dbe 100644 --- a/routewde/wde.go +++ b/routewde/wde.go @@ -24,7 +24,7 @@ func Route(route *gin.RouterGroup, wde *wde.WDE) { ctx.JSON(http.StatusBadRequest, "TODO") //TODO json error struct return } - ginH, err := wde.Render(path) + ginH, err := wde.RenderFileTileView(path) if err != nil { ctx.JSON(http.StatusInternalServerError, "TODO") //TODO return diff --git a/templates/finder/app.tmpl b/templates/finder/app.tmpl index dabc9ee..8e47b24 100644 --- a/templates/finder/app.tmpl +++ b/templates/finder/app.tmpl @@ -1,5 +1,5 @@ {{ define "finder/app.tmpl" }} -
+
diff --git a/templates/img-viewer/app.tmpl b/templates/img-viewer/app.tmpl index e74126b..01a3f49 100644 --- a/templates/img-viewer/app.tmpl +++ b/templates/img-viewer/app.tmpl @@ -1,6 +1,6 @@ {{ define "img-viewer/app.tmpl" }} -
- +
+
About me diff --git a/templates/wde-widgets/file-tile-view.tmpl b/templates/wde-widgets/file-tile-view.tmpl index af81399..606eab2 100644 --- a/templates/wde-widgets/file-tile-view.tmpl +++ b/templates/wde-widgets/file-tile-view.tmpl @@ -1,7 +1,8 @@ {{ define "wde-widgets/file-tile-view.tmpl" }} {{ range $fileTile := .Files }}
-
+ +
{{ $fileTile.Name }}
{{ end }} diff --git a/test-img/cat2-test.jpeg b/test-img/cat2-test.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..1794a0af19bd95d610d4dfb3dd314364787ae87f GIT binary patch literal 15516 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 D0ofl= literal 0 HcmV?d00001 diff --git a/test-img/cat2-test_32px.jpeg b/test-img/cat2-test_32px.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..116d05d2e2be4eaa2d463038398859ecf301d238 GIT binary patch literal 1077 zcmex=WnyY(ZeeNV?BeR??&0Yb91<+v*#~fzWVs-^OvvRzW@07i;;mD;vFCf@eq=K1cClx z0);s{$UlrsuS~;l_iU%Emz-M3agxa*3&!JXHM% z@)Fob#CfQREFZx=1ozMXTMRtRjKBzE7G$tz_~ZC@(!G23x7r`x*6Yn9 zM*qCJSDdWTSC=iYe6)YT`5XJc&A9xo#@lZ9@|wU4k1u|aExKjB{)bonmb@>Y)^MNE znRNBgk^?11$_l!d*VeK9JFxAWdHr_&gTH-)RH`HE)G{)QWtz1v&VJF%{Kn0-?#ds# zzq4&De_Ow>I^SZWUSD0AT)r;$UewY90lAMSp7hwnenvzl&t~4&&yi2#ljG+6*1z&A zr&nu6)s*|;zvROzzJHticix`hkB>t>svkbzb?n@&$8Wxw{o?CiY`XWzb$^Y|UrqJ| zop4rk6*SULm7nKYZ)(5&>h7qzJNqSdwu7I%*CwDnwnr~l^p zgVSc6KW@vVFL2`0LEigwWmuisN?9kEueihhG`?Ma`|ByX*a;wF61f08-co@H`Lj2f+O`;9=wCOW1>e z@aK#4>d!zzLqtY|J!q)tC@3iCs5qGD=$JV8*jU*3#Ds*zly4}RnFU__|4#7S4!}Zs zVGQR5|AGnthxGy;>&0^?fEVxr@Zu%>ix+_Zj+gKVuMl6rAt9r{{tJ8a&v$U}FJHjk zKF0J*K-wVH53Id zp+3M*7WTVk`KNF?|6LaVK%v~C^T>Vv7-hYDc{#uFG;JUe;4pwjK{mtpO3@+1+{1FI zr`5Hk`1C&VbY=J2Wsdk6FpR^z^}BjaV^_m%g!#ThSA%5){)@Y?WucBsD;{gCh4Y}4 zsyq3tpNStg#TXfI+j2Ci>ug!SXsWN9S2AqcgKR+JTCf#;gxi5?;G`%(m`ARgMbTSb zcN#a>krShi4GX%tt#G&~aYez06Z{WZ@6^sUc7d^n?t2n7t(}isZt)g6yE?@rUo^89 zHKI1I%q@L~RUL<-kQ%pfYDI@CnQU0q2dd8WFrruf`O-4ILW@7{`oU znmVDPVH`z@GG^x&`z1CF+)w(dva4Ep$m=#qj#Ud^oX)>|zI_V7eB+@sES%x@{f(tN zgGIjwc|P$Ey48{xpO@@u5v4xwZ+=$%LrC~tf}!Oca;e&Vl+%p|jU8U*M(n=)g&#q( zsrhgLP^a+h=@f!0jnS1Ljpa5CBPY2WYbm~#JJ$oamYBn|U9d>0I*Iv(n8c*uO)MOqEFJF^;`lh+#W+5L6 z%!oLt0W>!s<*cr*sR-4FW^>*8f@gsE&G(9*{}c4ZMeNq{#0YTVqBto|Sm1(b@f>|? zp7XY0o}-NACno=PZJ z_MvPi5tpRc+A@zE>mKWYhr(}taBX3)a}?hHaM+_8Tj`8g7yd2jk3u- zbZXC==1zMz@?;`qBz>rQ13IQ+`N`P`szm0Ot^T~*4aQbeea*_0Q(z1DD z=_N(ZrBL-P6KA{NvIK>U$!(99XjnV5U!rQ^>8<2MW0ay-(9p}3f5<7k>B)WXvwbi8 zc;1ugxIN^>FRKZglQ=5=FpRCw; zXhp(P+S1=lIz5ZupJ2bfMBugwHLf@0Ji^JhS0dNlbEn-bk{1%uUG&tiH)QiM;=@i9(=xp1n4cCzwgC`?ccD z|Kx=~2E3U&TszEIO&-?BYde*(=sKw#E2=`%>xR7)v_x_}=XY*u zubfKCoW;JlOg}nLH-It(U4Exb{Pt|@x_#6K_PfYT?2$ixsoy!eov7ldE%|XNe0P4} z@UJfMLTsQB%ftIUtq8cV5+4-+Ef2rdmAly1@a>L&^2lXMAv)2C(?mTd= zyK`WeD`czhikJ#5n#$!Aa$|YwVHo^Y5?Xwpq1a)c{IC!-(PDbhNGCP)w#wk4z-+NA z-}`=3bmkwzVHRi5J@wrRXAoyhw0yW}{jpEn0k1ZTkk@BAlVaq{N_v66+R5nyOrl$u zX#Au)clxPuWz6LsTJ7?5&enU<=Vaz(FT&8>jpB4SNjzS#EgO0GvHQ1d?f;UkS|87Q z$u&J;|73bxAg48{XRH>=GV%t9}oa-4^Ep z2kQ2v>bF;6Ic6N36BxKNB=)1u+X|0rOfEkQMl!t|t5$t%~kd!$Na-S*Zp1eKS@ z*A|M?Mi{#*cGb$gkjtDEyuBv3hbe zdGQXXxiwyR-=E&7P#y&gxSO>~GS9lC^4tb$T@6kPi1IE7e8?`UGM&yxzF5l@X6P!B z#1*d{@hcPJ(B1vn7@s|zE%5eKsdPvvbIMQAJr0*rO|hzRBQ7kr<8X*gp|_jhr^KWxicEeSectcpJYyQk21SZyjB^ zQFqj$!;2p|2sHWbz=GAhGCwbcGVCxAnHDm-uTf?)U82W7!(}89|6x^Ub-xr7g=kv~ zzQ#@G?fZQ-`@6CHnz^aDpZtC7Zv}MS9P|2Ep8@cU^)c>jXmbl4teX~PA6dz$u8J}e zScK}ho&h@;}m6LB;^QU~?KIPt$y9;Z57EYQ-7|_*WB^t5r z^D+yzW_7-IkKjozEOO8({2jlfE|Du7>RhLh;u&pK>tP){YXu!J!Ed2)I?X1?H`mP6 zPxcamOZ!wP3e~f2xPj97dykPH{Q0Y;>N+)|N?ZpS_>pZsk0Fvo=7{X1fmoa7(%gzP-NDbvmfyR#JeV5#fk zT+BKf|L(U}e$vA5$NIt{yi>&z!PDIyu0rSCaVVbECACRoE;$VU(poIZpyIo_Z&$_| zltmY()|FCg&lwCN%$rx2s?9%EV3*eHckekXZjaw*AZQ#-?rrw&FX!U%fY*{I2Es0Km#M1T%Ytxd|qAo;HM|N8=?Gw?Wq5AHI zBCo8c=uvr2Pll;VnVbn_XA;3!jfi(z^QU^-np(YfDA{kt484nobm<1& z^e!E;N_zG7&HMT;=$ljZIHp}}1!50b|GEpR)1{0cM-gRumBYgTmdSAVHM}E~&R(IU%Wz;|#s+#KRkfmsAI`G}!+`e!$ zyUQDN#m(Tjb67(=%qsL@S7BEo`fhkXzotM#GrfrgH^1wmQML@5d0W=$PBB@~MK*CP zcl>;Nu&&~Kc+Ui)%Xx+3)%Ug9f%kg+hC_q%4PhXL_;8EFr8+UIs{0=3Kx<6ZD?54Df&&$G2U{$oC z`mh>SUeI zr{P}gYZOnqPwqfvoeC!`y{j44(_r~rqqubpy%*veFC-h72`dSaU}P^uUOWSQ57-v9%Qy;me;thp*ymOX z6t*R}oL9$ma2*`YuQhQoU9Qts+I|~U#^!rPJ~yjf z#tvhduS#VC2T_Nj0=tOtYaMb$CbcYVpjF!Dwy7GTX`M!EjODkXdGblLpHMsFCkaA6 zJ*9doYpeFiU`^(2s21$ityF7C2ViC{2;yXuIWB?331AJ6-3#FUy1=jI!9DN=GvLpbaWGppPv708r(%HO zO|at?X=-)F=zr8{skq|l841j)o|0#CuZgJ^QQ(|1Ry-LVtC`=#tultI;~C%CGwjB0 znB9HM4R=lU4&SC7K*$SP>|xFoFnG=4*2Xmelb@YIr@|3W%KGE6q?rJgKgUE(+B=UpnN30kkHWdLJ9b)%OY36R-? zHW0cbl_~Y^QFvI6jF{bGhCypAkRKKK^C|vji)lecf5OF{D}nRt1a*FbPnKDa=>dyX zg{9zIkdSm76!dK)?4f(g%HFuJ%EkG2s%waq)wG}C+`w{*NEn-UPEF~RT#-nq&67Q_ zn%M8ucziP6D*Ly&TydE-$unSZ`PV(!wej|&laeAymi9;x0>eh1lbql{;+N2uEGZ1L zk4Rcwp2731I$=z#%$^a#Z45v^xrtTM+OczLNh~=CxfC`Ii9koN-|#Jt9L;0QdKVO0 zBECE-|_d9Rxj#G8^ty7WR$wPk%0Rqp7&nwki zinh2X(V2c9>KkFyTcwp9r&XSAs9p8kBHPZS_4+g5M~Nq9`LVOL&$QA+;D)NJQPUk3 zL_bw7RBsGLUo?#iGU_+LAQgt-kFCF<`MwseUyx3@D+-6eL(jNs4~hMo$_z4_t_Y$E?9a`ch;|z4D*z3l)~8TPOpU{ zjEy7Z#cZ4A`#BMwmdo4|;hx92`e%Tyh$0;IWL_l|l|AD%lNS5CSLz6iN zVpY%{j<4)g?MSa`@31Pjr&J}VR#3OBr_(b>+C(#;IBr6`G%Y4Mch4frq2n4$sVz*E zAl_R6M?|A8WyVX2`!gM-axepQ+^Ha(H?$xdpmu1$TwbtEcz(k2fC?5*2yrk+a=(H5@JB!{ zezu4iL5iH-QBHH==ZI^P?U-dHC#zKzwo7Jc+F==kAhF)q^v^oKW1+Y^5{eowCzRI# zGPpmwEn<5cuqd0es`xpp28d++w=bA<>twQ;C*qQj>p5lJlqG}c4t86!Sk_KL*%0_Q zWU%vs6w+oHT}g=+)4t!|SEbu{?aQrrg^jPz%Ke3Z@j#sKIb+L^(g}L?ep+ShLdZa3 zKW7`!Jza?dBYs8lzMpz)k<%xcfdp}elZs`XhUy?R+TP~hrL5`Z!a*M0Ly=RZmdAyK zf*tg;CCVDP7(N?fNiS({`4qCpN-k0Pw}_1AEz_3LoK&jmjl(mPAnIwRN~u~lq%Gm2 z7xzV>(czzOAJI{j;z?X5Vz#k96{zThY#}f{O{>I9&^96>)04rZ7ZAO^H}hP3224SJ zJ&jCJxX*a(K2*yVJpKQNSKylji#`JNw*pP0!xD9PpCv}uN^xq47d~TeY z2UD99PG1x@<9S5Xa=RYGn`73M8nWi%`LVM$^63b+kJC%_^ zhS<8>ECEH3E4oTsVmw*GiYJw_kKlsTbxqG)wWeTNJ%oFoqwDKqP$x3@H#~hb|kGoxeZ1u<3ThHDxdn2Zgk>t3Fl8REU&=4y% znQX~SqCQZl4g)TIx2;SMy*q8d$8#A6Zj9lo`G%x$e9SB5{D-J3g}i5gEWNWv{#deI zD07Ws_bhW4u49oqx-C}Z>v{}L#s%BT<2vCxuZ#OV+E1KbvUY3KFa5*u%G=Gk3 z$QOPFxjC6RByPuUSYC~GAAjTAI2{as@I;^_TKsQpC}Hz`O!De%JvU#9pjHmLa^oiS zG41>H?JD4#4Mh2jFSI%v0Xo_+nYDS)J7(QDm99WlkrT^YN~xmjhJR=v*jvRww&oFw zzX7V&BbUr9cw7XRRi$Ekk3A?o1GFCGp8*9PN>SS^R}qtOwi8-hbB~XLN18PKxz7N> z<&B|?sZBcsfl;Cg<0 z=3@fPJ-j0X?-nDbi+&Au$db4kf->0_2A3YEcE0+@bkt3~G>tR9&2yl7*(C^%QMh=v z$mCO2>~5^0d4$M0nG@D>w+K~UF5Ve=Hhy_;eHpT_#Nk^fRo2gONiJq6EeH`ZX4lbA z;mKapOH?^@z{V>51+x6}lxF}8RPKfJ+b0al41v=he>?+jRe`0-p?m6+1?r3^eP=uJ z;7xy>>2}s*yL8V`sABe>7|1vSsNkhQSNS32i?9UaSy0IJ?L(J`NRow9XG<>A66O|u zq0(Jcml$yCU(@$Q;#ZBX{!YvTZDo z<%;l2Fp&v}j}cixd5t5NI8&SFBCr$Af(Ms9Au~mElO&ZbPDVi})>TAO-C7jpy%@pO=I35=x+>XTvKqHhpxg}^oz5ctJ$)Tve7z}8 zwj>)U)l>qO&8zJTu3&yqTExZdR)L9QQW__6oKum)n~cc^r9IW(srt$mBC4lRg-SYc z6sk8-P(i%vANF2yhmx^bXS!-C1t*fFL}ov(Ey&@fPS|7iHH^2YfCdGvz0%7v+yy^s3TF>CU~l9L7ZhFzy4C%)L)w`pPHN^(R8Cs zQmQNE0$CJEVoEpK9N!8HZPKHK@(h?75gUaT(WVE)H!*NWL2!WX5S48*+l=5z5p3w-gG_8|ETdljnnoGLE3YjdjzzgGudV#ScsIEsfo_Ho+NP8} z$!yWo0OgHbWzIs=N;P61M&)M!%fj%Oh%L{5Frz$OWW{4xrxm+sSCw_`{+1_Zi{T`u zXrN&KQA#Jxr_j!!E5^xw2$ZgDA(febkIh1p!+@SuJf>nKleV(Q84;Nic^YZCei!+D zACzl}T?A<{Tx_RD;b&l`rZKNA z8Q=(G%*~{?R}~goA|KyjSau22DY2gp`P8DwvtjD|@NqKvgk`%-m+v^au>ulH(mKR%J@hBSna{1 zgxU-V>_}|L!ksI^dmclR%}ouw_c`7Yj|tBL9It1T9bS|zD_1AM9T-ZnMm2knB<2}f zvDofng0v#bN0a2|zXFt^t`+ciK{`@i$Zq6&S-T+t7kj0^`(QBfz;}Fza}96S^q)X8 z9KALpaLiM(GtTpET#yY?^x)>)Ns!Ew^;*Z)VzPKX|ApY<$kCLwjgJ} zqnsh{j9Tt*+q2+V6)|JdMX-SRS*ySFB(a^dFa-%{2LZ+_VHkyx%NopHwt?!j#M%HvLqx z3T0N3RGkRzq{oUU!8!db^wD0ZP6?r?uf>tMD0;bV9Qr9v&X>@W#7bf>_zi zF7BA&Z}~4(HTi0tL+*X6mhApURejszhd(UJ(7IBz%?VSAbbVF=+4 z?Ggq|4iDiTIdX+*w+q*m^nDEHRGq34eBhrov8EF{E+3UKvOwT}^YIAyi;pA+rkyI2nJVQz zeBz{dvc?Bth)6Ziq6#iGqEEQc$%$a>;m`+htcvSl@Gx)&AEGWF=KkNcaoqohCnAn! z#c_d*;g*#igr0$yAQkHTG{Go^W`sM>CBPV8^rZ}5q3WoxEQMwFMEqpgSA3P27UyM1 zJhF+0vG_3MfD1Ab#Fy9ziCC@FWUxA?u#J$N()!=5{OBLj*#2W|Q437Z0A85G;O|2N{B&}DOqdlXM<(Py)Ui79 zzfA*4nZT-7X0F8X3|}kjY4H!a{*s6o8?{2?5RM9YL&DKvw6t0OFV?@JA=t@WdxENc zh6scuvk%Rg9*^7YQ(S40O~~`v_-rjf{@StvxPJ0v-B#TcraD+RfNC~dhZw^-i_g- zQLo22eco1BRU%S}^0cad+hrpOLE0$lr@hqK#A}kF`oM1JEJ6+9kvZ~65^g-!={}PGZ7iw=roBv$auf>-taNxzf8vf#KY~JD0!CKrCyzY_O?m zn{Ua80}06@%ZOu$6TxPi-z#3q*9-}qD{VG*aqsWx6sdtMi+{5G7Ms5u(`eb2?O_e( znD*_g7Iv=j8%ZAw7kd-7gvP}{LW8C;#02+2^+>+*)hwPUBH3q#E~dgyhioZ-#p+py z1=ME%A5535CjRQ_G8MY7LRdW#9}uSfxucGR80p+=zTU)5eH6#4er z^+$(@%Zs_^9)Ei%I?rS-q zG5Y;67ETfk-Cp4R^|hJj(%-56Am%e*gd6iODROc?0;e6ww>V#+5fZM~XJ*5T(a1St z;M!(pBek)9+oPh9HL5qi!xfRi2z&)z`&Y>@7!_36EH=#K&J{Y&=tNV0WT?H&iHJ1C z%f-d@xy?5-OFD+5UJAPD0l}srdRO(N67@CLFWjDF@jnV#`lAqwbODi8{cD)1P-%fP zI1*`l4JkGft{eSV*gr#PxNK8NJL|D`Z^<{rL$DXBPgtG-z^_Sjh^>t>Ti1V0VCAzQ zaQw$RfNLC?7sNEK*bh-2l|1cpF3cE7T zKM6A=5*$5+hUv|p$o|=516DLec`Ti94?@kc-`7N&TgBTg%s?68}~M01Ra+G7fb0PDh4F|kNEvS z06V9ofBmN)VWb8xZ9C`qbybT;%@Hk)wmlX=kgrLI>d{kPn{NO2O?a4HzW~+C&ex&BL3P8({E3jp7dMk3zzj&AZiTc~$4{aTc_Y6>e zg}OqeNhh`*LOIkQ>jQ$KSIW5FQwy zTP>AUunZdgFxjiVraGrB0L~*{kNV+11L}mvGU_q)uhs^Aa{Tl*DhnyCl!E&8D#sgNVdBz{cssZ%cS+ZXO04Upd=PQ4~%2HFzOfQ6B`CvgID6lgtcueK6h2Ww-|QCwO6)#)oUtUeAOEo?1!(q4YTr96wO*>7+a^xeGuRr)y(cM>|=ktUTtoIC=AX*w4%8 zyr=t9&xP^XI|2a{{qU!lU*O-EGy>~kQap}MuSAf0&z-_P-T>v_j4bsH3W^oFG}a=+ zhgpWeo6K!KL4{~mUoTXbiiM}_A?lyT`s~-!TBF!izB~{c6mZKv_*xc&eVy8_NP)g^ zvLWt!OFA-J0$wj<*+c8BU!KPQYy_WO@HSiz^Me>)>U|n6>SFG<1tw302i9%LcTNjm z9Chvq_JG=g!g*t}=KW*|=N#e7A;!%|uLlWVipGvh(Oj3i1{n!pUP#q^wZaPL1K48c z11=#OZoI^@hlm@MXNrm~X!v^2wr{8+_8Q09c(*m=GYd9_5=2$qU!5GgZ%o0V&PtUD*-Yh$ z@A!#aY2ZR;5u5*a!(Z;{*HAf~m8F_Z#5w{7h$)DQnJgsA^F2v7100F13!E$9M$S_{ zk~4WV5YMRxWWvbVol$?Je>KW0auF2uj;%IXJ`};KSn&%AJju}H47ir_zh2P-egpu^Z3_H=y3rW ze_egq(d2b2le5_)$gTCNbHwGRIEjEkM;wReQN*j=T83A4H%j-ZdzfLv*jDFzwp)CA z*NGEWY(&GunBObElcaiEjzNEVhz5N_1 zNP(J06yF!SxoVT2+ES-3*J^`};@89QgsEP!pCi4G*v)XQa)IWqzbvlrF<&^0GgyeU zBK%cE+@tw=%5JijLV#Y*x8rxf^_SFBSOcPRfqn;(c8KyGB}ZuvUVEk1TJkTfRL5_6<_`!~392sHoN>R29aq zhiImXCXHx6qx%}=V*LnQ*Tj9Qc7)~V$>O~af=QWuVA=V1^UX-?n5jz#`1-Apw3DvW z@+@mJY>Yz)9hFvP22OlL_^GX+91K-YUPhiNk+nfE*imsf@E2AqG2X{_eAdn95gp3D z(O7}^R>0!TXN<07Dft<33o}vriWh`&MlrliiPm}^u|kWhh}$yfHVe5Y-Ezg9H)K6l z>pI-?U{@>v6d%7eVBzZ~=<|ZOaMd#apMalb@_N-hws$ecR2BIVj-c(!GV5UZ{qg*>Rz%Kwj(q8?ry??d?Myer##f! zZZCk_=sfO}L%dQR8?|M5o+38sgM{*H>Sxp&@yK+A8zJGZ_gHRFbi7?mo9u`~ZV z;qgPoL0sFP3}mL7y}YRbEiZ>Fv7|Y9jUQkZ06&DUXS_=4L=x)4N&KqS8iFjV5K#Bl zQ{_`H@qB04#|iW3FYfOKgcL3LSze32L-czQC?iKVcj)xALK}hyJ_Eakq6ekB&hf}H zFYk3w!1aQb+he%q`MK)DK(myXSQkI_&T)=}KPRKeSzG66^nYiB zP~eoQD{lWLhL&Ln`C8(+}9T*ht!T>?u|AzFtWx*h-M|Moqje5S5kUpqEv$(c@(2 zz$l|6I3YjeB8$>KAklX>0%V zzf1Eb`%%YJ{*q7HrCU>4AXX@KSW>`u&!zXLaUVXsL!xDR2%J>{PeMXMOh#MY;4P$b zw6a*2=u~kjn`WgJxT>bX3|bvy%p5yftl zmZCa_m-D5sXqG!cnfh*YH7>oIXX{)XtQu14NRSQoT&=$WP3k~~e3uwBJnrQo1RSSP z;g&uD_#AkKNo3AlVSMwd5|`axuAWNm=KVgZ>BhwoN-pw|m8WRUo*Z;vY9?dBacMD- zl%Eywfser$@(_o{nt8A zR0=`O^}gSq(>OWU?KaYQqH@5SuV+C%0sEXHWkBK^5#=O7o|=~FSKioHdhB68ZtCc9 ztP?CRE6~4^v}Tx|)|OG{b>-U%mPa(5_ymosi`otZYJI~A(}Fci#<}R|t%AI!tM>%) z8|h}rD%%PDkz5?41raT^FXPCh$+O>Rv`t+_VU)iOE++qQx?G?#b$Mg78I6iLRAM5o zdFZ=yVucFoo(zvDgL9>6kck18H(!eoqy-hqm`tWFQupq=P`;kpt2aFvgOrc7{jPs? zfX;GQA;S3$LwX~{u=kO=C#WMgr+AUoBn47L*?IMx0gQ91bd06t-u&C)1IL8&l<&RjZiJ)`WQeuYku{wfi6W?V zY}NBUp++`-i~fPP`^eSvZ+Z=kT98K=8+mQ$d8x!+3%({_iR9ssAcF z;ab;I#OCakSM^nZ#;C@rvhxFiYKVhT*ez>oG`AeO45-Yd zMEZS5RnZW7&|XE~G)*5l6+?xHL#Llk546`W{lj^>aWhCe{?_gZnt7NXiEt^NVzV$7 z=W1C&XiVZNomCSohL)8x*N=wUN-G>W#Ih)Cvp2BZd2 zg&UD$+sWH?CJFC(COVdh&C3a*?uF#rNzibRAcdzYt0hKn#(ccUcYqOU+- zk%^`m(N8Js8C1DVmaZm-@@j~x3Hq998%FCi@dhs?}uWm$!mE2$|&gLxy4 z>lauB&km<;jfM%N_Hr~?%s^4#TDzs23J9NkG^MEI8Ry1*0oxn}DPQPEDX^@1L3HRu zl>OZLYHK}MM|R5AlvHyHsR;y|uIbv$&=ta+*2nB3X(oa8YgQ^&U-m*ISj5`P4m6DO z>eDQ?Rae$UD1Qju7i>AItq<1=_R0$p<#GjF7w`gITxVK<)DkkuO`Xn;6G zrQ_nHSUf{SCCC-Lm`1O*M}-SgK}>(IM%WsbFFaChtt|+z(%7 z&OSRG9>Zg#k3hc1doM1tenXQbCv%e5sk+gT>rT;0Q7c>r$yBnhT9HDtL5l68;|b!+ z9Za3@>^FQ84RjIY8Nty1qCvyQPdU`JiYFvTVWu4IaBJAK`suiIVyDY)eISv!$Ma+H!d{G?9DQ~WEyXyJ90W$|MrxW-#bWEmrSLH=~ojGrq{T|Z6GKW0tvd1cWb@BxR=DHoBTGu1q<5S>}% z;%I#oEbfF5iN8Hy?inC?2jS^EQdDFPpEr4R{vpOtMH0&q$4FZccV@JB#@;fcJ%nYz zFhMpSSiz847)toH1xv8PuASlR%Xl-Ur5Dbg_yDrQ(MprQSPT|dMIS9B2cnFjJASL# z_nIpDF|3{neIIy+d;4KmKO2VZ?0+LW917eEg#Y}&?FAebJT~QPj+Y2HAWp7#@9pfV zl;8Y??Y`gs0(RJM;Y0w>07T`Y-Ti&4AXFf+q^7x=_z726L{xS?=F1p-e6S*20~nkb zKNj*@Jp!4A{!@kd+Azd6cBbzZ_c#ODC1WIWk4?Cxf+0o)+cJS~EEXXx&H$1}?@r#i zKowr1O_$<5f}gjXIf`;D9>`s#5^Q6HmPV(* zEAOB?FMZ9PeJW&S`fT+;=ia`SjbyQf0Yqw6UQZI4kVv(m#0u>#N&A^!$7o7l`ldNq z_MGX)#Sv(XPEGz$dpyS6Nq?h7l$4NcAtFGQGJN|G1ZS5g>5;51omg%LLFO9gFtY82 zJa!gEpYxcw&`HcuX3T_V!|4BTFYuX>+NVY?G~+z-Pb!F2WbNLWR4_O6g%Xp~eBL=X zeVUV-iIPe-3zeZUR~!8O43N*!rDK6oO7|^82QGvpp4vsU2=ij7xpVp_f)}xSXEx?Q zREqHty;crgKY$qItBt!VXlsP-tZ zefvw9KOW|83}!+ngWFQGbZzA)M^j9DmWXaDK19UzgOzE@qStoPX~uFTY=2Y3_M`Gb zNMmdIcSv4uA4~ASh4~EZRtbSDn9ZIvWX>p#l1f|q5tBCa2s}HDAaVmfrG>RTtGnf1 zf>n$@#L5}Wq_;aupyFtct{p>6RiyivjJNXdscE$=4g~w<`-s^IFf4|@avPFnx*3bnug89&Y}~kWOmg^(*0LqXpUK(lF1C{vRBv{ z2coZUu?XWJxlh5F)K2ZzkoYrhI-vaDN`TG08d{amtK`(K^C76WVeN`5r+>zdE6c(v z6fOjX6_`VSR?-QrMNow`<^2Lc)?|JE?-McPG4y&Whkk)Vuc>&Y|VdG`MR D0ofl= literal 0 HcmV?d00001 diff --git a/test-img/cat2_32px.jpeg b/test-img/cat2_32px.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..116d05d2e2be4eaa2d463038398859ecf301d238 GIT binary patch literal 1077 zcmex=WnyY(ZeeNV?BeR??&0Yb91<+v*#~fzWVs-^OvvRzW@07i;;mD;vFCf@eq=K1cClx z0);s{$UlrsuS~;l_iU%Emz-M3agxa*3&!JXHM% z@)Fob#CfQREFZx=1ozMXTMRtRjKBzE7G$tz_~ZC@(!G23x7r`x*6Yn9 zM*qCJSDdWTSC=iYe6)YT`5XJc&A9xo#@lZ9@|wU4k1u|aExKjB{)bonmb@>Y)^MNE znRNBgk^?11$_l!d*VeK9JFxAWdHr_&gTH-)RH`HE)G{)QWtz1v&VJF%{Kn0-?#ds# zzq4&De_Ow>I^SZWUSD0AT)r;$UewY90lAMSp7hwnenvzl&t~4&&yi2#ljG+6*1z&A zr&nu6)s*|;zvROzzJHticix`hkB>t>svkbzb?n@&$8Wxw{o?CiY`XWzb$^Y|UrqJ| zop4rk6*SULm7nKYZ)(5&>h7qzJNqSdwu7I%*CwDnwnr~l^p zgVSc6KW@vVFL2`0LEigwWmuisN?9kEueihhG`?Ma`|ByX*a;wF