From e2a1d7a0195d40d3aa0b9303c1e78e1aa56b1453 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Tue, 16 Jul 2019 16:09:48 -0400 Subject: [PATCH] Assorted fixes and things (#1740) --- buffalo/cmd/destroy/mailer.go | 14 +- buffalo/cmd/filetests/destroy_mailer_all.json | 20 +- .../cmd/filetests/generate_action_all.json | 43 +- .../generate_action_skip_template.json | 27 +- .../generate_action_with_method.json | 35 +- buffalo/cmd/filetests/generate_mailer.json | 8 +- .../generate_resource_nested_web.json | 6 +- buffalo/cmd/fix/fix.go | 1 + buffalo/cmd/fix/plush.go | 50 +++ .../user/{edit.html => edit.plush.html} | 0 .../user/{index.html => index.plush.html} | 0 .../user/{edit.html => edit.plush.html} | 0 .../user/{show.html => show.plush.html} | 0 .../user/{edit.html => edit.plush.html} | 0 .../user/{show.html => show.plush.html} | 0 genny/actions/actions_test.go | 8 +- genny/actions/build_templates.go | 4 +- .../{view.html.tmpl => view.plush.html.tmpl} | 0 genny/build/_fixtures/coke/yarn.lock | 6 +- .../templates/templates/mail/layout.html.tmpl | 3 - .../templates/mail/layout.plush.html.tmpl | 3 + genny/mail/mail.go | 4 +- genny/mail/mail_test.go | 10 +- ...flash.html.tmpl => _flash.plush.html.tmpl} | 0 ....html.tmpl => application.plush.html.tmpl} | 0 ...{index.html.tmpl => index.plush.html.tmpl} | 0 .../widgets/{_form.html => _form.plush.html} | 0 .../widgets/{edit.html => edit.plush.html} | 0 .../widgets/{index.html => index.plush.html} | 0 .../widgets/{new.html => new.plush.html} | 0 .../widgets/{show.html => show.plush.html} | 0 .../widgets/{_form.html => _form.plush.html} | 0 .../widgets/{edit.html => edit.plush.html} | 0 .../widgets/{index.html => index.plush.html} | 0 .../widgets/{new.html => new.plush.html} | 0 .../widgets/{show.html => show.plush.html} | 0 genny/resource/resource_test.go | 4 +- ...{_form.html.tmpl => _form.plush.html.tmpl} | 0 .../{edit.html.tmpl => edit.plush.html.tmpl} | 0 ...{index.html.tmpl => index.plush.html.tmpl} | 0 .../{new.html.tmpl => new.plush.html.tmpl} | 0 .../{show.html.tmpl => show.plush.html.tmpl} | 0 go.mod | 4 +- go.sum | 7 +- .../takeon/github.com/gobuffalo/syncx/LICENSE | 21 + .../github.com/gobuffalo/syncx/README.md | 18 + .../github.com/gobuffalo/syncx/byte_map.go | 73 ++++ .../github.com/gobuffalo/syncx/int_map.go | 73 ++++ .../gobuffalo/syncx/interface_map.go | 73 ++++ .../github.com/gobuffalo/syncx/string_map.go | 73 ++++ .../github.com/gobuffalo/syncx/version.go | 4 + packrd/packed-packr.go | 40 +- render/auto_test.go | 409 ++++++++++-------- render/download_test.go | 105 +++-- render/func_test.go | 19 +- render/html_test.go | 131 +++--- render/js_test.go | 38 ++ render/render.go | 3 + render/render_test.go | 12 + render/template.go | 55 ++- resource.go | 4 +- route_mappings.go | 2 +- 62 files changed, 962 insertions(+), 448 deletions(-) create mode 100644 buffalo/cmd/fix/plush.go rename genny/actions/_fixtures/inputs/existing/templates/user/{edit.html => edit.plush.html} (100%) rename genny/actions/_fixtures/outputs/clean/templates/user/{index.html => index.plush.html} (100%) rename genny/actions/_fixtures/outputs/existing/templates/user/{edit.html => edit.plush.html} (100%) rename genny/actions/_fixtures/outputs/existing/templates/user/{show.html => show.plush.html} (100%) rename genny/actions/_fixtures/outputs/multi/templates/user/{edit.html => edit.plush.html} (100%) rename genny/actions/_fixtures/outputs/multi/templates/user/{show.html => show.plush.html} (100%) rename genny/actions/templates/{view.html.tmpl => view.plush.html.tmpl} (100%) delete mode 100644 genny/mail/init/templates/templates/mail/layout.html.tmpl create mode 100644 genny/mail/init/templates/templates/mail/layout.plush.html.tmpl rename genny/newapp/web/templates/templates/{_flash.html.tmpl => _flash.plush.html.tmpl} (100%) rename genny/newapp/web/templates/templates/{application.html.tmpl => application.plush.html.tmpl} (100%) rename genny/newapp/web/templates/templates/{index.html.tmpl => index.plush.html.tmpl} (100%) rename genny/resource/_fixtures/default/templates/widgets/{_form.html => _form.plush.html} (100%) rename genny/resource/_fixtures/default/templates/widgets/{edit.html => edit.plush.html} (100%) rename genny/resource/_fixtures/default/templates/widgets/{index.html => index.plush.html} (100%) rename genny/resource/_fixtures/default/templates/widgets/{new.html => new.plush.html} (100%) rename genny/resource/_fixtures/default/templates/widgets/{show.html => show.plush.html} (100%) rename genny/resource/_fixtures/nested/templates/admin/widgets/{_form.html => _form.plush.html} (100%) rename genny/resource/_fixtures/nested/templates/admin/widgets/{edit.html => edit.plush.html} (100%) rename genny/resource/_fixtures/nested/templates/admin/widgets/{index.html => index.plush.html} (100%) rename genny/resource/_fixtures/nested/templates/admin/widgets/{new.html => new.plush.html} (100%) rename genny/resource/_fixtures/nested/templates/admin/widgets/{show.html => show.plush.html} (100%) rename genny/resource/templates/core/templates/folder-name/{_form.html.tmpl => _form.plush.html.tmpl} (100%) rename genny/resource/templates/core/templates/folder-name/{edit.html.tmpl => edit.plush.html.tmpl} (100%) rename genny/resource/templates/core/templates/folder-name/{index.html.tmpl => index.plush.html.tmpl} (100%) rename genny/resource/templates/core/templates/folder-name/{new.html.tmpl => new.plush.html.tmpl} (100%) rename genny/resource/templates/core/templates/folder-name/{show.html.tmpl => show.plush.html.tmpl} (100%) create mode 100644 internal/takeon/github.com/gobuffalo/syncx/LICENSE create mode 100644 internal/takeon/github.com/gobuffalo/syncx/README.md create mode 100644 internal/takeon/github.com/gobuffalo/syncx/byte_map.go create mode 100644 internal/takeon/github.com/gobuffalo/syncx/int_map.go create mode 100644 internal/takeon/github.com/gobuffalo/syncx/interface_map.go create mode 100644 internal/takeon/github.com/gobuffalo/syncx/string_map.go create mode 100644 internal/takeon/github.com/gobuffalo/syncx/version.go diff --git a/buffalo/cmd/destroy/mailer.go b/buffalo/cmd/destroy/mailer.go index bebbc3cb3..0e9269875 100644 --- a/buffalo/cmd/destroy/mailer.go +++ b/buffalo/cmd/destroy/mailer.go @@ -33,10 +33,16 @@ func removeMailer(name string) { if YesToAll || confirm("Want to remove mailer? (y/N)") { mailerFileName := flect.Singularize(flect.Underscore(name)) - os.Remove(filepath.Join("mailers", fmt.Sprintf("%v.go", mailerFileName))) - os.Remove(filepath.Join("templates/mail", fmt.Sprintf("%v.html", mailerFileName))) + files := []string{ + filepath.Join("mailers", fmt.Sprintf("%v.go", mailerFileName)), + filepath.Join("templates/mail", fmt.Sprintf("%v.html", mailerFileName)), + filepath.Join("templates/mail", fmt.Sprintf("%v.plush.html", mailerFileName)), + } + + for _, f := range files { + os.Remove(f) + logrus.Infof("- Deleted %v", f) + } - logrus.Infof("- Deleted %v", fmt.Sprintf("mailers/%v.go", mailerFileName)) - logrus.Infof("- Deleted %v", fmt.Sprintf("templates/mail/%v.html", mailerFileName)) } } diff --git a/buffalo/cmd/filetests/destroy_mailer_all.json b/buffalo/cmd/filetests/destroy_mailer_all.json index b630f06ec..358c1fd42 100644 --- a/buffalo/cmd/filetests/destroy_mailer_all.json +++ b/buffalo/cmd/filetests/destroy_mailer_all.json @@ -1,8 +1,14 @@ [{ - "path": "mailers/ouch.go", - "absent": true -}, -{ - "path": "templates/mail/ouch.html", - "absent": true -}] \ No newline at end of file + "path": "mailers/ouch.go", + "absent": true + }, + { + "path": "templates/mail/ouch.html", + "absent": true + }, + { + "path": "templates/mail/ouch.plush.html", + "absent": true + } + +] diff --git a/buffalo/cmd/filetests/generate_action_all.json b/buffalo/cmd/filetests/generate_action_all.json index 296f03c97..347e183bb 100644 --- a/buffalo/cmd/filetests/generate_action_all.json +++ b/buffalo/cmd/filetests/generate_action_all.json @@ -1,22 +1,23 @@ [{ - "path": "actions/comments.go", - "contains": [ - "func CommentsShow(c buffalo.Context) error {", - "func CommentsEdit(c buffalo.Context) error {", - "comments/edit.html", - "comments/show.html" - ] -}, -{ - "path": "actions/app.go", - "contains": [ - "app.GET(\"/comments/show\", CommentsShow)", - "app.GET(\"/comments/edit\", CommentsEdit)" - ] -}, -{ - "path": "templates/comments/show.html", - "contains": [ - "

Comments#Show

" - ] -}] \ No newline at end of file + "path": "actions/comments.go", + "contains": [ + "func CommentsShow(c buffalo.Context) error {", + "func CommentsEdit(c buffalo.Context) error {", + "comments/edit.html", + "comments/show.html" + ] + }, + { + "path": "actions/app.go", + "contains": [ + "app.GET(\"/comments/show\", CommentsShow)", + "app.GET(\"/comments/edit\", CommentsEdit)" + ] + }, + { + "path": "templates/comments/show.plush.html", + "contains": [ + "

Comments#Show

" + ] + } +] diff --git a/buffalo/cmd/filetests/generate_action_skip_template.json b/buffalo/cmd/filetests/generate_action_skip_template.json index 78372ebf0..9457342cd 100644 --- a/buffalo/cmd/filetests/generate_action_skip_template.json +++ b/buffalo/cmd/filetests/generate_action_skip_template.json @@ -1,12 +1,15 @@ -[ - { - "path": "actions/users.go", - "contains": [ - "func UsersCreate(c buffalo.Context) error {" - ] - }, - { - "path": "templates/users/create.html", - "absent": true - } -] \ No newline at end of file +[{ + "path": "actions/users.go", + "contains": [ + "func UsersCreate(c buffalo.Context) error {" + ] + }, + { + "path": "templates/users/create.html", + "absent": true + }, + { + "path": "templates/users/create.plush.html", + "absent": true + } +] diff --git a/buffalo/cmd/filetests/generate_action_with_method.json b/buffalo/cmd/filetests/generate_action_with_method.json index 342cd3616..0492c6f44 100644 --- a/buffalo/cmd/filetests/generate_action_with_method.json +++ b/buffalo/cmd/filetests/generate_action_with_method.json @@ -1,16 +1,19 @@ -[ - { - "path": "actions/users.go", - "contains": [ - "func UsersCreate(c buffalo.Context) error {" - ] - }, - { - "path": "templates/users/update.html", - "absent": true - }, - { - "path": "actions/app.go", - "contains": ["app.POST(\"/users/update\", UsersUpdate)"] - } -] \ No newline at end of file +[{ + "path": "actions/users.go", + "contains": [ + "func UsersCreate(c buffalo.Context) error {" + ] + }, + { + "path": "templates/users/update.html", + "absent": true + }, + { + "path": "templates/users/update.plush.html", + "absent": true + }, + { + "path": "actions/app.go", + "contains": ["app.POST(\"/users/update\", UsersUpdate)"] + } +] diff --git a/buffalo/cmd/filetests/generate_mailer.json b/buffalo/cmd/filetests/generate_mailer.json index 01acbd54c..9785d1e64 100644 --- a/buffalo/cmd/filetests/generate_mailer.json +++ b/buffalo/cmd/filetests/generate_mailer.json @@ -9,9 +9,9 @@ ] }, { - "path": "templates/mail/layout.html", + "path": "templates/mail/layout.plush.html", "contains": [ - "

templates/mailers/layout.html

" + "

templates/mailers/layout.plush.html

" ] }, { @@ -21,10 +21,10 @@ ] }, { - "path": "templates/mail/welcome_email.html", + "path": "templates/mail/welcome_email.plush.html", "contains": [ "

Welcome Email

", - "

../templates/mail/welcome_email.html

" + "

../templates/mail/welcome_email.plush.html

" ] } ] diff --git a/buffalo/cmd/filetests/generate_resource_nested_web.json b/buffalo/cmd/filetests/generate_resource_nested_web.json index fee35f17f..11e04d498 100644 --- a/buffalo/cmd/filetests/generate_resource_nested_web.json +++ b/buffalo/cmd/filetests/generate_resource_nested_web.json @@ -20,19 +20,19 @@ ] }, { - "path": "templates/admin/planes/_form.html", + "path": "templates/admin/planes/_form.plush.html", "contains": [ "" ] }, { - "path": "templates/admin/planes/index.html", + "path": "templates/admin/planes/index.plush.html", "contains": [ "newAdminPlanesPath()" ] }, { - "path": "templates/admin/planes/show.html", + "path": "templates/admin/planes/show.plush.html", "contains": [ "editAdminPlanePath({ admin_plane_id: plane.ID })" ] diff --git a/buffalo/cmd/fix/fix.go b/buffalo/cmd/fix/fix.go index a3e2c0767..ebeec7652 100644 --- a/buffalo/cmd/fix/fix.go +++ b/buffalo/cmd/fix/fix.go @@ -61,6 +61,7 @@ var checks = []Check{ fixDocker, encodeApp, Plugins, + Plush, } func encodeApp(r *Runner) error { diff --git a/buffalo/cmd/fix/plush.go b/buffalo/cmd/fix/plush.go new file mode 100644 index 000000000..96c62902a --- /dev/null +++ b/buffalo/cmd/fix/plush.go @@ -0,0 +1,50 @@ +package fix + +import ( + "fmt" + "io" + "os" + "path/filepath" + "strings" +) + +// Plush will update foo.html templates to foo.plush.html templates +func Plush(r *Runner) error { + fmt.Println("~~~ Adding .plush extension to .html files ~~~") + return filepath.Walk(r.App.Root, func(p string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + dir := filepath.Dir(p) + base := filepath.Base(p) + sep := strings.Split(base, ".") + + if filepath.Ext(p) != ".html" { + return nil + } + + if len(sep) != 2 { + return nil + } + + pn := filepath.Join(dir, sep[0]+".plush."+sep[1]) + + fn, err := os.Create(pn) + if err != nil { + return err + } + defer fn.Close() + + fo, err := os.Open(p) + if err != nil { + return err + } + defer fo.Close() + _, err = io.Copy(fn, fo) + + defer os.Remove(p) + + return err + }) +} diff --git a/genny/actions/_fixtures/inputs/existing/templates/user/edit.html b/genny/actions/_fixtures/inputs/existing/templates/user/edit.plush.html similarity index 100% rename from genny/actions/_fixtures/inputs/existing/templates/user/edit.html rename to genny/actions/_fixtures/inputs/existing/templates/user/edit.plush.html diff --git a/genny/actions/_fixtures/outputs/clean/templates/user/index.html b/genny/actions/_fixtures/outputs/clean/templates/user/index.plush.html similarity index 100% rename from genny/actions/_fixtures/outputs/clean/templates/user/index.html rename to genny/actions/_fixtures/outputs/clean/templates/user/index.plush.html diff --git a/genny/actions/_fixtures/outputs/existing/templates/user/edit.html b/genny/actions/_fixtures/outputs/existing/templates/user/edit.plush.html similarity index 100% rename from genny/actions/_fixtures/outputs/existing/templates/user/edit.html rename to genny/actions/_fixtures/outputs/existing/templates/user/edit.plush.html diff --git a/genny/actions/_fixtures/outputs/existing/templates/user/show.html b/genny/actions/_fixtures/outputs/existing/templates/user/show.plush.html similarity index 100% rename from genny/actions/_fixtures/outputs/existing/templates/user/show.html rename to genny/actions/_fixtures/outputs/existing/templates/user/show.plush.html diff --git a/genny/actions/_fixtures/outputs/multi/templates/user/edit.html b/genny/actions/_fixtures/outputs/multi/templates/user/edit.plush.html similarity index 100% rename from genny/actions/_fixtures/outputs/multi/templates/user/edit.html rename to genny/actions/_fixtures/outputs/multi/templates/user/edit.plush.html diff --git a/genny/actions/_fixtures/outputs/multi/templates/user/show.html b/genny/actions/_fixtures/outputs/multi/templates/user/show.plush.html similarity index 100% rename from genny/actions/_fixtures/outputs/multi/templates/user/show.html rename to genny/actions/_fixtures/outputs/multi/templates/user/show.plush.html diff --git a/genny/actions/actions_test.go b/genny/actions/actions_test.go index 8f3d08ffe..1c45b26d1 100644 --- a/genny/actions/actions_test.go +++ b/genny/actions/actions_test.go @@ -53,15 +53,13 @@ func Test_New(t *testing.T) { box := packr.New("genny/actions/Test_New", "../actions/_fixtures/outputs/clean") - files := []string{"actions/user.go.tmpl", "actions/app.go.tmpl", "actions/user_test.go.tmpl", "templates/user/index.html"} + files := []string{"actions/user.go.tmpl", "actions/app.go.tmpl", "actions/user_test.go.tmpl", "templates/user/index.plush.html"} for _, s := range files { x, err := box.FindString(s) r.NoError(err) f, err := res.Find(strings.TrimSuffix(s, ".tmpl")) r.NoError(err) - fmt.Println(x) - fmt.Println(f.String()) r.True(compare(x, f.String())) } } @@ -87,7 +85,7 @@ func Test_New_Multi(t *testing.T) { box := packr.New("genny/actions/Test_New_Multi", "../actions/_fixtures/outputs/multi") - files := []string{"actions/user.go.tmpl", "actions/app.go.tmpl", "actions/user_test.go.tmpl", "templates/user/show.html", "templates/user/edit.html"} + files := []string{"actions/user.go.tmpl", "actions/app.go.tmpl", "actions/user_test.go.tmpl", "templates/user/show.plush.html", "templates/user/edit.plush.html"} for _, s := range files { x, err := box.FindString(s) @@ -126,7 +124,7 @@ func Test_New_Multi_Existing(t *testing.T) { box := packr.New("genny/actions/Test_New_Multi_Existing", "../actions/_fixtures/outputs/existing") - files := []string{"actions/user.go.tmpl", "actions/app.go.tmpl", "actions/user_test.go.tmpl", "templates/user/show.html", "templates/user/edit.html"} + files := []string{"actions/user.go.tmpl", "actions/app.go.tmpl", "actions/user_test.go.tmpl", "templates/user/show.plush.html", "templates/user/edit.plush.html"} for _, s := range files { x, err := box.FindString(s) diff --git a/genny/actions/build_templates.go b/genny/actions/build_templates.go index a4768adde..1336c963d 100644 --- a/genny/actions/build_templates.go +++ b/genny/actions/build_templates.go @@ -8,13 +8,13 @@ import ( func buildTemplates(pres *presenter) genny.RunFn { return func(r *genny.Runner) error { - f, err := box.FindString("view.html.tmpl") + f, err := box.FindString("view.plush.html.tmpl") if err != nil { return err } for _, a := range pres.Actions { pres.Data["action"] = a - fn := fmt.Sprintf("templates/%s/%s.html.tmpl", pres.Name.Folder(), a.File()) + fn := fmt.Sprintf("templates/%s/%s.plush.html.tmpl", pres.Name.Folder(), a.File()) xf := genny.NewFileS(fn, f) xf, err = transform(pres, xf) if err != nil { diff --git a/genny/actions/templates/view.html.tmpl b/genny/actions/templates/view.plush.html.tmpl similarity index 100% rename from genny/actions/templates/view.html.tmpl rename to genny/actions/templates/view.plush.html.tmpl diff --git a/genny/build/_fixtures/coke/yarn.lock b/genny/build/_fixtures/coke/yarn.lock index c4ad8b77b..81ffabd2c 100644 --- a/genny/build/_fixtures/coke/yarn.lock +++ b/genny/build/_fixtures/coke/yarn.lock @@ -2847,9 +2847,9 @@ lodash.debounce@^4.0.8: integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= lodash.mergewith@^4.6.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" - integrity sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ== + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" + integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== lodash.tail@^4.1.1: version "4.1.1" diff --git a/genny/mail/init/templates/templates/mail/layout.html.tmpl b/genny/mail/init/templates/templates/mail/layout.html.tmpl deleted file mode 100644 index 7d88c8fe6..000000000 --- a/genny/mail/init/templates/templates/mail/layout.html.tmpl +++ /dev/null @@ -1,3 +0,0 @@ -

templates/mailers/layout.html

- -<%= yield %> diff --git a/genny/mail/init/templates/templates/mail/layout.plush.html.tmpl b/genny/mail/init/templates/templates/mail/layout.plush.html.tmpl new file mode 100644 index 000000000..8b3241e9d --- /dev/null +++ b/genny/mail/init/templates/templates/mail/layout.plush.html.tmpl @@ -0,0 +1,3 @@ +

templates/mailers/layout.plush.html

+ +<%= yield %> diff --git a/genny/mail/mail.go b/genny/mail/mail.go index de4de0daa..7e74b3ad3 100644 --- a/genny/mail/mail.go +++ b/genny/mail/mail.go @@ -34,7 +34,7 @@ func New(opts *Options) (*genny.Group, error) { fn := opts.Name.File().String() g.File(genny.NewFileS("mailers/"+fn+".go.tmpl", mailerTmpl)) - g.File(genny.NewFileS("templates/mail/"+fn+".html.tmpl", mailTmpl)) + g.File(genny.NewFileS("templates/mail/"+fn+".plush.html.tmpl", mailTmpl)) gg.Add(g) return gg, nil @@ -83,4 +83,4 @@ func Send{{.opts.Name.Resource}}() error { const mailTmpl = `

{{.opts.Name.Titleize}}

-

../templates/mail/{{.opts.Name.File}}.html

` +

../templates/mail/{{.opts.Name.File}}.plush.html

` diff --git a/genny/mail/mail_test.go b/genny/mail/mail_test.go index fd7f6f34a..5ba9a873a 100644 --- a/genny/mail/mail_test.go +++ b/genny/mail/mail_test.go @@ -31,12 +31,12 @@ func Test_New_NoMailers(t *testing.T) { r.Equal("mailers/mailers.go", f.Name()) f = res.Files[2] - r.Equal("templates/mail/foo.html", f.Name()) + r.Equal("templates/mail/foo.plush.html", f.Name()) body = f.String() - r.Contains(body, `

../templates/mail/foo.html

`) + r.Contains(body, `

../templates/mail/foo.plush.html

`) f = res.Files[3] - r.Equal("templates/mail/layout.html", f.Name()) + r.Equal("templates/mail/layout.plush.html", f.Name()) } func Test_New_WithMailers(t *testing.T) { @@ -60,7 +60,7 @@ func Test_New_WithMailers(t *testing.T) { r.Contains(body, `err := m.AddBody(r.HTML("foo.html"), render.Data{})`) f = res.Files[2] - r.Equal("templates/mail/foo.html", f.Name()) + r.Equal("templates/mail/foo.plush.html", f.Name()) body = f.String() - r.Contains(body, `

../templates/mail/foo.html

`) + r.Contains(body, `

../templates/mail/foo.plush.html

`) } diff --git a/genny/newapp/web/templates/templates/_flash.html.tmpl b/genny/newapp/web/templates/templates/_flash.plush.html.tmpl similarity index 100% rename from genny/newapp/web/templates/templates/_flash.html.tmpl rename to genny/newapp/web/templates/templates/_flash.plush.html.tmpl diff --git a/genny/newapp/web/templates/templates/application.html.tmpl b/genny/newapp/web/templates/templates/application.plush.html.tmpl similarity index 100% rename from genny/newapp/web/templates/templates/application.html.tmpl rename to genny/newapp/web/templates/templates/application.plush.html.tmpl diff --git a/genny/newapp/web/templates/templates/index.html.tmpl b/genny/newapp/web/templates/templates/index.plush.html.tmpl similarity index 100% rename from genny/newapp/web/templates/templates/index.html.tmpl rename to genny/newapp/web/templates/templates/index.plush.html.tmpl diff --git a/genny/resource/_fixtures/default/templates/widgets/_form.html b/genny/resource/_fixtures/default/templates/widgets/_form.plush.html similarity index 100% rename from genny/resource/_fixtures/default/templates/widgets/_form.html rename to genny/resource/_fixtures/default/templates/widgets/_form.plush.html diff --git a/genny/resource/_fixtures/default/templates/widgets/edit.html b/genny/resource/_fixtures/default/templates/widgets/edit.plush.html similarity index 100% rename from genny/resource/_fixtures/default/templates/widgets/edit.html rename to genny/resource/_fixtures/default/templates/widgets/edit.plush.html diff --git a/genny/resource/_fixtures/default/templates/widgets/index.html b/genny/resource/_fixtures/default/templates/widgets/index.plush.html similarity index 100% rename from genny/resource/_fixtures/default/templates/widgets/index.html rename to genny/resource/_fixtures/default/templates/widgets/index.plush.html diff --git a/genny/resource/_fixtures/default/templates/widgets/new.html b/genny/resource/_fixtures/default/templates/widgets/new.plush.html similarity index 100% rename from genny/resource/_fixtures/default/templates/widgets/new.html rename to genny/resource/_fixtures/default/templates/widgets/new.plush.html diff --git a/genny/resource/_fixtures/default/templates/widgets/show.html b/genny/resource/_fixtures/default/templates/widgets/show.plush.html similarity index 100% rename from genny/resource/_fixtures/default/templates/widgets/show.html rename to genny/resource/_fixtures/default/templates/widgets/show.plush.html diff --git a/genny/resource/_fixtures/nested/templates/admin/widgets/_form.html b/genny/resource/_fixtures/nested/templates/admin/widgets/_form.plush.html similarity index 100% rename from genny/resource/_fixtures/nested/templates/admin/widgets/_form.html rename to genny/resource/_fixtures/nested/templates/admin/widgets/_form.plush.html diff --git a/genny/resource/_fixtures/nested/templates/admin/widgets/edit.html b/genny/resource/_fixtures/nested/templates/admin/widgets/edit.plush.html similarity index 100% rename from genny/resource/_fixtures/nested/templates/admin/widgets/edit.html rename to genny/resource/_fixtures/nested/templates/admin/widgets/edit.plush.html diff --git a/genny/resource/_fixtures/nested/templates/admin/widgets/index.html b/genny/resource/_fixtures/nested/templates/admin/widgets/index.plush.html similarity index 100% rename from genny/resource/_fixtures/nested/templates/admin/widgets/index.html rename to genny/resource/_fixtures/nested/templates/admin/widgets/index.plush.html diff --git a/genny/resource/_fixtures/nested/templates/admin/widgets/new.html b/genny/resource/_fixtures/nested/templates/admin/widgets/new.plush.html similarity index 100% rename from genny/resource/_fixtures/nested/templates/admin/widgets/new.html rename to genny/resource/_fixtures/nested/templates/admin/widgets/new.plush.html diff --git a/genny/resource/_fixtures/nested/templates/admin/widgets/show.html b/genny/resource/_fixtures/nested/templates/admin/widgets/show.plush.html similarity index 100% rename from genny/resource/_fixtures/nested/templates/admin/widgets/show.html rename to genny/resource/_fixtures/nested/templates/admin/widgets/show.plush.html diff --git a/genny/resource/resource_test.go b/genny/resource/resource_test.go index be69a4709..ca9a9f604 100644 --- a/genny/resource/resource_test.go +++ b/genny/resource/resource_test.go @@ -68,7 +68,7 @@ func Test_New(t *testing.T) { nn := name.New(tt.Options.Name).Pluralize().String() actions := []string{"_form", "index", "show", "new", "edit"} for _, s := range actions { - p := path.Join("templates", nn, s+".html") + p := path.Join("templates", nn, s+".plush.html") _, err = res.Find(p) r.NoError(err) } @@ -210,7 +210,7 @@ func Test_New_UseModel(t *testing.T) { r.Len(res.Files, 9) for _, s := range []string{"_form", "edit", "index", "new", "show"} { - p := path.Join("templates", "widgets", s+".html") + p := path.Join("templates", "widgets", s+".plush.html") _, err = res.Find(p) r.NoError(err) } diff --git a/genny/resource/templates/core/templates/folder-name/_form.html.tmpl b/genny/resource/templates/core/templates/folder-name/_form.plush.html.tmpl similarity index 100% rename from genny/resource/templates/core/templates/folder-name/_form.html.tmpl rename to genny/resource/templates/core/templates/folder-name/_form.plush.html.tmpl diff --git a/genny/resource/templates/core/templates/folder-name/edit.html.tmpl b/genny/resource/templates/core/templates/folder-name/edit.plush.html.tmpl similarity index 100% rename from genny/resource/templates/core/templates/folder-name/edit.html.tmpl rename to genny/resource/templates/core/templates/folder-name/edit.plush.html.tmpl diff --git a/genny/resource/templates/core/templates/folder-name/index.html.tmpl b/genny/resource/templates/core/templates/folder-name/index.plush.html.tmpl similarity index 100% rename from genny/resource/templates/core/templates/folder-name/index.html.tmpl rename to genny/resource/templates/core/templates/folder-name/index.plush.html.tmpl diff --git a/genny/resource/templates/core/templates/folder-name/new.html.tmpl b/genny/resource/templates/core/templates/folder-name/new.plush.html.tmpl similarity index 100% rename from genny/resource/templates/core/templates/folder-name/new.html.tmpl rename to genny/resource/templates/core/templates/folder-name/new.plush.html.tmpl diff --git a/genny/resource/templates/core/templates/folder-name/show.html.tmpl b/genny/resource/templates/core/templates/folder-name/show.plush.html.tmpl similarity index 100% rename from genny/resource/templates/core/templates/folder-name/show.html.tmpl rename to genny/resource/templates/core/templates/folder-name/show.plush.html.tmpl diff --git a/go.mod b/go.mod index 5ad0ad839..3731b3ab0 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/gobuffalo/nulls v0.1.0 github.com/gobuffalo/packd v0.3.0 github.com/gobuffalo/packr/v2 v2.5.2 - github.com/gobuffalo/plush v3.8.2+incompatible + github.com/gobuffalo/plush v3.8.3+incompatible github.com/gobuffalo/pop v4.11.2+incompatible github.com/gobuffalo/release v1.8.3 github.com/gobuffalo/tags v2.1.0+incompatible @@ -45,7 +45,7 @@ require ( github.com/spf13/viper v1.4.0 github.com/stretchr/testify v1.3.0 golang.org/x/sync v0.0.0-20190423024810-112230192c58 - golang.org/x/tools v0.0.0-20190710184609-286818132824 + golang.org/x/tools v0.0.0-20190715221914-9b2cb0e5f602 gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc gopkg.in/yaml.v2 v2.2.2 ) diff --git a/go.sum b/go.sum index 1d7961c24..1bb64e40c 100644 --- a/go.sum +++ b/go.sum @@ -403,8 +403,9 @@ github.com/gobuffalo/plush v3.7.32+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5s github.com/gobuffalo/plush v3.7.33+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= github.com/gobuffalo/plush v3.7.34+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= github.com/gobuffalo/plush v3.8.0+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= -github.com/gobuffalo/plush v3.8.2+incompatible h1:EXtDf5L7TTwX8tEddtdHT+PT2lFerIKQm8Ye/M7O+54= github.com/gobuffalo/plush v3.8.2+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= +github.com/gobuffalo/plush v3.8.3+incompatible h1:kzvUTnFPhwyfPEsx7U7LI05/IIslZVGnAlMA1heWub8= +github.com/gobuffalo/plush v3.8.3+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= github.com/gobuffalo/plushgen v0.0.0-20181128164830-d29dcb966cb2/go.mod h1:r9QwptTFnuvSaSRjpSp4S2/4e2D3tJhARYbvEBcKSb4= github.com/gobuffalo/plushgen v0.0.0-20181203163832-9fc4964505c2/go.mod h1:opEdT33AA2HdrIwK1aibqnTJDVVKXC02Bar/GT1YRVs= github.com/gobuffalo/plushgen v0.0.0-20181207152837-eedb135bd51b/go.mod h1:Lcw7HQbEVm09sAQrCLzIxuhFbB3nAgp4c55E+UlynR0= @@ -947,8 +948,8 @@ golang.org/x/tools v0.0.0-20190613204242-ed0dc450797f/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190710184609-286818132824 h1:dOGf5KG5e5tnConXcTAnHv2YgmYJtrYjN9b1cMC21TY= -golang.org/x/tools v0.0.0-20190710184609-286818132824/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +golang.org/x/tools v0.0.0-20190715221914-9b2cb0e5f602 h1:/dPlQDpCQsf49+x/SZzxnM5BU1Ox4YEXhXHXcx6xIyw= +golang.org/x/tools v0.0.0-20190715221914-9b2cb0e5f602/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= diff --git a/internal/takeon/github.com/gobuffalo/syncx/LICENSE b/internal/takeon/github.com/gobuffalo/syncx/LICENSE new file mode 100644 index 000000000..a538bcbf2 --- /dev/null +++ b/internal/takeon/github.com/gobuffalo/syncx/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 Mark Bates + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/internal/takeon/github.com/gobuffalo/syncx/README.md b/internal/takeon/github.com/gobuffalo/syncx/README.md new file mode 100644 index 000000000..0f0d02b20 --- /dev/null +++ b/internal/takeon/github.com/gobuffalo/syncx/README.md @@ -0,0 +1,18 @@ +

+ +

+GoDoc +Go Report Card +

+ +# github.com/gobuffalo/syncx + +This package provides a set of types and tools for working in current environments. + +See [https://godoc.org/github.com/gobuffalo/syncx](https://godoc.org/github.com/gobuffalo/syncx) for more details. + +# Installation + +```bash +$ go get github.com/gobuffalo/syncx +``` diff --git a/internal/takeon/github.com/gobuffalo/syncx/byte_map.go b/internal/takeon/github.com/gobuffalo/syncx/byte_map.go new file mode 100644 index 000000000..39b7dae16 --- /dev/null +++ b/internal/takeon/github.com/gobuffalo/syncx/byte_map.go @@ -0,0 +1,73 @@ +//go:generate mapgen -name "Byte" -zero "[]byte(``)" -go-type "[]byte" -pkg "" -a "[]byte(`A`)" -b "[]byte(`B`)" -c "[]byte(`C`)" -bb "[]byte(`BB`)" -destination "syncx" +// Code generated by github.com/gobuffalo/mapgen. DO NOT EDIT. + +package syncx + +import ( + "sort" + "sync" +) + +// ByteMap wraps sync.Map and uses the following types: +// key: string +// value: []byte +type ByteMap struct { + data sync.Map +} + +// Delete the key from the map +func (m *ByteMap) Delete(key string) { + m.data.Delete(key) +} + +// Load the key from the map. +// Returns []byte or bool. +// A false return indicates either the key was not found +// or the value is not of type []byte +func (m *ByteMap) Load(key string) ([]byte, bool) { + i, ok := m.data.Load(key) + if !ok { + return []byte(``), false + } + s, ok := i.([]byte) + return s, ok +} + +// LoadOrStore will return an existing key or +// store the value if not already in the map +func (m *ByteMap) LoadOrStore(key string, value []byte) ([]byte, bool) { + i, _ := m.data.LoadOrStore(key, value) + s, ok := i.([]byte) + return s, ok +} + +// Range over the []byte values in the map +func (m *ByteMap) Range(f func(key string, value []byte) bool) { + m.data.Range(func(k, v interface{}) bool { + key, ok := k.(string) + if !ok { + return false + } + value, ok := v.([]byte) + if !ok { + return false + } + return f(key, value) + }) +} + +// Store a []byte in the map +func (m *ByteMap) Store(key string, value []byte) { + m.data.Store(key, value) +} + +// Keys returns a list of keys in the map +func (m *ByteMap) Keys() []string { + var keys []string + m.Range(func(key string, value []byte) bool { + keys = append(keys, key) + return true + }) + sort.Strings(keys) + return keys +} diff --git a/internal/takeon/github.com/gobuffalo/syncx/int_map.go b/internal/takeon/github.com/gobuffalo/syncx/int_map.go new file mode 100644 index 000000000..f6eba4dce --- /dev/null +++ b/internal/takeon/github.com/gobuffalo/syncx/int_map.go @@ -0,0 +1,73 @@ +//go:generate mapgen -name "Int" -zero "0" -go-type "int" -pkg "" -a "0" -b "1" -c "2" -bb "-1" -destination "syncx" +// Code generated by github.com/gobuffalo/mapgen. DO NOT EDIT. + +package syncx + +import ( + "sort" + "sync" +) + +// IntMap wraps sync.Map and uses the following types: +// key: string +// value: int +type IntMap struct { + data sync.Map +} + +// Delete the key from the map +func (m *IntMap) Delete(key string) { + m.data.Delete(key) +} + +// Load the key from the map. +// Returns int or bool. +// A false return indicates either the key was not found +// or the value is not of type int +func (m *IntMap) Load(key string) (int, bool) { + i, ok := m.data.Load(key) + if !ok { + return 0, false + } + s, ok := i.(int) + return s, ok +} + +// LoadOrStore will return an existing key or +// store the value if not already in the map +func (m *IntMap) LoadOrStore(key string, value int) (int, bool) { + i, _ := m.data.LoadOrStore(key, value) + s, ok := i.(int) + return s, ok +} + +// Range over the int values in the map +func (m *IntMap) Range(f func(key string, value int) bool) { + m.data.Range(func(k, v interface{}) bool { + key, ok := k.(string) + if !ok { + return false + } + value, ok := v.(int) + if !ok { + return false + } + return f(key, value) + }) +} + +// Store a int in the map +func (m *IntMap) Store(key string, value int) { + m.data.Store(key, value) +} + +// Keys returns a list of keys in the map +func (m *IntMap) Keys() []string { + var keys []string + m.Range(func(key string, value int) bool { + keys = append(keys, key) + return true + }) + sort.Strings(keys) + return keys +} diff --git a/internal/takeon/github.com/gobuffalo/syncx/interface_map.go b/internal/takeon/github.com/gobuffalo/syncx/interface_map.go new file mode 100644 index 000000000..93376135d --- /dev/null +++ b/internal/takeon/github.com/gobuffalo/syncx/interface_map.go @@ -0,0 +1,73 @@ +//go:generate mapgen -name "" -zero "nil" -go-type "interface{}" -pkg "" -a "0" -b "1" -c "2" -bb "-1" -destination "syncx" +// Code generated by github.com/gobuffalo/mapgen. DO NOT EDIT. + +package syncx + +import ( + "sort" + "sync" +) + +// Map wraps sync.Map and uses the following types: +// key: string +// value: interface{} +type Map struct { + data sync.Map +} + +// Delete the key from the map +func (m *Map) Delete(key string) { + m.data.Delete(key) +} + +// Load the key from the map. +// Returns interface{} or bool. +// A false return indicates either the key was not found +// or the value is not of type interface{} +func (m *Map) Load(key string) (interface{}, bool) { + i, ok := m.data.Load(key) + if !ok { + return nil, false + } + s, ok := i.(interface{}) + return s, ok +} + +// LoadOrStore will return an existing key or +// store the value if not already in the map +func (m *Map) LoadOrStore(key string, value interface{}) (interface{}, bool) { + i, _ := m.data.LoadOrStore(key, value) + s, ok := i.(interface{}) + return s, ok +} + +// Range over the interface{} values in the map +func (m *Map) Range(f func(key string, value interface{}) bool) { + m.data.Range(func(k, v interface{}) bool { + key, ok := k.(string) + if !ok { + return false + } + value, ok := v.(interface{}) + if !ok { + return false + } + return f(key, value) + }) +} + +// Store a interface{} in the map +func (m *Map) Store(key string, value interface{}) { + m.data.Store(key, value) +} + +// Keys returns a list of keys in the map +func (m *Map) Keys() []string { + var keys []string + m.Range(func(key string, value interface{}) bool { + keys = append(keys, key) + return true + }) + sort.Strings(keys) + return keys +} diff --git a/internal/takeon/github.com/gobuffalo/syncx/string_map.go b/internal/takeon/github.com/gobuffalo/syncx/string_map.go new file mode 100644 index 000000000..2bb37cf4b --- /dev/null +++ b/internal/takeon/github.com/gobuffalo/syncx/string_map.go @@ -0,0 +1,73 @@ +//go:generate mapgen -name "String" -zero "``" -go-type "string" -pkg "" -a "`A`" -b "`B`" -c "`C`" -bb "`BB`" -destination "syncx" +// Code generated by github.com/gobuffalo/mapgen. DO NOT EDIT. + +package syncx + +import ( + "sort" + "sync" +) + +// StringMap wraps sync.Map and uses the following types: +// key: string +// value: string +type StringMap struct { + data sync.Map +} + +// Delete the key from the map +func (m *StringMap) Delete(key string) { + m.data.Delete(key) +} + +// Load the key from the map. +// Returns string or bool. +// A false return indicates either the key was not found +// or the value is not of type string +func (m *StringMap) Load(key string) (string, bool) { + i, ok := m.data.Load(key) + if !ok { + return ``, false + } + s, ok := i.(string) + return s, ok +} + +// LoadOrStore will return an existing key or +// store the value if not already in the map +func (m *StringMap) LoadOrStore(key string, value string) (string, bool) { + i, _ := m.data.LoadOrStore(key, value) + s, ok := i.(string) + return s, ok +} + +// Range over the string values in the map +func (m *StringMap) Range(f func(key string, value string) bool) { + m.data.Range(func(k, v interface{}) bool { + key, ok := k.(string) + if !ok { + return false + } + value, ok := v.(string) + if !ok { + return false + } + return f(key, value) + }) +} + +// Store a string in the map +func (m *StringMap) Store(key string, value string) { + m.data.Store(key, value) +} + +// Keys returns a list of keys in the map +func (m *StringMap) Keys() []string { + var keys []string + m.Range(func(key string, value string) bool { + keys = append(keys, key) + return true + }) + sort.Strings(keys) + return keys +} diff --git a/internal/takeon/github.com/gobuffalo/syncx/version.go b/internal/takeon/github.com/gobuffalo/syncx/version.go new file mode 100644 index 000000000..97ee3e4ca --- /dev/null +++ b/internal/takeon/github.com/gobuffalo/syncx/version.go @@ -0,0 +1,4 @@ +package syncx + +// Version of syncx +const Version = "v0.0.1" diff --git a/packrd/packed-packr.go b/packrd/packed-packr.go index 47e82b343..9e109d373 100644 --- a/packrd/packed-packr.go +++ b/packrd/packed-packr.go @@ -28,24 +28,25 @@ var _ = func() error { "20f0fffdc5b71982ce85ee87b75fb3db": "1f8b08000000000000ff1cc9b16ac3301000d0d9fa8a4393548c6a3a163ad4a6d4433bd9d0b11cf2d988c8ba44270d21e4df43bcbe77467fc28d007d099c44a9b5260f06055e3e0f9a6a2864612629ff23ef34625a226563e1a69a4c02ef1f80e2c6f9f7c7e8576ddd371563956a50dcd7a562346f5dd7422671032f648f1838150c49cc937b5eae6e2a39a4cdd816f41f45cf3b4161e8ebba62646dd55d3d020000ffffeff2ca6daa000000", "219f70cdf30f6f12b6c726d0cb3c36b8": "1f8b08000000000000ff9490cb4ef3301085f7798aa9aafc6a16b137ff86aa170995dba61bd845883af124b67032953d2e1215ef8e720116b0e9caf2f89cef1ccf1ceed11dd187242966c575b44ec3232b8ee17961988f6129a5c69350efd1a3a8a895adf2afa5620cb28c75ad1cc91775b4fdcd3a2dc3e0950d4d8fc28cf86de9555799bd6a71ddaac0e8b30b0246b6eb87bcd558dbceb2a5ee41afff5ffdfb4d2e66c51deda8fa4968485325c837b2b16c6239047d97945f25c7f6229c9aec526f96e4799eec8971094fc606a8ad43b0015464ca1becd02b462d6047b027861b6d79b024ab740d357958980c6c07130fce906e92f91c8a432f30a2ff20a49bc35fc546c56d746e526503d5d6b03062475506678f1c7d07fd7235bd75d3fca30f59a5309c9f010000ffff3df549080c020000", "249b50674fa80d5d2389e61231cdbc08": "1f8b08000000000000ff2a484cce4e4c4f55484c2ec9cccf2be6e2cacc2dc82f2a51504acf2cc9284dd24bcecfd54fcf4f2a4d4b4bccc9d787d24a5c80000000ffffdd06e7bf37000000", - "32d6be02cb664211a2cdeac73239cf58": "1f8b08000000000000ffb491316bf3400c4077ff0a213038e03864358e3f3e921632b4189a76577c17fbe8f964e44b4a38eebf17676849876e9db43ca4f750a5cc055a4bd3b4c1913abdec35292d58270055bfae1f94f11042c1a39f8a2756da168df0a825c66ad5afeba45a2973a993a44a377062191e59b27bfe8d644b937e31aeb33ac61c02b5deb02bbff63ed3a07f620df93e0bf7484342c37e176309bf9e28f63b888b1c06ed7b562560f37ac0b88000e9ad2bddc048e20dd90c43284e6cd51cb49afd8bde0f1617dfa435eefdc0d95fbb86db134ac0a37770f46ef941e28ceb300754e469d9b23b1919b004fc2f1aae7c86e92cfa1fe67064752d01b7e45a6de7d0b44eaa14e23c3f030000ffff4803cb13e1010000", + "2b101e95a5f58f9db6a47dae28e04166": "1f8b08000000000000ff7c52cd8a1b3d10bcfb29fa1318fc416686dc72900cf9bb267b302c3985b6a667d56b8d24a4f62c8ef1bb87b16cafc3929c24d155d5adaad6ff7df9fe79f3e3e12b3819fd7aa1eb01a01d613f5f00f44882107024a326a69714b328b031080531ea857b71a6a7892d35e7c73be0c0c2e89b62d19379afee85acc35c488cdacbd07cb89684c5d3fad37e18d04768e07884362629edc794da6f3852bb9911fc8be074d25d852f008ec706788010e50effc8e21e699bd0eee074aa0d96068a1c3c1547241b7c5aa96d6dd6da52d4ffb0bcaa51e8ff41c2943c5b148ee19ef8a74bb6e4a1499871bcf309f7e228085b96c34f893b0a0ababf702fe51b771ee42d1f96eb5709cf610799bc516c6350e0320d176229240f286ea578c4272add80d30c6ad9c6f307ce21e8ee1ab9dec6feb05e54dd9e27b01e4b316a1e073950be84560d4a98e7ac576af0585c3b2fd0ab2b157260f2fdcda8aee7e9aabe34f08c13169b39bd35f8f9e6afeeea4cbaab0bfa3b0000ffff85cad3beb8020000", "380ebe4d9806da77bde6826811c711a7": "1f8b08000000000000ff84524d6bdc3010bdeb573c9425b40549ec2d98f410dab23d357b28ed31c8f25816ebb584242f856dfe7b91ec7c7443e9e99937efc333a8a5de477a4826ba901b06088c1344826a67377609ca7a95a2519b7764060f7e3e4b1f72927721c8bd36076d697fb08f8f1cbf61e60cd1812b0ed16fdfd734d33d47fccb5a75c743e722444098dbd119a553a29ceac87a58ca1033accbc3dc4ae38fcafa76ee7b3d7a7581ec7c16703d5eba7eba3c7ca680b5698dfb2b6bd493551d05658e5dc12aec2880a63447aa993426bac81019e204a9a4948b64ea9e14f42bf898b1bffbfef523df146836bbfb82aa7513672c656d292d27cf943263b28038e9981a5c3f7f33e0a4a3d3edb8a881ddfdc3976f3f1af0a2e18c5d615717c08962727e8219bc338481c64091c93991585614eea82d35b87e458dbab603eb6ca19b95fe9f7b2b6ede58b7f286b1e22ebf7b854f839e2c217bf0dbdb061fde74f3329b13210f8485c2ce3f6dc3804bdb525ad9d767aa176db0aef3f2a4cb85d7c7b10cff040000ffff5b69610df5020000", "3dc49c126d9ae937cfa7f3b28cd6695d": "1f8b08000000000000ff548fcb6dc3301044ef530a01ef36910e5c80409313890ec555b8348d741f08f900bebdc300efcd64cbd6152168906aeb0ff8672d8390921915b7d214633f14cd3297ddf2a3d215e2d1fd9262daa8089723a68f2eabe178dc6a491add39ced9f464990a597b791fec0a619ba749deaecb755827821c2523d9648f2bff41721c11e2b3419235b7ca652b3eac7fbde803e4be3dff5aeedb530282f819b23320171f8a958d3d0ee6b3e9f737be030000ffffcfa015bc01010000", "4458f74dae2e5b725e2ccf002ce9ed98": "1f8b08000000000000ff7492c18edb201086cfcc534c39d99585db957ab19443ab6ebb87dd4d14a7eab1621deca0624018278da2bc7b35d8de5372b060f0c7fcffcce065f357760a7ba98d0a0380eebd0b113360dcb88e0330dee97818df44e3fab2736f63db4ae3ca650dcaee55e0f730658fe7bb3f493c94c787bbc0b2923b0e39c051061cfae8935f5127ed7418f0e3e4443cda4e5b05d08eb6416d75cc72bc00b0b2c4cd688cb61d36ceb6bac336b81ee341a1b247012cd55dad283a8b9f2a66bc7ed96dfe6cd6db1d2f907ffef4f085e7c00e6eb8853dadeb8419d748430cb1e3a0c20df657fdb82596102f87e1e4c2fe96f2d7bafebdde7e9f516054a80ae973011835a24807aba91fafea4417a7b66464a240aaaa403252e0a245b9749b6e7e58a1d5062fc098719df821a334990a2107760560947aeeebab3a65f376eda37676b80022e2d3eee5f9599edd182be4266dc421f68617c0d84ef5dec8a8866fee5f8569de291197de57f39babe20251a14294eff134f7bc987494f1442f7ee6f8722d805d73b8c2ff000000ffff685bab16cb020000", - "44a6873412ed570728aad35c300c999b": "1f8b08000000000000ffb2c930b4abaed6cb4bcc4dd50b482c4e4eccc9ac4aadad55aeaed64b4c2ec9cccf4316b5d1cf30b4e302040000ffff9ca0bf3a33000000", "462c7c76f198fdd0129ec42ee775d844": "1f8b08000000000000ffbc92414b03311085effb2b1e2b85f552a878743d78d793b7b2946967acc126914cc2e2bf9760060b2a56058f99f95ee6bd4cd66bdd49a0e4e2347581bc60447f8859111f303bde4bd6beeb80777099697b9069ea00c024c7e8477899e2dc0480e32ab85a8c28c5f11d79e1a1e9fb732caefbc6d9d5f78f4ee1b4b9c1d9ca806de4970a68f462dd5ab3fe2e0965e10d651b18e23c1c8f28cffc25f1d320c329de2ffecdfb37fb2a2ae917dbfa34e42da527dc5016b50eb1770123722a62a57d652f57edf8167973ea5ff8e373bc060000fffff48dcecee6020000", "46725fddc2f766f41002e82e0f237bb5": "1f8b08000000000000ff010000ffff0000000000000000", "50f60207eb74d1b7f2b9b07fa815c278": "1f8b08000000000000ffecd1416b32311006e0fbfe8a21dfd945053f616fb215040b915d4be9496232c5c5b8b364a26d59f2df4b2c6a0f655bbc095e873c7933797bbd5e62f080969a1dd63e4b004ca52c6a9f8126bd75a4f4260e95576bc59841dba6d4784e170e5fabf71056df7802b021f6f190685b1102607d900e442ef3792127f96c3593e55280180cc7693feda70301104202d090eb740b594437fc3f1c8d4f66cfe8bacc53392d040847e4cf318af98d9ce98c9a94e5b32c1e0488cbebc866304a00a8f115d51c3f0a80d9eec86006a662b5b6781cfe63b6315263f74665f9b82aa45ce6d3e366a7a8af0bfe827f845bfcf8cdcda72f679678e4ab5a8fee5ef7cdd5dd38327b1d77baa6f48bbe577f6bd57f060000ffff849b5ab1ea050000", "5326a1f49e88f03a1e5f2c3a40e54348": "1f8b08000000000000ffac94516b1b490cc7dffd29747b70249038073e8e63215cdd26d0408883ed50fae41defcaf6d0d9d146a3716a8cbf7bd1aebdb6d3bad0d0079b5ded48fa4b3f692e2f2f3b052ed15155a297b4035058e33097149272159e5da22623666a02a690acd75daa24741f1967f6eb663339f0d6a30b0aeaea28374e9fd55611abadd7fbfb5f7d8d01398584899aaf268417e2a2357504c329257fea0f3e5384dc788d040682f57387f034bc87206cfd1c66c4200b84604a849cfcccce231bb1e4d35d8cc86e1737bdbad2c4a9febd3b6b95a7aaf7fceabb8255ddff95e180635be2b570c4bfcae8c48ec4086a1f42636434851ea128d7bdb057ff4082200b236067b0a25897914576d905902c908f2507308c10ac432f6e0576ee89b1e8d6a1ee3cc8c206c84dc08bba64ed421983680c31d683710e189fa3652cd4e831d7a8501936250a72e86e95fd8cb216fdbbf0564c45cc8f68b4448d0b54f703fdd232796da771b0346ccdd4610021a02532db0261695cc40076d784ba6bdd23c2eb75b25e279b0dfae58021b9e98ffbeffba3dbc9d3f03e791bfebdfab70cc166b36bf6af6dd93eeb9ec2a9da3e0e46e3e490519db4a174cae77130549f9a617dbca178b27da3db61b205da446f299fccd01f8d3e0d8637476e0dfcbe2fea3d6807a025fcc37985e90a028ae8a65b81e80b64a0aade9596fef6bd9e3095b725958252698caf781d7e3aa096422f34c69c9c6b2e1148a2ccfe2ba7ff4ce6e8918d9be476bfdf1ffa4fe3bbc1c31f8d17646df20c8c2fb2d779b3665fa7a845e97c67aa23d3a717e22f503155c86ed5ddc6bb6b2e0dbd143c0984c8780105d52ff9c2f839c219b1063bd71b21ecf6a4dbf9160000fffff8e8761fed050000", "53cc1d15028e0b1431c355d61ba109d4": "1f8b08000000000000ff648ec14ec2401086ef7d8a3ff4a209e9039870a8b2310605d2ad282732b453d8b8ec34bbdb62dfde948428718ef3ff33df97a23c9a808c5d8fc658c699020eecd853e41afb01fbae69c8ca1454d738b267c42363ecf7e40ded2d070cd2c131d748d26b1f5160856a1817e572a2961b8803b5ad351545230e21928f5d8b20e30b7f939dc57f0554e23d57d10e5992a2948bc42fb70b8c85dace36f9ebbb4223fe44717ab1a9c8c152640fcfd11bee476d1360dc3fd2e83ca00bc61d20217be6c8aebf9b2cd476729f256992427dd3a9b5fc90a498e765fe986bb55be75a7fac8af9ecf33a490aadb47e592d775a3d15aabc8ddecaf54eab62a38a3ffb9f000000ffffb53849697f010000", - "5597b95c7800708f526fe349c8315960": "1f8b08000000000000ff5490cf4ec3300c87ef3cc54f968640a2aae04ad20b4fe22d5e172d69a6381b428877476bba35bbe49f3ffbb3639cbf601758d5524edf343c01eddb2e852ebaeefd638e006663b14f192fc7374451e551f4157ec23eb01ef08b4de51a32ea381337bc851e651c2417cc6b774d3f623310720ab2c468cdab82a8635b0c30db73296942f93989a57aa1fb3021a9101c17ee9cd7e8ef520267cf5de0ad044b5f33d796058c9e78aad4c13b2793a592cf42c373f151f4d3f457e0a195beea9b597be72febffe0efd6fb7a5e9065fb0f0000ffff829b6c549e010000", "58087a293b8355d4c89fcbff6f66a041": "1f8b08000000000000ffec595b53e33a127ecfafe8f1c396bd9555186a9ed8e2210c304bd5ec2c0519f6714ad86d47852c792419c249f9bf9f6a4926092717a8b99cb9f01412b7babfbe7ddd320dcf6f7885c07327b4b28381a81b6d1ca483014052d62ea1cf4ab8697bcd725d8f2a7ddd9625977a143f370b34baf10fe773a61b67d9b869d87f7581d29edf545d970cb2c1603482c9545828854410162a5468b8c302aeefe128286270e64097251a0b1caeb915395867dadcb506a1d486b4f0a210aa1a0216c209550157051428317c818657c8e0ac847bdd1aa8090599abb5413a9debba9138036d48001462e19f819b72056e8ad1ac20b11a95e314ae85acd3a4856c83ebdd61debb532da5be23108ad7f42175458aec4217162054efec011df2513a804ba1aa567203691f42ff809d1bdda0e9ba8c648f8f60c2af251ec0b96c0d978f85fd43f10746f10bb4ba35f91af10fbc46d63f8ed2e7dc4d1792a315d18f17efa3d495c03b9860dd48ee903c2ed02c9d72f1895d3d7f4a310a421ede2894c30638fd5f1439ca87e9bf97daf81fd68728a47ae0ee1bdca939d4d47c00102bf84168d07968ef857550a1b3c0a57c64f09dd16dd3752c9673ab7c43f91ae34de34bc4c36cb89b92ae7727135813cf019d84f47617d8cc8349f307a86fb572387319a031da00794156d079abc747906ba530802a8daefdcf7938340070b321e81b3838849c5d71d9629ab85992b1f49f8d6e48793c9b0d004409aff48d370160d0b54641593b764296cb34511a9ce1caf2684db7aa48e86047a4b21ab62b6ede728ba10cba8e00fcc3a7ccb2b5f19d7b1dbe322ba1a8dc0cda563acbe09c1b5e5b48a8d513dfff4983e653f84a9e1a2d8907e898d08a053dc758f2563ab825a72d708341c3e1eb473a0ef7f7123af39930ba19eb019c1a5d07d369cee21f5916515ea033026f7173c12c92717c14628bc69089cf6c2c65ba355ad9bfbdf0ab435042aee6038de9033e1ac1b82862f179ccd4317ab900c06a100e72aee01aa1b5819148a0ef5df23c6797e8d26411c264089ffb38689385ec920b0a611d05b14b678802578bbefff55f5d17d04e8572beadc7add360501568d043b6c84d3e85c637f70336903af7781618fb479f1a83a59825c3c5145af49aafc9f91c5015d1780c5ece2ebcd1747f6f6f0886118e341f6e2fdd2c8b2c7139d577812528800577dc3ba3d5268edac619a4b0a78d4d9c319acf9379d2752b4f7c259e1d77cfa11442fe33520a55b8f44580c01560ddb8fb0db1de4440346a256e23a05ec303034d34944215db864fc89ce1353a34b03e3f946eea38b6d2fd6ec64e852ad6f77f0f76089171d264bdee24db421179886efa66efcd90849618fa77ebe13ea0a18783ff8b9d756cff8fd75efb68041ff02eba13fabbd4a6f68ee606795c3615de6d6af5c5c2bb7543d8d8ea0aef9edecf1f70473bffd299ded5c63ed94b0a29356f2989489709ba6a6cea6a1d0970d7b2471a7d36cfff77f985db5e00b6939cff061a3c220edcae2c066cea6a19fa05c3c5c7ae505ece8e7632de93379e1f734a5d71290a4acf6233e8113d046700708bc6d8e1d228e8cf8d55110b617b941671dd1129510663ec3fdc8ed57d9a4549ba83f29b80d31798057ecb85246a00a1ac287081ba6f5f7f32b67438940c837abf1ac685985a1578c5e382a9f08ead68a12b77c85d6bd1d04eda9fcdb5319887674235ad63abe32cd2c09bfdfde710fecad05b47fadef65949660dfa0b82d27d502c3ae060db3c476ba1466b79859ed84e25b7d33463e3a2489328900c61c2265421d237f312cfad45c7fc4cc182f5e7b3471c18b0d135c560214270f4ca42b2e01a10aac0997f11b2963b5f7fcd29795208f73026797831f230293711eb5fe994543d63386edf834784e2e98c4b2ebc2cc34f9a022f6beb0fb0b63eda643e367ed0e453ae2adcb2cc441adebeccacdc42cf3f7edb5b6840fed27a3f51ebad5f031f2fccdf6dffdbb63fc5eafa65f6271a6a2f0bd4a605aaf5d9fe3e0bd4735f33f897cfd6197d1ffe51b58da5975e126fe4694fd24b5bd2f1c9fb93c9c937a5ea88ff85ab7ffb77862b28fab2f80a54fe25ac5212837c7d4e2982773b59e5e27b33ca9f010000ffffea202445cc1f0000", "593cbb702bb3c5a0fcbfa227df3a58f1": "1f8b08000000000000ff7452cb6edc300cbceb2b089dd6856b033d1ac821011a1468da5ef203b24ddb42255195e83c50ecbf1792656f1a6cf6b2e26866c8a1e5d5f05bcd086a604d2e0aa1ada7c070120072d6bcac7d33906d67ead7695286daa408edd317f92163ff0fe8460c5254423ca900013e6d48f3d5cdda6106558cc8f18e5ee006b273f3139f4f5279df6d57b206d934ad5f7ba307590931ad6e00ed349f2af82b0002dc40f14dd272fce5739e4448bfb6856f8f3f1ec0a8575a1998a04758238e30510065cc761df0cf8a91635764097cc8922ed7692ea30795bc9b85ad91b5b87448290672acb4d36eceae34012f088cd61bc578183feec01dbd74ef831fec92fd525775d1dfee6bcb731d4b7c3bcded381e7d6141e331445830e0116ec3ba7d7ba5de57964dd2761cb9cf3d11470eca27c41e76ab1bc85a749c531aed30be55f768e819941ba1bcaaebefa5b8b5c93aca77ed6d6cee29d8eff8ba7d820b545f67de53d8c8ff413bf99c0ee74a9cc5bf000000ffff6f674a71fa020000", "5a8408312923fc8c5fdddc2e213566cc": "1f8b08000000000000ff010000ffff0000000000000000", "5dd1df1b2c53e1a3425bfe5dc07ff730": "1f8b08000000000000ff8c525d8f123d14beefaf3859decb773a10634cd660823bb81a6521ec977b653aed613832735adb4e7443f8ef663a08a8bb89e102e8739e8f9e3e03b85953000aa0a069eb485988aa4228acdea05f518da0d880c76f2d790cf066bc8760f44a0e5f8a01ac6374e13ccf8dd5419a84496d9b1cb922c6bc0de8ab960c76071935aac23c19259fac6ca936b978b79ccfa0b265bb5aa9dae6fbeff3ed565a1783bc431fc8f26e072a40a2a01762797b05cdc69087ccc17f97f3c5e4e67d1ebcce7fd126cec985d21b55e16253ed76e27ebefc587c58fedbb0d86e690547f09ee2fa1e4ba7f406b2dd4e0c2076abfb4e750d5ae935425c23b06b80384455d71022baffa1e51a4300d76bcbafc132e8b5e20a839814c5ef807ccaf541794e96ddf8a3f22c6bab3720d306baff07c72c639b396f2b8f2188ed16eb8089d94d9e46fb6b904d9a3bfe4a66f2e94005ba83aa4107c8a1f578eaf70469664d5b6348f0f4ea0e2ee7a3d168362f6e3f4dafc7964fac3bd9ca428511642ea5fc03dab7a32f02645d632369c82ce42571ae9c137da154ed88317194db8032a6bf77ff5aa50aebe730ad328d3ed28ab48a18c4a139c941888bf9e201b26ce56d33def7f1600e528801dcb2b64d831c215af02da77294c4ca3f02319c396f4dab23593e83c61a3c1703e8b7f2657a75373ec29dd85b6293043af9686128d30782058aa0154389101019ba4460db18c8f47dd496a322469f763e298ae578cf1662fa7931bf9ec28be170f86ce4862aafba1c014a5c598f1dc2c4d5c985baec17b3e2b8819e84af8f0fd2c1f803f5f1e467000000ffffb0f46bad7a040000", "6046dc01b561b25c62c4c0d22e8131a1": "1f8b08000000000000ffecbd6d8f1cc7912efa79f82beace7e590399c98cc8c837c3f48145c9f6023cf72cb05e5ddc4f06b74489bcdb228921454bfaf517f14454750f3994a8e1c86c9f630356176bbaba3223232322e3e589dffd8fefbf3d2c6f9e5cbd7af6e2f9834b4af97279f27c7df1d5b3e7df3cb8fceef5d7715cfe8fdfdffbddff15e3f2a727cf9f5c3d7efde2eab7cb1fbe7af15f4f967f3b1cbe7bf51ab716a694530ecb7f7cf9a7e58bef5fbeb87abdfcfbe1bb6fe2bf3d5f126e7e69eff8edd252cecb67df3d3b7cb5e4df2c4b8cfaf39fffaf877ff97ffffd8be5d59b6f967fffcfcf1efddbc3e532debfffff9487f7ef7ffe97cff10b94e8fefd2ffeefcbe5f2e9ebd72f7f7bfffedffef6b7f4b7925e5c7d73ff4f578f5f3e7db6bebaff1f5ffee9be7ef1f3bf7c7effd59b6f88d257afbfbafcfdbddfe92f9fcc932e97675f3db8fcecbbafbf7e7c78f1d7efeb1ffffaa7172f9f3eb9ba5cbefff6f0fcd5831b5ec23967fd51ffca6fbf3f3c7bfedf377d91e69cf7f1d7cbe5fb0797f9e5f797f72e961fec6a79f3ecc9df3e7ba1f797bccc8cff2bd51fffd7e149fcafc7eb7f7f73f5e2bbe75f3db87cfee46fcbb5ef7cffede1b7af5e3e5e9f3cb87c79f5e4d593ab374f746adffcfedec5ef5e3e7efd74f9fad9e1f0e0f2f98be74f2e9757afaf5efcf7930797ffc24493ea7623feedd957af9f3eb8a4b6df393c7bfe647dfcf2c125de7bedf6fff7e2d9f3b7ef7ffbecf593abc3b36f9fbd7e7049f972f9eac1e5bd8b8bff496d240934c6da66ec1ca8d53423514f25702fa9d8f5c3562971e839f53098024b4e822b9199c643bd6a75a612ec8b836710217c7bdebbb878c88553c1edc6a9e2bb6c97f88143cc89435e634e142951d04fd65bb1245e23a51eb9a7164b92586be25813c5c169e8233d12a516f5ff5cf020c522a9dfbbb8d03f732ca9c59c5aec8963d639e5d4d7ac132da904e23422e9a4f4e525d535871c721c3d75ff7895f52b55bfc291ea23e2ae447b3a93e8d06be49c585fa7cfd95b7aec69c6a62f0a19ffae4ae9d4624b823770121db37e869a26ee29f138b550f4bf071d3b4dffba4d44ffdcf5d3df1674c2ba2c2591fec9be1ab827b18fb6e2517c4fdfa66bcaab5243a92c51dfae33c0bcf19d8155183eda9186be8a31291dacbe4a473182a4b1e654424915eb37a20e9d729a4a76fb59c12b9b7ff2460c257adf2f9ee654fe0c56fcf1f2beee0be5e2c7577fba7afcd5b327cf5f63d3ffc7977ffab7cfff4a7fbd5cbef1dbfff9fcd9eb570f2ebf7bf5e4ea3f747ffdafe7fff9eac9e5f23d3db89429a9895c2e3fd083cb2a39b5dacae5f23d9ffe891f5cf69c6aa172f9fb7b1717bf7bf5fac5cb6579f1f5d7af9ebc7e709975ebfc7078f2e052efc7f5c5e1c5d56fffe573ea0f6bc320df7920491ef3e6a7f2c8f5b31b9fa21b1ff88cbf685ffcc16871ff3a31de121bdf5d1dfef55f36dafc06fb1a9bba041a1d9b9ad208d45a246a49b0a9c5ae8f9bbaee9bba1c37f59a95dd4bd48d2b2391f272e804ce3b44aa9466e8caff4df98138954734f426979cf8d13e085fd2972f0e3f7cf3e2b90ffb5ffef0c74ea55c2e2f5f3c7baeabd89ba8f490b934a92a1b724fb2d4ae7c53674fbcd43e12872a6369ac5ba99691ead2cad8af479e7e3db66ba154977b171723d7d443ad2df5a5cf9128d43ef57a8cd0724bbc74fd77689c535d7ae734432b92da72f141c36fa0928c5416154fa1144e75a9a2bb8570b7250a85ca5287ee84ac2f6fa2f7b24eaeebf04aae49963e702969e8c0bb4e8f5b4bb4d825eb4cbb8a4fa6aa93d63dc779a4b90c7d92b3a4b2cc1138531a0b652c49563a509e69069a4a5993607db125a3d1535d3863fff696445fcdd49575babe8565e8d77a496de1aa0ba1d7b4701bf8ced0eb5ef15365e101969839c9c243e9c1194f4e888bacb4e1a1220a9cb6f0245dac4636679e3d51682a6c17ee84eba9636e59af2be6c2e012a5e6a22a8a4313251265d1a5c3b313927576ac689aa1d6ae64645dfd5297a6e4aa042eaaa9059923b1bebf15d54bbd276535957375a6fa1e46e89f95cf59aef3f1084df0ab52f43aeb00949347a853c7c853c06a92faf5794063b6417abfe277664fdb1a756e200ef754436f9cfac24d257a1f25d5a55053119cf58152671a61704eb494a1ea58794254d486c13dcd45ca4ca4fa78912a50e57391a15c3fb8a5b12859200b74e349d1fb5413e900aa3263185997bc4edd897d369d2d29b9fbc0cc791b9872b9da05bd299bb7a65baf5749b4b4a933ec8595fd5507874e75e945d43e98398da5575299a02cb653ff28f9f63da8224fb7ce0cad97340fb1aa2ea4340e9cf186540fac6bdd0ea21f94cad3515239508dc574684b3dce5443e976a11a8f420e8d5458ea1cf7ab436f6a38ccc46f22cd43644923724be51065268e2dcd4727a3f9f1dd717ff6707ed11edab86b515ee342fa3ca9de95549e4612fd37d7d4637baab64c3bc4a202ad3d8d95f45f0c8191caaaef1e816a1a5174ab488b552da75e4c7147ddb80c5b43d7416a64e5a636cdae2a814ce3b34afb1194054a4f7c502b2a70a203bea41357f9cf9cc6a1c008a8a91d5ab7ab7aa8d574793d88287d929a7d072e6a9c49ea87d6d47ca1540f45ad0e4c905a2a5138f53791f8906145c83ad56aa846893860a2084cbca1d69e32995a7945a7d1a2c0b6503ad59ee6bbb46e7ff8bc7f518dd63c27e803aad14c2336d588983fc94c2d0c5d40bd948374d842f254482d3cb595cada7b12908af20ca3e0fb41bfaf8ba7dc3f92403b327e78ea42917d3fc953651f02c3347d693f28152434dc1cca067aafe8dcb2b2310fd8a5a93d526dc24166769e509bf0d1c9746e60b23fb6cff90f6c1317557041ca487d153556cd4a93585355ce51d394d68a498afe45774fd3bfa89d27abf285ee24e51ffd2495079c9ab21726a37f0b2a774999465f53549eeaafdb5c2516650f49758d2a9a945b6960044de75974282bb6206c509512532d793d87502a7a8428b34316ebe82567e85b7dddc9ec6ea203fee7741013ec92ca2a30be39546cd9118a32ad1e0b708ca87124561358cf033acab92a3b068e2aa71acce68989e9c8a4e43483f4aae3534b04d72d9cbcefe74646b01f549cafaa03d4245312e650c10d6dc5512cb1ae41d4f7e0c453d25c752f32560c6b596d852af6dfaae7a58089e8c6f6e38eb27fb53d8a93911e27aa4e7eac19363e36a8b1bc9ebc6ce84f0e87672f5f3d595e5f3d7efeeaeb1757df3eb8fcf6f1ebab67dfff6b4ec463519e9d3496fd436f4a4d35cb5846a9494aa1df5cbe3dfbf57b35c97b1a97cbfac383cb32492faf70f772b9fa019f3a00359d6f3586d839e5cc63e95992cc516e1e446992da368892f86e07d1d31cc5ecd95e3bbf6708256f74603ddbda105477db2070f50e1f756eb38e4dc489eed9ae7c14ab2d9f8a90ae4bdf54deb06e2e3000c5b9f1f84c12672c387f632bda2e54e1deedefd088d891ca416ab7eaaf06ce2627c63aa1246660bdad3bbf98ecb093abddcafb9951796be23e43a628b7d36aa2555f82932743ca90f3b1deebd10e93aad22ab481ee423bbceae932aac4aafa3b105838ef12045ec16070e0c4b91ffb60469c63ed67e034504182c3ea0ccdd527e11cdca31d73f5a45ed748f6749250ec341eaa523c43e2956813ab7a96d6a71ef26c81bb8a2c9e1557339c2cd5cfd8085c7194a1b1aa71112452379f05e368a7477c8874d61556f2135c225827b50fd49e523b081aa60635d887096fc29fa632432052598367d7ea16012437848b1a48b20e9fac1e9294bd42818722bbab420eee6c394415e9c36d9aa29c34d4a0e82a3eff8cf9fc7879efe2e2ed697f900f4ceed805564829d39aa89057abb729e734651de535d8905cb0a1365b6906eea60729f0486d9d60385ddad8942caad628a7baaa0a87e280882d38039aeebbc158b9b6e86aa106ae53175d42562d39c388259b229dbe27d80cb70e3d1e8a1de0121f8619a9f5d1fe433f7e900483cc8a26b4b6ffda3d1d38892c3da74679de2cc260cf7e9408738b9839d10adb0976287c62902aba99d706cf12991684b5c0f068a950e81015caef4aa8000b621abf43bb11dc52fa408f33a8d0834501c3bf2bf128520d3460a0817b0b2e093f0f438f60aa1fa03d39f5472763feb9556da14ad3d5c38c942174797bb65d4581724eb482f758d7146ec91a601f16350470b2527e13d8fdca753d1b29860b6963453267224cd4a47bb7d89e6e7086ce6096649295cdb690a087d6088710a920192b8c9f66f4afba8b0503512634f9a1d28fa71d305a6c50084a1c50c74e280433174ec30328cc6adbc23eee4a5736ff044ce50981aa4f408ce93d1c76533db841d60f3066ccce7e245542cb662aeb146c7554d1c841d9a2c6a9bf36201cf56755b4f32196a1a3c4407403412f1e224c42d8e513ebaa7bc797eb67247483d30167e615225a79ce5c9b6113d2b2ba8c0e9b8cd645d6adccab8be868225aa289e8eafa07323a988c8ebb8c8e2ea4e326a4a30969d5a32ea7e326a7e3514ec35bdd533b0c18bea4a7bad8931c7485479a8792f425ca4a8f4ea6f5cefc3f89a8aee07913d52ea9c32ea9c351529ba00e9ba08e47411d5d524793d4f128a9a38beab88beaf881a2ba9a376e4c089f8915c3efaaf15dd8fc066d85675db5ad0711b08b225570bb4ee1d1c90fddc070324be3133b4f25800a499ba19a20f8193d43c1972a7c88ddce34b0fb5453d83952cd311c17da8a63605122aa39d6cca0ab387041fae26cc415b6d108a586ac473bd58419fc22cadf7a402a6a01821795e445c9c6784b24ddc5c6b370fa9b2c87042f70f9c2098017ea8e257821f4740e55574aace27c1bca5a084195aa3fa007b081788aca41e5e982bd6fa456918425ac01dbbd92f977e4a09235bb5da9328ab15daa0a4018434a41610bc860157b80bc28aa52d6683e80a20489b6793ca0644e146c3d4214041ef34d2ee377328e5c6ab38a79323c5682af91ee4b446eb0954311634bc6299986bb9ab0626a466f3195d861663668a67d66165d9a6e89a9ecf4331e8c6509d95c007d972766a1739c300895732265b89758d92bd666ee88199b0a7bc92038c7fd8530f4a34c7d56854e85656e14af38c4ea8aeb54a3e4487a8a8820acaeddaa36baeaae6a4a78eaa8d46e81187cc8bde3c00f653470b88673fd6423dcb065da1795b62d23f05af1187031cde81ab75b540bcebf5457e85378323a2219b0f27425e000d063b7ae8d4af7083f2c4d0f33aa98d0430ee68fc3471de6a90169a7528e7028283950d1159c0fc56e22d028d8173a3e0a2763bdd1e95c3fab9fd53f1e9dce0ca7692d736151215095ce0b4b4d23d49a93de1f887e0cbb6a053efd0eaf7bd7ef16c1f5d0ef16d6e770ffdec505179563b50e7d047ed45a259585558e855a8b3ec22db9aa7c8f9ffced213786cb5ff4698fe7484e7d69b0736bd181347bb3706a4b1335722ac205ad4c7d5b2da92c4d256da8d59dd34d8fd01ee7d16bc65c6569100436277d5d0bb5cdc44bc34ef3fba4df10b8b22b8205157fd7c9e7f74c6bd303dbb44a472862e8fb4b535e6eb32e4594bbbbf9e6b9208e56970269d94957a540d57635e2179e3abd4e88afcc167aaebe1216379833c9c2b3223ea05f41b464e89a94dc4243c0a650c3a9a6a6b614d0baf5acf74bc635be236d8f3758c8a08d9aca4dbef66bfaeed7d3c2eeb07eaf223ea876a5035c877aced4c36f6c7a41309be8d1c9e06e0e3cbecd8816ced015e345d75c0982d0a3e84e6c5389560b488c604cc5d1afe796ca52595747f9484f00baaa8c27e1385139817889f266e8d497da085715f1c0866b4a6d5156ec58665c8786409432a54542e803f7d4754e5065a253290b2290a14d4eb49462315f7d6f4110482750970297b532ddbcc698f72e2edecf9b826113227bba55dbd4a9f16cd803a7619b9f09feb2ee8fd6556a2965058c5b1765c7e3753686d74d3f95d394f93f2c28d77044ac3c122dadb16a7a8f0a9e5c5b3c728e6580512b22c10381297db25c0b2f7770815e37133be47f7a5fc0f88f7ffcbcfde1445034c1ea668b556378ca70cbc826701021ab704411ddb8277fda02ff7883fb7f76e4e7d43adfc476cc6e611c1f29321c60e4091df0347a3e096d4e3fd86cf085f91d813080f3ef90f73c98cddd4cf815f23c180fb4d8335bb24b868980ffc23a235868fe9a68593d96e2939116334256dbc5fcda3eece1c39cab3dc3e631779f24d9c9d662201ccca46b9e6103171fc14a820711ffcd9eba93032c3cfdef2758ab8ab029b77faed5d9af55eb0db6889cae5580211d1807355f1578ef33bca6dbdacd6861d219b6542a318736d609546b27f96204cab66da994cad1a83e7e72a9a279b16bb4b5b5b38daf55f15f29c7d502ab0dbc89fd40e30f4cf8f3695baa785cab6abe10a48f350f09280f29cf114ea367b05475ea61a9cefccfa5fa5597cafd457cd7d9ad057ec6d1cded4596d596f73c50cbd02c27199ac53334cb498666fd800ccd7d793c42522c59d333347799f493199a6c39ac01a19d3d43933d4393dfcad064cfd0947733349b6768f60fccd0849b169fbca7ab22c23cf78b1bb26f1e7efe793e5a0abb9de08a475c82b7931dc1ae78ea89e219ae11c6cd8ac736c991ba6cdae744f7b0eb1e3e61c37715cfb4d8dca9da09bbda014ddf553c3a4cdb77bbee99a7ba67533c2e0dccabfe96e269c1b26e6fd8227fee8d6ff0595ca36b955da7ff93ae1f4cd72a3f43d7d6dbae7f7da36f6f3b358ac8a5fa29ad874bf5f193527d27ac8bf5b98b75b2f57a3f51fd89ea9fd7e439ed5ae15d79be53f51d91be9135be6528057a4b9e77c8f37e23515bbf294c7d4ad43acbae29ff49d40f226a9d3725069d12f557d760f72e2ede2e33f85535981bec3729b15f5783ddbbb878b453f3180bbf7afcd5b3c7871b2a0df8af16d1eea5a7d6a758505b724b34695c2e570f2ea5a632271f2b12fe725340bdf445974a262ffb076e4e4a75f4b2f0e0346b97dffc5c69c30757293c943ef83d550a37d71bd45a48de53d630f2e49b5f33c71f8b47bcef5f27e4fbab1478ab52e8390761c42b113cc602b23bfcf4c09a13af14b95a244704b97489a394242bd74001f71849802509feba6dd640cdc2b908c155fd99325379b4bff56732f27aae81e1f7cfa608c16d26baea6a5a49903da89f5d15db2a76c60d081d58fa0c83812d5083642a4826fd3f79811276644f25224d8103c9da548906825354efc01189b7b225a758ee21458498914b808371b4644cb6b8931296d8cf012c183147c4cdb2056cece4c0b10acc8a16518590b7dfd3f5a878ba2153802c6b4c3795253a53ec88a2af6c31654b8fd1c32d59bd485df5cbd411958c24dbe7bd8b8b877a0a9e817922fdc1897dbc7ab45ffdcc429561abdd53f5fc2e4b6043224ebec52c3d2e7827135d955f91f05b908d37b7cf37f926be3233fe4e58eb26beea1ec6d5a9985c6c10f4f2d314ae73aa002e9ccaca16e42d816a4431093e9eda6caca0ccbd344ad295dc2434361497e2165dc6c1912ccd35759daf92014c8e502d84fa083ac1cda2e86a35789450b78365a935b304c2c08b78c541d5680865d17c4d2de550229b8e0b08865ab2a34eca2c0e2c6a923536a8164b7554d3d57209df3dd85e23556b3a74290539855e7ba84b6b99ce88816e37a6b9d24ce0916527ca6e0e6d264bd9861ecdf556118b55535a4cc1daa4dd46c6817ff5c37db0f424da3e57b2fc1095254e187c1e72c8fb31c053ddb7a82e0e1196ace9fe3dd5ebdd6d1b4bdd44828bdf85dc31ab0703eb6f5982f3661a9ee636d48c7c9d5a61901c39c84e3492d808857c66ec938e9d3c525d2baca116105a27d702b09a8ae7aac769bb17c95c2e45b99941382dbadd635191b1a50f9415894158ad1ec93734ebf3d59faa6aee288b23a5aa0c4bcd2c5e37e0312d952f88de531ca9458461f2ba25ed547d0c59a47ad19046bb5ab688e5204e0804b68cfd15a5046aa5423fe8d8a0058ba5caaf88ed8f005eee961b4601d314cbcff7f423361980307641da2c923455b82131dfd20656378e0526a8399b24f1216fb906c5f4924a12fbcd692f1e2b922af41f1c3ce36b062be3d0c9588e020cf8026121a17b165c433225e40caa35500a4c4865a8f8249f2a92232d7f05f5299e7bc16b337bd3f2dd2c97a058e29eca126327b20c57af8229ab551b50e06a89139ecae2f93096ee5b603f4306e6807163f96deaa2bc8269aa41fbb0669450a01252af4b60140a9eb0f887c5c7c60835e76b512abfea057791758638591f308550b2b65dd3f11a8592fa7dbdf6e248ff27b37fad0751822e7d203c465612296f5f733d86d04a3e5ed7a6d7a8ad915a126dd782fb153c2162f17aff67c64fa1e44d32a3f40b994a39275eba28d79789b85ba9ca68134335ebceaeb3d2b50cd4ec75e4110e14a5f576bc6ed063282dbb7771d15ac5e3082e361b0642fe56cba92cb3a83cd7998ee3f53b81c39be37d22c2c2c72594822c71e24590f55949872d1637a49a44af916bc7b83b425519b08825632018a94fcefd3bf04ceb46d1c96cff2ca9ec5fe30f1e9a9a34faacfeecc0754de43582953a0687b40ccea9e19a4265c6f79be5a6a3a6b0fbf77d48482fa1869fd2ad55493e30922d48c7aa9cf1828a97e9af28252aa832432d4613bd325a5a2570c1df319422692c621922c533449c3a459cb81d8f545cb3fe14ae74ae0df3c6b7d9be514181899f2c3b352a663df17bdb0215fcca4625bc1606890ae145d802c9a47362e4b2948291aa98d291caf6b8ce7efbd9d2f09d8661dab5cdb86121505785598a64a403a18a57ffd16d5e765b5f88af0b8829f8c98919946bebf9a14b555046cba08b71a15c634f2928e2a689253c5dd89b38e7946d9c8bd899f33dc17e4f1e3fe51d5b1cc1ab09cb872179201f5765db514692be0d93e7c6313c4063702eea8f311c23797686a3fd27b187b81e69a816c136e4f5d9d57a78f2f60644ed9312c47c0bb530dc0a25b13d75f5647dbde03b7cb9e00bedf238eb4ebd5d2e1e391997cbd327cfbe798af8c70df6fcf64acb84aba10a3ff5e2d7edbca4f64cdefdb1279fabf9596036ab6de8ee2e31e310f6623ff96c7eaaddad4471df103db437abe9e163d83e7f7c7bc2dd26ac437e6b063ee1729cb0bce7e19a6ff3b0935ada473c5ce563863d3ee2e1f631c36eb7a2b63fdc6f456d1f76ff18828d8f1af6ada8ed0f8f5b51db873d3f8660f363863d6f456d7bb8e58fd8922d7f04c11a7dccb0e9238441a38fd8928d3f8660e56386cd1f210c5af905d47e27ce8f737c538b84695865a79518593400de8158de5b5682c8c7d4c362af3880c259e4304e285b573df5530f0fb8155b5e2dbec3eed380c3e2ad675fbc7cbc3e7bfdc3834bbd6d5e9c593c1d71ac5b6c125568a1a04ed5ab483d9062c1154e03e594e6abb0ac72c111dfa6dddcf9a1bf30f509af0998f876572bc4ca3767e856c180a7a29533557c130e2bc645858f9791ae8f842a87ce7202b3875bca0a002df8e39a8786dc19623f5ef012d40f468be09a726f1eb34185b847769ba172052073ad79cba10768842060531eb6a9c441aa31723567681d6eeb2349dff5e77e506e48b9ebdc1064ccb1f09b2a16fa42a15fb47a3f54c779a4adc46265129ce84ba16325b8bef1934ce17b7a70d947aa866f258d0cdaca6fb11a11f53c464983b76116553b3acced1e230bf63c32855a1d762e49f52745c39691e1314fb8513dc3329c246478c4b76ff782d56452dc9231aa0790e1b83d642b03ddd2362da4bce5436c09195b4019b167b7dc11e68e0873fb53e22e59099e92114cea59e6a45bef1e9e6e70cd8e4d3a995430d39f3ccb1359161eb0453c225a8cb7444fc8409a88951fe2bfc7b19987b25e2b89bd41d676f8451a006f548076a72b3cf851875bf79c00cf5b85973f6f7e69681389b4c5a5375c398bf6185819aa14b628790b0e74b2ff8afdaa67b180d8f0df013963eea4adbe2015de6e0ec763914532688f3e1e535dd98f466535f28be3030c1fb3de2feeeaa7688a6300d7c333139cb696db83300106886a2dfcf727a95b274a6026997bb782e308e118b270cceadab1c68d04804cd86641ae3465539e2733ac4eb96adc6d3439090121e0b87a30c1ffbde50c1182fa793f3a921f344b38fef6ceb247c6a42d07c3a321b491c9c2255bd064bac6c271d455a967403bf52d7b64383a84f87df1dc941a8f01b9874a43e48002896ebbb6ff3a6d7ffc6999d1e0caa933f1c143167cc2e4cd55fa3861737656e9276cde9c65aea76c1b3b1567731477faefd49db1f73d79fc3790968cd53d9089cf768dd9c7c6f46fc991beb1fd293318bb070bf3bccdeed5b7e3588f49a99bbc18b1bccdec5ecfec392c668594edf38810794d61a8b619e2baa6b2abc4a1e77868447e8f1c2abb99eb59137bcc53f581ac967e860043377c13440d2682052d8d5003a11c5680b2b55afe0c0255d103b3b1986c773016f2a273849450728f0014024878580d322b156e660a1603392d0815954812694b3cead898e201b67a2d96fbb3b3449d5a6035d4578b095bccb4a2e095535bb71f1e006a21035269ab6ffb025955ac8ed2726cd6e28ce7a62de23e865304e9a34304338fe031cf6196af8130b0c5e5d82c5d64434741d8ba02a7a8acbb755b215e4bd4a1752f79c53e89cdb813da915644042165d9c36908ceab3488823fe09c62c5ad5d976035394c41409369203886f5d40632badb447555d12701de7042caf748839b97a00bea9d2bc25cc5923b62b71097efb415822a14577628904d7db5f02b329e8201bb2add0cba4ed7ca8f25c52cf3dd1810a46c6fd85c92eabac5cf05a803d3b49ca34491e1c61a400e2020c009168084f02a961e263558a89a8ae7a317147ba30018cfad11201091bba52e4412032bb18497b6010b89e14d30b8863675c226b43a629c5be091c4bd910c6d1dc480ff44f726f605c996ff0641bf5657cb645f2cc04a81295310bb230b2b237fcd227f641b93900562c1dbb187e5c54bc1c5f58fe530d1c35eb13056ee270824d61e4e96fa97b1086a57591af497a7f1fada12407595c563d73dd800eb34232298dd76d1f032766c2b2be8b7d147ab399f911dd4c450a32c47171926c5405518675272e8b18a743dc490c11a6db5a0710f16096d61c62d59062ad2d45ce847cad9e112722b9871d6a001d9f54875f56d8fd4552c75c3e04e106b4501602a0f3b23942abaf77b81252ba267ff23d17e11b19be5c4b08b0120b08d606926dd4fff96f260d9082530a0a8c8ad6ed9c4a8a53a98e93282e1534f24c014307931680f334caaa76fc14c729f03721e0305377775f9105d66a4792a19a609b011871f0c802c52b6640731c9ad6b13c84a400c2c5a0f1b961e0be1ee542760e018d529d2bae5ec54186a0dcab979ce890954cbe6a951764b004695b29319b130ca2defc67d0d03b3cfe6d311cfb0edf8ae0abf6a9901c80e30540b53786be4702c5cb38236da2aef8d73233240516a2fa64e2d47d8b2e8807112b29925ae3625f8c47f097f948ab27fdd142e6500e3a2ec482a3ecb8ae81372216670109fba56cf10a66630dd8190a3412e465aa8b6e5b09f238aced5d23bcd6cedd8d11ca6eed16699bd6c0e18834082355fede069ba2c3b6acf495a9b95fe109945d16c15574ffba890600c241aa59c1ca96bfc69291b3a77c79768c09a01e761b31bba844a158c07c972dda5256f1920dc2c838242a98e610588126c2b1ed841c584790654a31f7d375f1cf084f09768893102a9667076d34090a6ed11867466202de9e4d6b6953aa4061044b687b77c2d8928a28a767631a445f0a831638bae11d873562be0408094d2772bc4322da160b7446dd722782147cb4dd13366736c7b689f0adc0d03026a2b2ae3abe14f217f2bb29da1c666736fc7cfed735cc754fb7959570780273cff49e2564ee6ca4005d31ac9b724769c4145c2be9f5e19e65526e6ec3079c72eef0cb30f7688e7f58923520a3c232e01d90d1f896650f21a69ab1e81cc401dca06eb2791bcb8c49c2f1b4cd2d8ab5eec3ef291762ba9b8be81de59f5a02a38ab00ed723d06299ba31512f491493a1841f8bb183a260cc1860c15604cb4069b8a517e7f24ea2d3d9d77eddbe2897492464853252f06da2ca07a5b70a7bb1fa65ad3b50386c5cf999674b969c3726b9fe69d8d554f993c879f325bb353a6dd618b829e05316bb735379f876915007fb86135cf8598a0218859a711d3eeb0c5a3cf83980d293e9d37d16bc52b65af8b399b3d54e187685312add610449019ce663bab603b13877b25835439f135d613f712fe7f262385cba74d2bbf6dee5fb781f2f90cb354023e4a36a768738886091f49b1a8e4b98cb463a4303c77605f83888c94771efde4b2a94836d9d4a60bfa22ec81abd9ce0312b16471dc1e2b8850731b18cf4089ed916fa990ee1cba11f85236ceed3c86d306a1b4a62363fe3cf853c6087554c39fb5e24ea0c2b2b97f917bde572a8e8a4f1dec6b4eab787bb0cc3bdf6632520db51ba6bc01881a9a2a908b01ab7a1e23ad79a2594c5b6345798c75e43297f730a4ef6ad8e3704bc13d4ee6e53d1313a1d4e253c0f8dddb85536e77cf4bb7a2019a96e731d05de97ca4b2107cc203b1392f2bea51cd07547bb8b3c3dc606225b87005ae7db3d33b8ed42db0956e9dc9cac8a87009b6b5794f39da40eeb173adc078c3592927500ad5a0a4c384eb03809400d11de731b182b208a6e926fe0080e606c5d7ad1d0bced806421aa695fca0a0d4dabe9cc7442413da5a11f06103e5c0c38a5e457054e1550ca574070297c06878733e9ba704d601aed5db0d585719ec28fd3893610e00abf66a81816e38b6c1ea027b7097b449d8e6413684a3cf64f802dd55ab753ce8ee3eaea1e0bf67c30d65e4405d5071392ccce4d9141641ad5ee68a6a0f2febc5bfce63f86a3208a257b26e5c6c6e750ee6a0bca5ed7bf703059e7cb54a634378630418f87c4443ed56512830c3c8e30edd50c2e1473e13e150e17037416ce7dcadc4b78433b2b4ea003d293b35eb09e6dff889b4e0bff3301925995ccd9b8976598816aad5dac399685e1e680ea707058f2c0f3bee2095e75c283911f5accd738ab6e4cae2b18733d93e6ced39ad97c006c8615d72d97bf09cc9488ba573f03c71b41707fa3b12f4d37b5f98cdfbc23cdcfbc2deb657ef9cc718c9bdd75cbcbd70a1ee632c3f55dd50ad599c4cef368dd424f893cfc5086833719026c9fb699982453282f7b53a132ba0a1fbabd49e8a9db2c7067f01ac002be53c17b5a0eb2e0186ec6a9156a40a20b14310517e176af113a959b1324d649a0dc311410b040beb9f892cab1dbd13304c4b891deef81e1e7b3e177aa297010b599e2f1c0b563f546e8444f94483b4766266026ea905b215f69ecf49b01658fed2d056c9b29aab53b3eb71e53c8659d81a78795fd1ee0950d54edcba93ce659cc69c96e56760421b969fc4b361cf82c41fb5a98be7916fdd1c2d13fa6cd853182825c2a9ae561f52bd118632e799a408189441114ad3f35cd8f25c8261c5b5f330b1ac20556dade24138299e20a077ce8294dc9be70201a1d98a42d146a8c0f03f139b8e07524fc5f2388b953219b696f5fd3e1779c403febc821295bd90a4fad9f44ca2c3dc37dbbf796123f7cdf66f7226631cf9ed310e3ab731f6b18d716e63ccdb18cfc57a33a7531335dbadc66903b43b1f4959fb7442f6eca954fb627b5edaa71fe3d8177b6c639cdb629f8957ac6571c8a9b26e5949e4e988c0873b97610e87706a3ecc7a8aa21ece269f42e969c05da79041732b0f3c9f14aa86b499daac4ef1b8f0c5eb20cfc431d6b86cf9a76c7ba8713db394c956ac5d5f8571c97bab77b811c2993026a3ab327a0a9e380fac6d7c897c1eabcd65cf36aeae1e256fab7d2ef69a20c1a85507677564f6b2378738939dc365beb57358e8cc764e6146cf3b83199fc1fadc3a887da019e84c768f77926c76e8a9ae20556272a0f358efb2ed9db6ed9db2ad773b97bd23841e8743c93880a0c0e4f03b3cc299d81a95045d430b6a3107d61a30c7bade259e89bb0dc899d62e72dd6036d80120249ec9fe06ae282a860c34deaa3336bcf2e3c6b90619f9ab363afb3918cabf67c3b51d1ff4d86dad58b9b8d552d20d60f59f6050d10635a30fea97ca923b19145a2ed3d87aaaf0eeaa27ef91c8b06b643f15b06774006cdbbd3e8c8c0442f700de30628095e2adcc67f01613860bef85acb1591dde49dd6f75e81aab09ae0efd72f47a5b9f976a45ecd1c7147d4c8655660d7a82a769a254fa972abb3ba1ac4335ef50a6a8cc169423ce4fd186504abf369e20c1fb127caaf138c2f4de973092437e58eaf32759b57e6d44c147144f47f48b2c923b715e5372f7753dbaaf737297472bf336a6f19d0c6c1e075653df863693bc3db44fae31a54f43ad460ebad9c23d0db472e0a9e735ebfa015c9d1e0093c364187e825afa950db8c3212bc0a7c31056cec498e60ecca05150a26e260b0d203d601e2d967558ae801570c0c35303104ac49070806a12d10f4225bba5af8b7d59bc7adece102648a878d57311c77204d636b573f1c7f0a870c4e91c7b6a685c81d311da5e9466384c30a7546d6d39fa8131db33890d9509379d65faa462c84ad626a37afb8dd5baf264acef006044303c847a3e7b1098e682be3bd635039c350dad021050a897aa08794d6bbd32ad668a93ac15e042649e496b948b6d7c26f363a9413a5b7f1e548758b5116afc0d95aa58ce79031a1059b4b4443a9f446361ef2a50572207712b193d5328941cf996c7b4bb465eb56dcdb9be01c448368812ee91d190c83e0fb122869ee810d9a17fca9f89fb2132e4b7a08601686368c883cd72bc7a95038a1decc320222cd659f52933621956d48664198afb7c3d1b1f254e06f763fe74b1f632f0610af2a23aba1f422ad78af4780a83cd2c3ea2788a7749aeb7757cdef90a14ccaacb9b421b90a9b5130a15a07b86f903542dfbf8b2ccdba75cfe5a88b234fa3b88b2a59c0997df01bef0cb17871f3e19adb7761af72e2e2823a121d3e257bd2d13a86683d35c28034f043d312ece8349fe41c091e139b061663f1d6cf7d41ae7db6374dce938598d170fdbd21e8498fb9693db874afecf049b268bdc8e4407116b06d7dec4d1121f8a1a466fe254e910bb956e4e0376dbaf0e6c8d3ee50020c7a72ca91c28a3472819ae2e7963c4fde24d19c0a73a10f059dfb4d40faab8ca9bc8edc0b17e29949ff6240742ca523f14b54fdfcc432ca1bf613a48e86f0aebdb91d498d3fc73ab1f27acee8cb027c2aa3564d6e79e68697d0621ef0916a4eefd783e3907209fa48c96da215b3dbe41fd4eaf139c9645864e75584fc322d48f37b7f219fc1ae1954eb4ed360fa7d91d955df54cf65ae71284da1b16afb468def00f107b1bc470f14e9a05487ce54b9972768cdda58532c7a29fd6baaf0b8aa48be0baebb55aa1274af86cc6de5109555b92a5f71ea4b17d8ef21126c3dd32f3064425c3b3a7fa064475ca0d9f768cb5fb18ab971bd99db31aa3f04647cff0ea1b688ecc33c9946b3d6fd6a19f20ecce598d71ba7015d9b27c269dd918770520a3bcad00ce658cad79b6944c5febdecb36c63351520d27ed5a86376f46adcdb0061dfe797687c25a4b12a05dcad2d07db535514b8b3b7aff64bfea797ea442fa3546cf1dd8fc32132d5c9167d36baa4bc93d35243adcda56bc73674db5d6493555745acea102551ba8c1db95da3772883c1162fd38e3e5d7a077c925f4aa868a08fa3ce3ba010bfe3c39a4cc9a4ae8d4535f8a489aa17349732979831aa7331c75958291ce3416c1a1a197bc94397527524b63399dd799786b303c13d218a3a76acd9c5c99f473f1d880a43ed2e266a2de9377c7791b8eb833d0bd53d35ba572683274bf09a51e5a563ea81d59d9b35de3e34f366203d6edc90d8ac692dcec21ae69435dace3b661bdbb96ca3d238851c41b44b177e411ef745357832591501df4a5eb09dec1cc9bf592d960d0258d55104740bf189cfe11e2f07654dd609aa67e5faceb3d9c027543d91ec0f4afabe5f3a089087e3902046c1e0129cc71c480db44fb243298ff12591cb71cdda0f30a40460332b756022d7680cb3bc8395afd00b45c9f6e28bf24c3e923f45e61c03b02cccf7a41a866a5bddfd00020bbe5c05147d03a926c9f40d8ee1d803468e57824f7e9f5a393eb33e92bd83a107e3aa5be16efd281eefcb6d8e8eab01aa27e31c453fcb1a3210d79d3062b7a23e0ee187e4c067b34f00c72022cc8e4ada32c892b4c5be5553656dc1a7390752699ab35a19c480b10f4f969684755d1838b3278879056707b64a2bb266919c86a6bddb028fadeb21adbe0fd9cfa8bd9d428facb3875ed16486ca1603bceedf34dfe2582c15a767cac6c583b7a250dec7aab67403b935f9c35f96bad240acda9e67fa8cde13843c83ff12c1a245b9ec7e1b1cea9c42a9ccaea08a925508d53478a8fa7d9dbba1d7bf301bfdc6bfd4bd85abd58f266719a12686af8e6bc35b3f1cccc60189f0350a0cd1b29f6d4228341aba3117bf00132050143246a9550f65663fa34798f9824d1760b3ac578c3926aa89c962d4ad6aa4ed6d8ac4991a741aa0868d74a837fe9aa502ad2da5deb828cc98a35f16a601e03bc6e4e53f2c223eb8d4181adc1dfde2b51f6f67f74eccd6929b5d646c65b57146fe4c9d6bac256ca9a3756f76d23e5c6bfde1d776458b7ad95bdb79f60cd66b014b44f90598abcf820c57b89595e1a3081adf1337c23eb7e635a267144e69bf79313743f1c7b53c86cbd2fb79691d5da9978d7c7e648b786796179f8e3d81e7906efbdb27dae8695096bcbb9179f871cb2372b645fbae26d2eebb684de9595d7ad83a2153f5a3729ef9cd23d811b80165e9cdf1d216a2f39be3d604c4e77b95a607151a5243cf62aa0d32a54ef6be9ad3e9b3711457f9fbd5da8352429616f0abaf5a6f5566779af6f3d5663b6635bd0719d36f1f875714d61ddd268df41c506e66dba3f4191436faa516a9d6f623b9614985960bdad8ead84b70c7ad9eeed9d3fb18bfd8e37850b68261c9bf7f6dcf2ec0d1069eb232c9bb8d93a78e2ab16790cd3be76d2c1d6fbe93a4672f14e9d0329df0cbdb20d7bf830e72ed31c376c2b493e6645f1d66dc7811bdbd60382b11f0dca736f5b0a6583ffde5abce7d42bddf919b04e6fec3a5677d67a462ded22bb6e26cb890928de29feedbe425bd7540a5b6110a2be9f804191bbd4b8fd9341ffc11914ad4bb8fdefc6a0adab21589b9c32e88ec9c14756f446cefd846167dcdaaff3de7119b6259813ac72e44f7613a26dfce9a6c58617ff7efef4b6bdd5fb1cf6ad597a89c716c8e5c8a2d85f636b078d63eed6ebdaa01737fe8c4706b54e679eb7e03ddd6d69c917f8ccf9b3751cb100abe24470068d1b83fa6291534ce2c6a1de3b8ebca1e406595eb63671e4d623baaa7f0a1eadb35897f07ff2e83f328fd659bdf1fbdf8747b7d8c1372f9e7ff2ac9d6ca5ca7569a3ee57f0a84c5ada440fde99d35c3ac393d34b9233cc3e6ac3e6d196366768232f9d2642be92c6b9e41fb5e9d8146dcb3f6a1e0ed1cb31d299e4dfb74c69475590b437edcb5b9a6de77a2e9d45a820cb6ff48349b969e0ab5b535674b96d9602086156ed70b9ddb31ebbde71babaa0226f138a46f887ec8dfc77118b9a6986efb2b85bac1cadc8fd349f03a32131ea471c107643dc44f771f34d58958a8b1b6b4047915cba0fb7d7c6e6ed64c827eb90c230cdc44fdfc55b715b7b6eca26bd2558f7e6638f611f9e798e697321d306a2fbe47078f6f2d593e5f5d5e3e7afbe7e71f5ed83cb6f1fbfbe7af6fdbfe6443c16d50493c6b27fe066974475d6a5674a3c6bfd8d410e9446a91be44099ac3c75f5fd834b92542e97ab1ffceaf6af959a2a2fa3d424329abf5366d717d93be9a7de09d6b5ba62eb4443d60f1840b891d8030a540d0e7bf526c94004888c8ef0de58b9c15f54a2d729c69e642dae359b1f80a6a10fd9329a73a87ae35a6baf34d0329ddc274bde4ca0a4f950d0e6cbc03c45e092950ce8e67ddc3fee92e3d694cc328c96a5d06f2e6fded319ff7b47f8a4c6e56eb12a6e5c4499b684323f6eb6b173ca99c7d2b32499a37ceae99626a96dd32d896f9ceeff495bf3a7dfd9e74d2fd5bb35e5c1bcc05f33fbd8e64a757b2f8f7daed0bcfada9ee8e3f8a9a7398a20dda2d7ceefe3a65f39bd02332df98699f24e6196139484f7abeebf07dfef9dc1ac4b425e058e1b2fe06f56eb59d340dc1a870d3b5520720d1dee3045354c6f6143a8c244477d159fe86e6051c01a869dcf2c9e652075441657153d154d38fa4b446b018423071427e99f6af036fbfaa33322a58d537b58e60852f5f7246788e61ef609fd7866842e8805551c71a057a2d16ea8c5038468af8df012758bb80a7aeaa16f480466664455e37e0eb2941294539fd97c49d5a934b68c826dc6c571ba39f49f9f7247f8b8e013483b30d7aada06e69ca473db4dffbb58329fbc992d370a629d7e8ac18e08e804c01156d275a40db4881e9f48c69066ed63676c331554e8abac18865252079a94c45e6e7b76baf3c6c205ee27e6d5c00e58c76b678b1a0b4e256b6c26062321ae0a680b30151a0c024c240dab6214e59640d39b683b52c40cac278c198a87ac951b7a18697a1b4bf17695e741131e2d545d48ec86500a02c1123a08647a28275a5ba0623804141865e0c3b018dacaa67c4690b6617ef46cfa66acd3fba0b3f7069916073993c9d7a9c7605d0d5df8a9fb16f950debd19701e629461eb71db213523418ff2ea6db006ba20a814180005a9ab959cce882c34601000234459a27a16092047a0989b45e0d7e1476d36b8b1a2f4457fd673e9cc4d288468a2ec3290e884aec5608e16c1f88cc852b56433ec37efce4cca326d9d6ec43070473cb3cc90224784a9a2bb11df2f40ae1db7ed7773f75b053de7eb5ca12eb29a4c338c58b275269fdefadd1acee83dd54885ad77ed2db11aef1e274300a932d240ca2d6f96e6b0a143b4b7d540627a30c4100b26b67399c3696d51f449c46d12f13889e8b388368b787d163f75f4c16127fa296bffb0bb85529b8d97ce89a5743f73a90cad1f7fe63abe783b6c9dbc7690c8d2736a94e7273c74d5526e98ea0d87ae4fbe63a543c490dab2bd6f51f83cc32861587ae93c97b1963130d6023bc3071b6db0f1dc062b452d611e23c93a1d698d2d760600bb6a59afd9daecaaf89b2ad7550f009a6d35a82d32a02dea11757534d1546a4011d728d38136abea45fd23027162901100138825072a517ff2a1d8cd81ee6930eb747c144ec67a1ec4f39664aadb570377c271a1a075910e5e4f6c75acc088f28e466a910163c7e836cec5a4862c5093daa0d260536f1dcd6b804d5d5637a9813905933a1c4d6ab7a8ed242501a041d37253cca48e629cb519d4d12dea0840b6ae921f09edb74c1fbc738274ddc666516f0675dc0cea78625047b3a8e36e51c7a3451d37933aee26753c9ad4d16d6a808ca1f4852bcea172efe296059e774d85960568aa03ab0fbb3ab85d1d8e76b59bd56137abc36656bb551dddaa8e9b551dddac0e6656c753b33aba5d1d37bb3aee767574c33a6e86753c33c3ba629dcdb076bb3aec767538dad5665687cdac8e47b33aba5d1dcdae8e47bb3aba611d77c33a9e99615d07a9599d18c09740679bc110fe0009ba6e6675c4c993e0bf81cba5de7601efda11c51315164de5a0ad0cf09675f8aa0d1b7ca67c885dd7a4af641d943994cdd01634036b2a4445edd5e635202a2981604706510de78a15c4946a59f17af4aa2624ac5f33d2cacb3aad72429455e0e865bc25523b44ecb7beda4117720a421a65d9ca2bc22b0dab461886488b534e29b14a6a883d07642b17b87ff45fd6d56120d6ac32aba77630f8c1b6a279a92a0965bdaa4a8d62c5554f7230ec42320f1e63afa2a52ccecf4a3e396220a7160bdc29a467f0ae0683d94a4569826aa86e30b896fae390df38e44cab11840c2dde68d1009ec51c5e9e5884d0b6d51aea0a7483dcedaa86b19d1859fb34941d07a01cd502196bb4a2268edd9a096f7e5352a525488c19c0aee408da6e1521c0c935842b31d83c8c5e2c433c4eb811947322e5357283579363c5e91bf487233383e0c8c65a235be05e6d28207d82dcd1c95d55bb9a3185f6c2142547c2be026175ed504061852fdd0c38e070714df521771da54883f4a9aa902b62edc75df021d180f7644ca431a8dff1fea4a66295465fdb8c1d1aa8b548d4b03d8aae8e5e3f6c9550be9f6a186c7d4e0bae44661a0ff5aaa9a40af6c5c1135edcae57f72e2e1e72613c300312e2fdbb68fda73f701ec2aae6a17c5d01551a8e1553239ac16e1d6f507a404813e99055aa802b36510bd82e64358c96865256490d6125ec1caa5bbd2e37d7cfd90cf719bb4a811237795094d5bdf0a5ab5103390fcba8fa53aada99f5191d4c419f0e4ae56089bef045a9d4817d1587c1cfb1d7f5ba1550f53146e950c1f449f79801fac275a546054ca9aa2ac7ecb21c81cb4c3a3666734995359b5304855bddac320adb340575619b3dc38e871c40a1680df43bf25d2a720e210a2c49d18b29a3e52f4ae203321aa1fd1a248ad80f4e7bf13067a2a0b08fd8e0bf3a5427421e1cd9e48e037516544a75f7ea36f8e05057a72303bd903c09d1e44577ae90a18d5402b24b52b68a6db6cebfcd4c0db8eecc110390b711dd64357432fc5eb776732a46200c5d375514fa4928f8b3174eead1ce4a62b0fc367beb2baed354bbe661cde8918cddadd72570635cef2cfe1182280f99777d726e40d7550e6bae82dc7d0c4f166dddbdcf66c065aa08d301fb787777f7b5f17e7a23b20346bdf7adb80c7e02353b86d51e9fc730b9d13fc2302bcabf7b56a31c6609b0f619e272335755229e891ba214b5546cb8711f6fdcc71baf8df777f7bff9fdbd7308602349a10669c3dcc3e7312680a14a173b5bfdeefeab37dffcfedeff1f0000ffff5fe69651a1010100", + "617109ec9b8616e0de6f52cadc0ad126": "1f8b08000000000000ff5490cf4ec3300c87ef3cc54f968640a2aae04ad20b4fe22d5e172d69a6381b428877476bba35bbe49f3ffbb3639cbf601758d5524edf343c01eddb2e852ebaeefd638e006663b14f192fc7374451e551f4157ec23eb01ef08b4de51a32ea381337bc851e651c2417cc6b774d3f623310720ab2c468cdab82a8635b0c30db73296942f93989a57aa1fb3021a9101c17ee9cd7e8ef520267cf5de0ad044b5f33d796058c9e78aad4c13b2793a592cf42c373f151f4d3f457e0a195beea9b597be72febffe0efd6fb7a5e9065fb0f0000ffff829b6c549e010000", "63b59db05ede78b10cb5f7da70d5553a": "1f8b08000000000000ffacce410a02310c40d17d4f11ba3707f00e82201ea034510aa529498a8c43efeec6c185ab8139c0ffbc13143a435c5794ee861721ae782bed396ad2f266bc3762b52cca7362564ece84367266b318005c53b39abc48fbfb5c553aeb9cf04a06dfe6316a5d601bc5b00f303a1d03d8467b01c4e62acb1184df2a864f000000ffff4c95c89e87010000", + "6636bf271e9c01d1d5f067708b9de426": "1f8b08000000000000ff8cd0c16af3300cc0f17b9e42080229a429bd86341f1f85ddd6055a765763b53673eca0382dc5f8dd470adbd86d275dfe483fd4287383ded234ed70a42baf359362c1360368f4b63df01d62acfc18a6ead52bb655277e6449a9d9e86d9b351b656e6d9635f90e2e5e86172fc5effe9d644f131f8dbb5a4ea984487d30ded5df7b0f34f057d6d959c8a6d451d0c5aa848183f6aa06ecde8e274c2b88903f6df90e469260c816186375f1562daacd82a874182cae7e4a6bdcc7c9177f39189fcfa801cfc1c139b8f59dc41977c5125051a075efddc5c88035e07f6178f819a659f81f9670f6ea5103eec9f56c176cde664d0e69999f010000ffff061f56f169010000", "69effaf8141ec967d8eaec8fe3a77d60": "1f8b08000000000000ff8c564f73dbb80ebffb53e0693263294f9666de511dbf1eb299ceeeb44977b7dd1e6c4f424b904d4726558252e2dafeee3b14a93f8e9dedfa60da24f00308803f209582347cc365c9d2279882c2ef1557e87bcf76cb0bde8daccc87422e8702ab422efbd31b59ee1ccae7a25a7131144d65b99b38c049d91cf79a9fb8e03744b72f5ab1549f2b6fb9e09394688256e21c80099e235d506d4d6e9dc499ea4d814cdc2f4916a8f1665d89271ae88f5bfdd4884da4939ba48de0b843f9ba2a78befb8dce1da89a930dbd79f98fbcc63fb0902c3b53eeac17bc46d5c8387563d9e9a752e47c5529a6a58229ec470028b4e24809e495483597c20fcc3640cd547be844cd879565c15366041398b94d8071140b99e1c356665581146fbe57a876936a4331a934568c17146d681c0e3518116a8a53a278001b514abde0c2fe388e9ac51455443b91fa5ea77e1d5f47d75e10e552ddb274edfbc6e95d00d3ff774ef31cec2e4ca7d39f590e3a350085ba52c2fd753e0014a8e10977306de2b38b1496054bd18ffd793477d8f3d827951e367448890e2b19cce3e0308f7c4d668f662c5dd8fd7815c2781c749efa4fb88b4833a5e91bd76bdf7bf002381cc08fcf75af621e441a4977779e42ce0ac29fdf81e77e9bddd913ee164655544531d43c3d87596364f113e0a1525456b476bed934dac56ab6a223806368d46db992dffa602ad0ed19f3ce80c0e74b0fd10fc28180e396e8b39235cfd0be167f7f9580674bd30b37bf9bb5df389e005ca2197f9ff30205db6202deccac8b68964aa151e835a3f5224a895ee19c119d3fdbe74a6e13e82ad80bb54cc0f38e8b10f686fbbe8aadcc78ce314b40ab0a43be1252610233cf54ecf5b51782b7697f98f7757ded2de07831021f25cb50dd97a6c0a9bd8721c92dff810e3fc365b54a6ce9bc0ac30959da00dcd900b42c196d480acf6576f16e34ccb0cb5e97614b0fce9921e5b88c3bb5b60495e19221cdf4b50960ea3e81781eb90771158783d38a70a8683e97521a154d78c213c13dd8dd044cbc27f68f17826cfdde93ac548a9f586903783cbe0940ec5f220c00fa2736c0ddf717d6f4f2fe2a0eed1d3d3dc0c797b4a8324ce0948d2fc36c2c4ce7ea922db1e8b0de807ac325ff59e6f9c17cfdefa0757ea07a15f8f3f7f5749efd771eb55f81b167bdae5467ea32224afd8f00a6125b844b4eb9be18292459d4e8b7cf3c70faf8524a6a11de5b32f8cfe9e6d51baead641ffd952cd7a8365d0eda3c2e5cdb6a2b7f59f122bb69daef79ab8d63b8bbff729bc0af39ec64054c21ac59cdc50a38518504cf5caf41af3981901a96688e083578a59225aa62e785b0654fd8c251a5d04029f870ff707bf717706ae45b7160048fcb2acf5921ad6f8f206b548a67487077ffcbadd16ad11aebcf6ba6b1c6d7885a8254e065586321cb2d0aed458d9e9d3850d430356653248a50d4510b6e9ada899aa30ec3fa764e198c1d5b694a11451d0edacc2e39196822d74ffa4e202b5d563a814bbc6d097b435e0825d3eb041eaff60f0f1957e6fc1897d5b2e0a963e8c7ae0e1ca1bd32dc35aeb077b72af095d409f9f5b2ae409361e37dd128c832c56c1c691a87306ec6a7669162bce8da2ef4cdd7f6f4ba19724e220b418b6d1d6a1db6fdd9f0fcebc1d2dfb3b24491fd992a5eea2f6ce5682a083aaf1ba6b67843276cda9b4996a319320dfce9c8ebb7ded879b76b077d0096c82acdf39deb49fd2bdc32b13281dd3f21960fb9c91539d77aa12eeda9dc9afb53dbda7a91546e4b85648c1e4f431974d730813284bde53f9af170588eae7faa0466ed5517c328bc0ecf71741c8d6c01448664943623cd49790c18c20f467f070000ffffcf23b5ab690d0000", + "6b9404501bcb97dedc55c936193973c7": "1f8b08000000000000ffbc544d6fdb300cbde757104633a4401da3d74cf15034c150602b82ade85d899858982c1912dd2c13f4df07f92389b734b7ed628916f5f8f8449209f9061bc59d9b2715df615a201768937c04c08afbdcfba9a9c84dbf1a816afad99aba0a8165c57d3e6299906ff988d5aa0750d2515a6b470785021a4b6a2535b6704ac605808de7a0a4fef162261af77d84675ee2f41b3a53db0d86b0e2544c6eefc037d83348d6a4614d3aadac2cb93d24e1163c8c5b4480478b9c109e710f43ca2b6b2ab421749121b4775816d9b0ac56f968c488af15f659b446f34d1d5959a168f953d426eebc07cbf50ee1a682d91cda700f44d641da45f21ee4167474993e9ab234fae5502124843f29397a312a72efa34f93fd8abb0d57f21742d4988abc87422dba3b03a305f8a0d7aefad8fbc7b5a3c9686dc4e1a4f9d658980cd579e5f6913bfc2ef54e6108b720355cf458a9da7215c2b9e68c6cbf3d2952be2bc95096f29a2e2dbac8236bef6fae309e7a1fa186f285f8c82c23919f073ed7edc28f36e2d10018b446ad546ae5aea0e4dc6550cb8342fe836653cd1e062e2b6e79f9b408617659f2638a4f0b08973a41eaad49ee203ef20c925789fbd814e37709a2903464d0f5c63f61b7e7564bbd3b115c0a49d709fe770545ac599bdc412238f1b4442a8c4866902c965f962fcbe3c1c6e8adb4653c79b008075383ab2d7e3a25b74047d61cfecaaf1b9227f354632cebfbe77c2c753dcbb26600c5e1745686b14bd20d6aea27f4780e15df49cdc9d849b793463724bad0bf030000ffff7c6741bce2050000", "709da3f0db2b11326f25fd99c4035c2e": "1f8b08000000000000ff74903d6b342114856befafb8afc58b2e83032917b6d866cb14c942cae08ace4a6655f49a0fc2fcf7e038c51248a93ecf390793366f7ab2a80df9180a80bfa5980905304eb6900f1307607cf274ad1765e26d9ce2a53aa7e73836398fef0ffc2fa0544f968304a0af64f1b8963cb74b2c94ab21fc06b65b29d51f61017035183cdb42af778220dc6d83d45936af4f1ed0e68cfb03f69447fbd1a5174fd793ffa49a6d11c794841c70dddb10c17fc7f301b952a3db0c2e2530efd6ec7f070c7e6e8d8cd449939e85cd59025b00982eadfbff5d52e3fa71bffdead050d6f73dd52068405d242cf0130000ffff7b2fce9c7d010000", "72751874ad9edbf6b806613c6e298ddd": "1f8b08000000000000ff9454d16eda30147dcf571cb915da2639511f265551f74007630f5d614057ed0939c9255835b16b3b6815cbbf4f490894765dbba78baeef3927bee7e08496dad2c2a5561a1f07db2d875c82ee116ae35d38b89c3f180233daf9dc9263a8aa00e010c6f39c3c4a93094fe8f5f61d59382f94027f4087ba573c55920adff09372f45791f583bb57ffa7d0408ec88bac235005b843949452650e51ae2367d3e8f41da52b0db6ddb6e27d63c28948ef444e93bbbcaa187e232d3d78061631f0e5d9fb862dcdf6142f419bb9f55d262db881291325d3483847de3547b946fdf9bc442efdaa4cc254afa35c27e57229948e9ed4ce8b83d6adf4ab0199ee7e3bba232e258a3ccac844e93aab6b3398910115aeb474d8ff3107f7e01b845118864fb748bf8cb61e93fefceb27765a97f87434ae6b94c8820581f322271737c39e9c0f82b02e7c23ac8bd1dbff0e808db05224aa9d0646e3c5f0fa470c56cfb0b7660f988c67f3d174385b0c2ee36323afc59ac22f5251552d0ea46f0a1cf0ede7ecfbd562d09ff72ffbb3e1abcc07c8743c9e2f26fdd9ec763c1dc46056eb4eb9db23301fcee67bf2c5cdf4aa15a8b906c98d5555c582e004a3c6426cc83aa90ba42b2d53c28a94211b84a523de9acce55ae414a3f7a8a544b37f6077d6b6e35dfb35f4193f7f063d0bcf83a046d7869de0f34a1439c16bb08b8b181f9e69b3faac7404bf22b42d8c74779b00780a6b459beee3a034998ab1bb8e23bb91699d9a9722726c246f9f85f8e3bfdd7f962bbe7fb0ba9d1d79d8bd91ede8ee5fda7ee39f000000ffffc16ad22346050000", "73ebe94c550be297aea1d1d45640408d": "1f8b08000000000000ff8456dd6edbb812bed7530c74651b0e756f200572dab43907ae63543ecd0245d130e2d8e296e27049ca8e61e8dd174349891d20bb178664f29bff996fe464f55bee10641535d99065ba71e4234c32807ca763dd3e898a9a62474fed762b0d1568f7c7fcdddbe1c9802df90a4330ef209bc3d58860b4935e3686763bf4ef0b9c81debad05a4fc6a02a0256adc73ccb004e27d05b10e4621037ce89071deb3539e83a163e9d5e6fbe924213d6bf775df7afb15d3972c5f06b0e796f07ad82abaecbde08fb5054e4c3fb3a9f8b802170ea1953918d68633c3a7c3f0967a03c9b665951c0edea3be8006d400591a046e3201c74ac6a0818a3b6bb004f926fc9c2a1468f106b6449e99cd195e4e2b38627d47607beb5023ee156b626f269ae708f865c8336e622db4b9f2c5e03f782f88271927fb9ff75bbfa9ecf2fb1d38495cec16c0880b39d5cbe718e55f7ce4863c0531b3180b40a1aad94c183f4c84d0483284b859a5aa3e00941e1565b540236b50eac29d60816fd1ea1421bd1036de148ad7f13a5c88a828fbe51cb79999f199bc3ce53ebc21c3056420860071456467a54b0b95fc3d507f874ffb0621dbddd06a50ddc64476a412a05f2dcf948f0289d7b8499dc46f4b34119a758b28a646e0eb196b17f8783360656f71ba8e51efb0b8b87339d1c2f42904daa1e87ed5be4503d066a7d353a9c620d20031cd09831e8ff469026d0e076523fa6dd23543556bf5181b62999e4157a7e3b5e242205ff5872a63f6b83e191bd90f0f166f3f1eeea66b9ec35ce2110e838164c9a833c727bb1b033b24205468638da4a3217aecfd9771dfb8c388f7bb4a3b3ace3a52c29b30c8c0416f7e8b9392ac95420b26d6b2beeb4c9f4a201e19401178d1bf3fa1aac36e904fa83b1dfc40a0f93f1fdde25af7a18c0addd2f7806e6c3ffb21fe23292c7058c232d56ad31a76e04ad3d3e488f61013f7e8e7a87b3512f53800f6298bdc954dc49ab0cfa5145f7c6e04a36b880fcd73997f199e0d274ddafc193bc17eba6597af2f8b5911a193567ea081e95f658a52496e572cc85f87fc04922e9b25c4ea6afd24bda81c7bf5a0cb1276e8ce8034cb6daa4179eb7e3545ce839e36eb11e6596e9ffabe21263df0f83f281eb20316224f85f79bfbad07a4686a264223a1bf5e2cf40361fddfec765908c3f78e902a0acea17fbda8284e8a50dfd821423162af15d9a1627797ccea7623273e4c447b216136e3ae2be6143fbe4bad2413e191e6a1dde6486f788d8bc5a9934691d894fff994e47df79c1f4fba517fc72bb99e4453e873b6a70e812062788c7d87acbb8ac4b6c3b16b11fa7f1fa82ab980c86dba119a4056d2b6ad24ae813924867cbe3a603588a70b7d9ac4b01791da35b14053ecbc619e4a595c3f587fe3cbcb938a3cf57fb8a30c06c6629ce668036a5aa2c97226d00e6f10b12870d81a2e4342b3b70c754d4349ca536248205e7e9f9b880d183971d2a347fc4148aaa5024cc902068c82368bb25df242b67b2ef7e67143dc7bc0ec90b7b7c7d89ed33234eaf65193f7bce20935edb25cd94e5f2db508b45cf3abc74af21779e549b3a6518ecb25cae39923b940a7d584023dd8f1079d3fcec1fa7fc8fabcfe40fd22b54576b4f91f2c5509e3cb14a37cdbaecef000000ffff2bd1c1610f0a0000", @@ -53,8 +54,8 @@ var _ = func() error { "7a4cf344aedb69074260e6cef71f14b8": "1f8b08000000000000ff2a484cce4e4c4f55b051b555c82f2829d60bcec82f2af14bcc4d5550b5e3e24acecf2b2e51084b2d2acecccf53b055502a33d033d03350e202040000ffff53ac591538000000", "7aee976b536bb9edb3b5ec620565cfba": "1f8b08000000000000ff74523d8fe32010edf32b90eb65623b5e65956a8b6baeb8eeea48188f1db21838c0f9d069f3db4fe038c6bbb90ecd7bf3de9b61feae08c914eb31db91ac1eda96499dbd84e209ad135a857a0139e463b5672296846af002473756a5e0a85cd4f8f5f3f75873dc0ae35db623c18390acc153209cb1368c7f104acfccf3432493e02d64b3c00da1d458dd59742e5b11f219652d1aed84d7f61ac89df087a106aefb75a7eff1d78b311a34a81a545c6092a5d6da3b6f990922156ca09872186d0cda30d98e64fb028a0aaa097b6fb5f5ec8c4ef7b86eb59adeb4b51887dfbfc2db2c75fc33e018f3b681ea6b9d0ea3c7ad8012ca79c0064f3f9e667eaf598d72cda58856dbc7a72498b6f85fd05874e829aad3774a6450a9598336a26f90c36bf6b21a61ee5c02de8ab4152f463b4ce11cb6b137c2ad900bb04c7b3b6d0e688fa9f83e877c5e95634be72d1473b7f357f9c5b8dcccf060e5327411754750999e0ae53c9392de2f8e1a3974e37557f7e9479d4e8af67a744f78b70212c35e2841c3aaf0e22de33e21ee73a8a09c88931097c814d5b5d3123d527e18d4877bd01fba5c9beb33f30a5ea3e642f481e4dfdde2e16cd2154e981427b418b6f530c8cafbc216c49e29d1a24b675b7ea9d20dd2f06df7204509793ceed5e7ea5f000000ffff64e3e7006d040000", "7bfa8af3a48357849c69805d49e22d8d": "1f8b08000000000000ff1cc9b16ac3301000d0d9fa8a4393548c6a3a163ad4a6d4746807173286433e1b115997e8a42184fc7b88d7f7cee84fb812a02f819328b5d4e4c1a0c0cbe74e530d852cfc9394e3c81b8d98e648d958b8a92693c0fb07a0b89fe9efd7e8576ddd371563956a50dcd7a562346f5dd742267103cf64f71838150c49cc937b9eaf6e2a39a4d5d816f481a2e78da030f4755930b2b6eaae1e010000ffffeabb8082aa000000", - "7e4ac7be867ba59c2d5b2fd5252a4c06": "1f8b08000000000000ffb2c930b42b49cd2dc8492c492dd6cf4dcccc492d2ad6cf49accc2f2dd1cb28c9cdb1d1cf30b4e3e2b251b555a8cc4ccd495150b5e302040000ffffd53efbb835000000", "7e882a42175bb172ad7014ae8bf629cb": "1f8b08000000000000ffcacb4f498dcfcd4f29cd492dd6e7d2d2cbc94fe74acaccd3e702040000ffffe55507d519000000", + "8086dcc0dc8cd747b27caae0808d1553": "1f8b08000000000000ffb2c930b4abaed6cb4bcc4dd50b482c4e4eccc9ac4aadad55aeaed64b4c2ec9cccf4316b5d1cf30b4e302040000ffff9ca0bf3a33000000", "80e003a140ebedf9c08cd0406024feda": "1f8b08000000000000ff94544d8fa3300c3dc3afb0345a69f740c54799a9d2cbfe95405288066294ba2ab3abf9efab244009add4ae7273ece717bf17ef6ad4c4959606fec651af747255825a06459e0ee331fe8ee35672e1af2b5e7f36062f5a2435766818bcbde7bc94f21847031742e98641960e23f8e2a8c23139ab3f2e5ea111d224157ad45d870d82ea1b0b3cf53ccc2d77a4a8936768337b7b424d164632283cae8b5ca56a5ab2b1f4184713a16babc8d2e9b969944e2a24c29e4156b8ba294a383028b7bdf2a55788bc6a9f1d1c8c50e7a1e35f0c94ee949649d561fdb9c0334803606e7137f4488e940859a3e1a45033b868218d050b4a9513c593369e93a37d5faf7153ba13585f7aa9c925ac703a792206f9617efef952b992072c57ef59e95b0ca38b3c7043ce8b725fdc8f7ff1d2ad5b5b6ca4cdf37b69f74e8070acc42b4f76adcb7ec277973b9f42158a2f2003249c79bdff9cf6e9d6b09edc09916caa9b2eef54a319b8b1dffcf55697f63cf4e002b156fced50d9f382e6b5d4248d145b063eee727ef752280ebceb806b013f7b3ecefff5e3231dc65fb636fc3cc188bd79968166a59512ca49d0ef272ddef72fb4289eb488c2ff16a8e8e9ad72ee4d1cbad84bf7947859bc403c0d89af19bb5565f317cfa4ab8b6987cd4b2c4bd31ffff588a0f16a3745b73d332f18fbd07f010000ffffa680b9a8b2050000", "80fc98a1e2bcaf004a0ae6186e3c7387": "1f8b08000000000000ffa4935b4cd3671887ff26de6d59d8922d9b2eb33aa6558aadd406e3d45a40c64108300373ba1a8452a0500e838156401ca70844c7383928c7164a2dd0ca414e15778893a51048c620dbc230195bb22cc8b8a63c0b2064f77b9237bf2f5fbee77baf7e82b04bd82578786ca44848dc2d086f0882201604c143100491b075bfc96e4178eda5add98617acadb937f3f9f3659a4d7da87515f845e57136328f8bdadb7cf9958da53ffedc79bbbebebeade2766f9dedfde3f886e4f2e6891cde3e654074c680e8d475f61ccfe6755926126526f75a1cb0beb6e96fccb65b5963c1439c88e7f9124ec616732cbe0ec9d53abce38d48a38bf009c9c033a89457c449a4196a5ffcb1b5bfbbcfc9ab122d074f5fc753994de0d57c62efd850dfed475d35486c652767626f7128bc0cb1d2c0cbe238caab4c9beef2df7fa1d21bf1d2b4228b337230b21275452fe9ed8f894a2f223aa7820cf3d7846519d92bcfe4685809b24bb5482e55323bf70b2d3d4ec4da0e14993dc8756df8e5b4139e5e8ad7c9300e78fb73c05b85541941f8a795f86aeea248ef24a0681c454e3f85f71cc4df6cc24b67c3476f45a16be1d4875af61c3cc33b9200ce4705e11f1acc5b87fcd92f0d40f5710e87833fc7d3ff069ee70af8405d4a68463d47d3ecc8d36c48350dec93a808bb10c4a0ed0263c3597cebd4d1d61081af4ac561df18fc937bf152d72055d713a83111906e449a6a439e66c53bae91d331494c4d14b3f49b93d68e62ec0faa595eeaa3c79ec989c81b84660fe095d080546f2144dfcdfb294dc852adc8f55d48932d4414753038d2c4946b9edfe7ef303f6361c6354daba39ae8422731d726507e3688a2e009970d03f8c455732cb50b9f940e8e6adbf0cbed22bfc5ccf0680521091a92f232187df405ba9a2e0c75e32494b8f8e4d614970b2729ab1b22bfda8a58d3caf1e4667c7466e4574a286fba4f424115fb4e46f3eed98b14d69ac82a6f446d3061ec71d1f77896fc2a3b13ae196e37f6225237234bb17248634671a58ce8f85444de4a8e28cef19e4cc511df603e4acce2669505ebc8240ee7534cf7fb8175565756d116d713985c4a446e2389e5163a1f0c11a54e65efe1b3ec97faa1bf5648f7c8180ee7389d030fa96e32b3b2f2cf4e7fa6e77e64e1d90293ae27d807da714d7fc7af8b0b34771ae91f3633fbf337fc30fd90c1d12e0686fa585d5dddf4fedba1ed362e3e5be4d1b883a1e1562626cc3cfddec4d8580b63ce1ee6e67ec2ed76efb81b08ff937f030000ffff6ddbe2317e040000", "81f7b0862d1e52602eed2b3f9d226446": "1f8b08000000000000ff4ccd314bf44010c6f17e3fc5f36e95c04b72585a6a73582868612116739bc92698dd5966674538eebbcb7129acfe300cbfa750f8a2c8a060abe4eadc9a8aa8c1c7d596761a82a431caa9cd336d32eef5ce8d238e92f84879da58b15610269ea96d86653f9aa0b27e335ab9fe1316498c42910737b71cfe0a5dc08e0f8f928d7fac07ab8ae2ec00656b9a118657ce136b777738fc870e4f6f2fcf5da2f2514dd71c3f6f39fbc4b552647f0fffce5bb8ae9ae0e1e6fff397be7717f71b0000ffff845bf41afa000000", @@ -65,10 +66,11 @@ var _ = func() error { "8fca3f2f698f93dd31db24828b9ab0f7": "1f8b08000000000000ff2ccdb10dc3201046e13a37c52f2a68f00caed266058c023939e690392ac4ee511257affaf46a887bc84fe4939336223eaa9c0a4b80c9acafbef928c79265eb2985b72c570dddcc18f052b5f9b556bf466529edb167cc69c811a55e22b8b05a8741c025fdfdb7b2e10fbed83a47933e010000fffff34f28648b000000", "920fdc8a8285bc442cfb791bcafe45b6": "1f8b08000000000000ff8c51cb4ec33010bcef572c3ed955e5481c41bd8004b78204e2ee868d6bd5b12d67034151fe1dd9e5a11e785c6766673ce364da83b184f38c3a989ef4fd07b02c00ae4f31334a4014d6f17edce936f68d8dbbb1eb8c8f8da510dec48f74f2e3b0b7147e5198f6909b97f33f3c0428806e0c2d6ee955c6c403aeee12bb18068572559fa16f2950361cf31a29e79815ce8068f162834741b9550088ae2b8a42142bfd64bc7b364c525d56fc6c83c1f97a8d9889c71cd05653405c4e0dacbe8a93ac35aabf2843eee2b4357dd950ac5168dd7cad7be37c811ba63e79c33408f5bf50c496a71258f72851d731304d2cd591d30fc452943e625d6b15dceac76cc2d0c5dc53969fdf7102b63ca922fd8e0ccec302f01e0000ffff7aa1c8be1a020000", "9520f324d82a6b9cf6f4fe175e5ef1f8": "1f8b08000000000000ff9c52cd6edb3c103c934fb11f810454a08f42d19b510768d2a6b73470d1e650f4404b144d44da359664d3c0f0bb17b495c0099c1c7a92b43f33a3d959dbf6ce7a07edd84919c63571022d856a0993fb939494427d389903ad53343743f6016fee3c9c9c37de213e344fbd6f2be2746d470727e74a0ae5435ae5a569696c3c2d73dfdb81f63b6f771b4fdee18b99b8eedfbd6f5a5ab255b292f2b765f00e1ddbe4beae53208c30879838b70936529c1d9565a651293a7e58648425d120b71b29a6c60c4edf5cdc6c6bb995b2699ec82fc70ed8add9458729425ab9a716b4348e16bb6762cbfc1c4e777f622ef7031b29be4737030075dccd5a8addf70cd4234e040be8eee1d58545c6cf33e833b6ba1d3b387bc65883651fe1e7af9838a0afc0311317e304c36c0ebb43985b971619d1b19ec2602e6c7be7993276baaaa41422f42fcf60266b0b966078c4fab4abbe8e25c4b6e0f9ba4829128edfe1daddeb9784d3b3dacb29ebffcd01c3304970293396f28e430836b721adb4af0ef8e6e029110dd17ca1ab3169360ba2f44f885397cd22a3aea4d827a6dc010286a4ab027290067335581f75652e88861f966ff4e971476b501d3ffccf1955795535f47688ae06c5190f83470cf721ad282768d9d914d0431f06178118382396c294cda82a09c7bd2eda3e76dd94187d20b9925bf9370000ffff4d6db28e37040000", + "a3279e1c13cbf42277bea34ba00e2d17": "1f8b08000000000000ffb492516bdb3010c7dffd290ead8516629bbe1ac5a35bc2286c23d0b2f74b74b54565c948724b26eebb0fdbf146ba32d8608fe6effbdfef77482afd0c078321ac458f0de52da1222fea0c40b637754a85eb6328be3845a6d879d793677e77dfba1759b63775264ba59feb2c9383597a8c0e311f6c8847430aa62f6d8db634b71a7df6e31ce53a5237e500f2720d46dba70777b5acff8a1d15dfd07fc4403b337834cc3b8cedd5f50ad2d45681d8470bfb68736d1f9de06b48703917027cc0c3134407680c9c2b7df26ee8994f8b81e719591afdd7b0a4743c035ece35912638cfd06377b761ae5e019d2cefb56d0c3117771be0b72c5fd05b6d1bb182bd53c70ac456e9386affbbc05bd75e38fe8b8342db90172b100a23e61dc5d6295181d86c3f6f1fb63f8383b38fda776372eb098e6e8030787aff4b7e43217a777ce52fcbc1d4599612f871135cf450ad6126bd8dd107c89933d94f1363816dea94e0a25ffcc2018dfe4ec02ccb535e4d174be9e24fc229fdd6c1d3d392655f8f3c64d5b43bfb110000ffff8729a39981030000", + "a4145ffd5413f8f3115dc808cae80c3f": "1f8b08000000000000ff7c8ec14ac4301086ef7d8a217441c18d7a2d6d61d9931711ec0b24d9e95a4c9398996835e4dd655d1441e96d0efff77d933344e58e087580a603e90393dc3147826d2955ce308d802f5007b9f7f3ecddf01e1004e3c2e26bd16e3a18e5800bef22aa411d2f44ce7590f76a46f9a0c8283b7d6029e20a72f46fd4c0ed4db9844d7f72a3255ced68efedefcefe09cdb3f6cb7a273973dae1a1815159c2bfbdb3edce85c42baa1fcc1dbebffce7ac5a9d98bd0363155127343bd0ecb6948c412201d15bec04253d4f2cfa47f58aedf519e9abcf000000ffffdcd8bf6980010000", "a61b972dce26544398f591b4e2f715f3": "1f8b08000000000000ff548fc16ae3301086cfd653081d16693172f6bab0a7253d95b484400fa514c51d2ba296e48c4634c1f8dd8b1453da8b0edf7c9aff9fc9f4efc6029f67ae83f1a01f57b02c8c393f45242e59230812b96005638db08e4ef9a8fbe83b1b8f7918cc183b0b215ccb5b4cf1d34a8440fd09bbba65b87608e7ec1004538c0d39f4fc00895e77f02189ff5ea3f441f19935c8fffee3abafaba1186b6ccb01eba8a05f0f13b918d2bc28d6a0dec52d62440988c5c51c8ab8562b3bf6390440a9ea4c3f393a495bcdafaf85ef7390aa6248b5446190f24849deec7b081221e9ffd17b13de52cb37ea3bbf7323a496ff29f670bb6385cf9b97226ecfd98c52c0c5f869044d17122d1ff4ce7828d10bfb0c0000fffffb4a36cd9f010000", "a676ca891e9d7b9f2f10d3a887fc812b": "1f8b08000000000000ff7490cd6ac3301084effb148320c52ec1a6f4169a4009bd96d0d25e4a0f8a2c2b22966456522e21ef5eecfcf487f424d0ce7e333bbd545b6934946b88aceb0327140400a275491001e2613247e853ac565d36d6afb60693457df97ddd044ecfd2694c1662d01b9b36795da9e06a13d6b96d6517eaf3db8f8cf85718fbf6eebe5661cd52504954d7d8698e36f8a56bc0ba671db54f1169a3cf13a8e09cf40ded24ff54cf713382aae571be27e02dead970d44926a6048cc167102a336b9f2ed8d0e2fa71c3d24bf64f33b4d9ab42b906b7bf9ca6906c223e3e6362eb4d09cd1c18fbb1d0d6a56ac5d6a7ce17e21f83ebc6d5fb3159397258a7cc1ede76041ca674201ae2c07a9b8a7234bb4a59baa67a6c9a53d4e2bbb0920ef4150000ffffe257d10308020000", "a95877cfc2957859690620af727512eb": "1f8b08000000000000fff248cdc9c957482bcacf55a8ae56d0cb4bcc4dd50bc92cc949cdac4a55a8ade502040000ffff8a41cdb420000000", - "aa381894be941a89d61176150f6fd4a0": "1f8b08000000000000ff8cd0c16af3300cc0f17b9e42080229a429bd86341f1f85ddd6055a765763b53673eca0382dc5f8dd470adbd86d275dfe483fd4287383ded234ed70a42baf359362c1360368f4b63df01d62acfc18a6ead52bb655277e6449a9d9e86d9b351b656e6d9635f90e2e5e86172fc5effe9d644f131f8dbb5a4ea984487d30ded5df7b0f34f057d6d959c8a6d451d0c5aa848183f6aa06ecde8e274c2b88903f6df90e469260c816186375f1562daacd82a874182cae7e4a6bdcc7c9177f39189fcfa801cfc1c139b8f59dc41977c5125051a075efddc5c88035e07f6178f819a659f81f9670f6ea5103eec9f56c176cde664d0e69999f010000ffff061f56f169010000", "b1d40bde484869ff2c0f5cdb619be937": "1f8b08000000000000ffecbd6d8f1cc7912efa79f82beace7e590399c98cc8c837c3f48145c9f6023cf72cb05e5ddc4f06b74489bcdb228921454bfaf517f14454750f3994a8e1c86c9f630356176bbaba3223232322e3e589dffd8fefbf3d2c6f9e5cbd7af6e2f9834b4af97279f27c7df1d5b3e7df3cb8fceef5d7715cfe8fdfdffbddff15e3f2a727cf9f5c3d7efde2eab7cb1fbe7af15f4f967f3b1cbe7bf51ab716a694530ecb7f7cf9a7e58bef5fbeb87abdfcfbe1bb6fe2bf3d5f126e7e69eff8edd252cecb67df3d3b7cb5e4df2c4b8cfaf39fffaf877ff97ffffd8be5d59b6f967fffcfcf1efddbc3e532debfffff9487f7ef7ffe97cff10b94e8fefd2ffeefcbe5f2e9ebd72f7f7bfffedffef6b7f4b7925e5c7d73ff4f578f5f3e7db6bebaff1f5ffee9be7ef1f3bf7c7effd59b6f88d257afbfbafcfdbddfe92f9fcc932e97675f3db8fcecbbafbf7e7c78f1d7efeb1ffffaa7172f9f3eb9ba5cbefff6f0fcd5831b5ec23967fd51ffca6fbf3f3c7bfedf377d91e69cf7f1d7cbe5fb0797f9e5f797f72e961fec6a79f3ecc9df3e7ba1f797bccc8cff2bd51fffd7e149fcafc7eb7f7f73f5e2bbe75f3db87cfee46fcbb5ef7cffede1b7af5e3e5e9f3cb87c79f5e4d593ab374f746adffcfedec5ef5e3e7efd74f9fad9e1f0e0f2f98be74f2e9757afaf5efcf7930797ffc24493ea7623feedd957af9f3eb8a4b6df393c7bfe647dfcf2c125de7bedf6fff7e2d9f3b7ef7ffbecf593abc3b36f9fbd7e7049f972f9eac1e5bd8b8bff496d240934c6da66ec1ca8d53423514f25702fa9d8f5c3562971e839f53098024b4e822b9199c643bd6a75a612ec8b836710217c7bdebbb878c88553c1edc6a9e2bb6c97f88143cc89435e634e142951d04fd65bb1245e23a51eb9a7164b92586be25813c5c169e8233d12a516f5ff5cf020c522a9dfbbb8d03f732ca9c59c5aec8963d639e5d4d7ac132da904e23422e9a4f4e525d535871c721c3d75ff7895f52b55bfc291ea23e2ae447b3a93e8d06be49c585fa7cfd95b7aec69c6a62f0a19ffae4ae9d4624b823770121db37e869a26ee29f138b550f4bf071d3b4dffba4d44ffdcf5d3df1674c2ba2c2591fec9be1ab827b18fb6e2517c4fdfa66bcaab5243a92c51dfae33c0bcf19d8155183eda9186be8a31291dacbe4a473182a4b1e654424915eb37a20e9d729a4a76fb59c12b9b7ff2460c257adf2f9ee654fe0c56fcf1f2beee0be5e2c7577fba7afcd5b327cf5f63d3ffc7977ffab7cfff4a7fbd5cbef1dbfff9fcd9eb570f2ebf7bf5e4ea3f747ffdafe7fff9eac9e5f23d3db89429a9895c2e3fd083cb2a39b5dacae5f23d9ffe891f5cf69c6aa172f9fb7b1717bf7bf5fac5cb6579f1f5d7af9ebc7e709975ebfc7078f2e052efc7f5c5e1c5d56fffe573ea0f6bc320df7920491ef3e6a7f2c8f5b31b9fa21b1ff88cbf685ffcc16871ff3a31de121bdf5d1dfef55f36dafc06fb1a9bba041a1d9b9ad208d45a246a49b0a9c5ae8f9bbaee9bba1c37f59a95dd4bd48d2b2391f272e804ce3b44aa9466e8caff4df98138954734f426979cf8d13e085fd2972f0e3f7cf3e2b90ffb5ffef0c74ea55c2e2f5f3c7baeabd89ba8f490b934a92a1b724fb2d4ae7c53674fbcd43e12872a6369ac5ba99691ead2cad8af479e7e3db66ba154977b171723d7d443ad2df5a5cf9128d43ef57a8cd0724bbc74fd77689c535d7ae734432b92da72f141c36fa0928c5416154fa1144e75a9a2bb8570b7250a85ca5287ee84ac2f6fa2f7b24eaeebf04aae49963e702969e8c0bb4e8f5b4bb4d825eb4cbb8a4fa6aa93d63dc779a4b90c7d92b3a4b2cc1138531a0b652c49563a509e69069a4a5993607db125a3d1535d3863fff696445fcdd49575babe8565e8d77a496de1aa0ba1d7b4701bf8ced0eb5ef15365e101969839c9c243e9c1194f4e888bacb4e1a1220a9cb6f0245dac4636679e3d51682a6c17ee84eba9636e59af2be6c2e012a5e6a22a8a4313251265d1a5c3b313927576ac689aa1d6ae64645dfd5297a6e4aa042eaaa9059923b1bebf15d54bbd276535957375a6fa1e46e89f95cf59aef3f1084df0ab52f43aeb00949347a853c7c853c06a92faf5794063b6417abfe277664fdb1a756e200ef754436f9cfac24d257a1f25d5a55053119cf58152671a61704eb494a1ea58794254d486c13dcd45ca4ca4fa78912a50e57391a15c3fb8a5b12859200b74e349d1fb5413e900aa3263185997bc4edd897d369d2d29b9fbc0cc791b9872b9da05bd299bb7a65baf5749b4b4a933ec8595fd5507874e75e945d43e98398da5575299a02cb653ff28f9f63da8224fb7ce0cad97340fb1aa2ea4340e9cf186540fac6bdd0ea21f94cad3515239508dc574684b3dce5443e976a11a8f420e8d5458ea1cf7ab436f6a38ccc46f22cd43644923724be51065268e2dcd4727a3f9f1dd717ff6707ed11edab86b515ee342fa3ca9de95549e4612fd37d7d4637baab64c3bc4a202ad3d8d95f45f0c8191caaaef1e816a1a5174ab488b552da75e4c7147ddb80c5b43d7416a64e5a636cdae2a814ce3b34afb1194054a4f7c502b2a70a203bea41357f9cf9cc6a1c008a8a91d5ab7ab7aa8d574793d88287d929a7d072e6a9c49ea87d6d47ca1540f45ad0e4c905a2a5138f53791f8906145c83ad56aa846893860a2084cbca1d69e32995a7945a7d1a2c0b6503ad59ee6bbb46e7ff8bc7f518dd63c27e803aad14c2336d588983fc94c2d0c5d40bd948374d842f254482d3cb595cada7b12908af20ca3e0fb41bfaf8ba7dc3f92403b327e78ea42917d3fc953651f02c3347d693f28152434dc1cca067aafe8dcb2b2310fd8a5a93d526dc24166769e509bf0d1c9746e60b23fb6cff90f6c1317557041ca487d153556cd4a93585355ce51d394d68a498afe45774fd3bfa89d27abf285ee24e51ffd2495079c9ab21726a37f0b2a774999465f53549eeaafdb5c2516650f49758d2a9a945b6960044de75974282bb6206c509512532d793d87502a7a8428b34316ebe82567e85b7dddc9ec6ea203fee7741013ec92ca2a30be39546cd9118a32ad1e0b708ca87124561358cf033acab92a3b068e2aa71acce68989e9c8a4e43483f4aae3534b04d72d9cbcefe74646b01f549cafaa03d4245312e650c10d6dc5512cb1ae41d4f7e0c453d25c752f32560c6b596d852af6dfaae7a58089e8c6f6e38eb27fb53d8a93911e27aa4e7eac19363e36a8b1bc9ebc6ce84f0e87672f5f3d595e5f3d7efeeaeb1757df3eb8fcf6f1ebab67dfff6b4ec463519e9d3496fd436f4a4d35cb5846a9494aa1df5cbe3dfbf57b35c97b1a97cbfac383cb32492faf70f772b9fa019f3a00359d6f3586d839e5cc63e95992cc516e1e446992da368892f86e07d1d31cc5ecd95e3bbf6708256f74603ddbda105477db2070f50e1f756eb38e4dc489eed9ae7c14ab2d9f8a90ae4bdf54deb06e2e3000c5b9f1f84c12672c387f632bda2e54e1deedefd088d891ca416ab7eaaf06ce2627c63aa1246660bdad3bbf98ecb093abddcafb9951796be23e43a628b7d36aa2555f82932743ca90f3b1deebd10e93aad22ab481ee423bbceae932aac4aafa3b105838ef12045ec16070e0c4b91ffb60469c63ed67e034504182c3ea0ccdd527e11cdca31d73f5a45ed748f6749250ec341eaa523c43e2956813ab7a96d6a71ef26c81bb8a2c9e1557339c2cd5cfd8085c7194a1b1aa71112452379f05e368a7477c8874d61556f2135c225827b50fd49e523b081aa60635d887096fc29fa632432052598367d7ea16012437848b1a48b20e9fac1e9294bd42818722bbab420eee6c394415e9c36d9aa29c34d4a0e82a3eff8cf9fc7879efe2e2ed697f900f4ceed805564829d39aa89057abb729e734651de535d8905cb0a1365b6906eea60729f0486d9d60385ddad8942caad628a7baaa0a87e280882d38039aeebbc158b9b6e86aa106ae53175d42562d39c388259b229dbe27d80cb70e3d1e8a1de0121f8619a9f5d1fe433f7e900483cc8a26b4b6ffda3d1d38892c3da74679de2cc260cf7e9408738b9839d10adb0976287c62902aba99d706cf12991684b5c0f068a950e81015caef4aa8000b621abf43bb11dc52fa408f33a8d0834501c3bf2bf128520d3460a0817b0b2e093f0f438f60aa1fa03d39f5472763feb9556da14ad3d5c38c942174797bb65d4581724eb482f758d7146ec91a601f16350470b2527e13d8fdca753d1b29860b6963453267224cd4a47bb7d89e6e7086ce6096649295cdb690a087d6088710a920192b8c9f66f4afba8b0503512634f9a1d28fa71d305a6c50084a1c50c74e280433174ec30328cc6adbc23eee4a5736ff044ce50981aa4f408ce93d1c76533db841d60f3066ccce7e245542cb662aeb146c7554d1c841d9a2c6a9bf36201cf56755b4f32196a1a3c4407403412f1e224c42d8e513ebaa7bc797eb67247483d30167e615225a79ce5c9b6113d2b2ba8c0e9b8cd645d6adccab8be868225aa289e8eafa07323a988c8ebb8c8e2ea4e326a4a30969d5a32ea7e326a7e3514ec35bdd533b0c18bea4a7bad8931c7485479a8792f425ca4a8f4ea6f5cefc3f89a8aee07913d52ea9c32ea9c351529ba00e9ba08e47411d5d524793d4f128a9a38beab88beaf881a2ba9a376e4c089f8915c3efaaf15dd8fc066d85675db5ad0711b08b225570bb4ee1d1c90fddc070324be3133b4f25800a499ba19a20f8193d43c1972a7c88ddce34b0fb5453d83952cd311c17da8a63605122aa39d6cca0ab387041fae26cc415b6d108a586ac473bd58419fc22cadf7a402a6a01821795e445c9c6784b24ddc5c6b370fa9b2c87042f70f9c2098017ea8e257821f4740e55574aace27c1bca5a084195aa3fa007b081788aca41e5e982bd6fa456918425ac01dbbd92f977e4a09235bb5da9328ab15daa0a4018434a41610bc860157b80bc28aa52d6683e80a20489b6793ca0644e146c3d4214041ef34d2ee377328e5c6ab38a79323c5682af91ee4b446eb0954311634bc6299986bb9ab0626a466f3195d861663668a67d66165d9a6e89a9ecf4331e8c6509d95c007d972766a1739c300895732265b89758d92bd666ee88199b0a7bc92038c7fd8530f4a34c7d56854e85656e14af38c4ea8aeb54a3e4487a8a8820acaeddaa36baeaae6a4a78eaa8d46e81187cc8bde3c00f653470b88673fd6423dcb065da1795b62d23f05af1187031cde81ab75b540bcebf5457e85378323a2219b0f27425e000d063b7ae8d4af7083f2c4d0f33aa98d0430ee68fc3471de6a90169a7528e7028283950d1159c0fc56e22d028d8173a3e0a2763bdd1e95c3fab9fd53f1e9dce0ca7692d736151215095ce0b4b4d23d49a93de1f887e0cbb6a053efd0eaf7bd7ef16c1f5d0ef16d6e770ffdec505179563b50e7d047ed45a259585558e855a8b3ec22db9aa7c8f9ffced213786cb5ff4698fe7484e7d69b0736bd181347bb3706a4b1335722ac205ad4c7d5b2da92c4d256da8d59dd34d8fd01ee7d16bc65c6569100436277d5d0bb5cdc44bc34ef3fba4df10b8b22b8205157fd7c9e7f74c6bd303dbb44a472862e8fb4b535e6eb32e4594bbbbf9e6b9208e56970269d94957a540d57635e2179e3abd4e88afcc167aaebe1216379833c9c2b3223ea05f41b464e89a94dc4243c0a650c3a9a6a6b614d0baf5acf74bc635be236d8f3758c8a08d9aca4dbef66bfaeed7d3c2eeb07eaf223ea876a5035c877aced4c36f6c7a41309be8d1c9e06e0e3cbecd8816ced015e345d75c0982d0a3e84e6c5389560b488c604cc5d1afe796ca52595747f9484f00baaa8c27e1385139817889f266e8d497da085715f1c0866b4a6d5156ec58665c8786409432a54542e803f7d4754e5065a253290b2290a14d4eb49462315f7d6f4110482750970297b532ddbcc698f72e2edecf9b826113227bba55dbd4a9f16cd803a7619b9f09feb2ee8fd6556a2965058c5b1765c7e3753686d74d3f95d394f93f2c28d77044ac3c122dadb16a7a8f0a9e5c5b3c728e6580512b22c10381297db25c0b2f7770815e37133be47f7a5fc0f88f7ffcbcfde1445034c1ea668b556378ca70cbc826701021ab704411ddb8277fda02ff7883fb7f76e4e7d43adfc476cc6e611c1f29321c60e4091df0347a3e096d4e3fd86cf085f91d813080f3ef90f73c98cddd4cf815f23c180fb4d8335bb24b868980ffc23a235868fe9a68593d96e2939116334256dbc5fcda3eece1c39cab3dc3e631779f24d9c9d662201ccca46b9e6103171fc14a820711ffcd9eba93032c3cfdef2758ab8ab029b77faed5d9af55eb0db6889cae5580211d1807355f1578ef33bca6dbdacd6861d219b6542a318736d609546b27f96204cab66da994cad1a83e7e72a9a279b16bb4b5b5b38daf55f15f29c7d502ab0dbc89fd40e30f4cf8f3695baa785cab6abe10a48f350f09280f29cf114ea367b05475ea61a9cefccfa5fa5597cafd457cd7d9ad057ec6d1cded4596d596f73c50cbd02c27199ac53334cb498666fd800ccd7d793c42522c59d333347799f493199a6c39ac01a19d3d43933d4393dfcad064cfd0947733349b6768f60fccd0849b169fbca7ab22c23cf78b1bb26f1e7efe793e5a0abb9de08a475c82b7931dc1ae78ea89e219ae11c6cd8ac736c991ba6cdae744f7b0eb1e3e61c37715cfb4d8dca9da09bbda014ddf553c3a4cdb77bbee99a7ba67533c2e0dccabfe96e269c1b26e6fd8227fee8d6ff0595ca36b955da7ff93ae1f4cd72a3f43d7d6dbae7f7da36f6f3b358ac8a5fa29ad874bf5f193527d27ac8bf5b98b75b2f57a3f51fd89ea9fd7e439ed5ae15d79be53f51d91be9135be6528057a4b9e77c8f37e23515bbf294c7d4ad43acbae29ff49d40f226a9d3725069d12f557d760f72e2ede2e33f85535981bec3729b15f5783ddbbb878b453f3180bbf7afcd5b3c7871b2a0df8af16d1eea5a7d6a758505b724b34695c2e570f2ea5a632271f2b12fe725340bdf445974a262ffb076e4e4a75f4b2f0e0346b97dffc5c69c30757293c943ef83d550a37d71bd45a48de53d630f2e49b5f33c71f8b47bcef5f27e4fbab1478ab52e8390761c42b113cc602b23bfcf4c09a13af14b95a244704b97489a394242bd74001f71849802509feba6dd640cdc2b908c155fd99325379b4bff56732f27aae81e1f7cfa608c16d26baea6a5a49903da89f5d15db2a76c60d081d58fa0c83812d5083642a4826fd3f79811276644f25224d8103c9da548906825354efc01189b7b225a758ee21458498914b808371b4644cb6b8931296d8cf012c183147c4cdb2056cece4c0b10acc8a16518590b7dfd3f5a878ba2153802c6b4c3795253a53ec88a2af6c31654b8fd1c32d59bd485df5cbd411958c24dbe7bd8b8b877a0a9e817922fdc1897dbc7ab45ffdcc429561abdd53f5fc2e4b6043224ebec52c3d2e7827135d955f91f05b908d37b7cf37f926be3233fe4e58eb26beea1ec6d5a9985c6c10f4f2d314ae73aa002e9ccaca16e42d816a4431093e9eda6caca0ccbd344ad295dc2434361497e2165dc6c1912ccd35759daf92014c8e502d84fa083ac1cda2e86a35789450b78365a935b304c2c08b78c541d5680865d17c4d2de550229b8e0b08865ab2a34eca2c0e2c6a923536a8164b7554d3d57209df3dd85e23556b3a74290539855e7ba84b6b99ce88816e37a6b9d24ce0916527ca6e0e6d264bd9861ecdf556118b55535a4cc1daa4dd46c6817ff5c37db0f424da3e57b2fc1095254e187c1e72c8fb31c053ddb7a82e0e1196ace9fe3dd5ebdd6d1b4bdd44828bdf85dc31ab0703eb6f5982f3661a9ee636d48c7c9d5a61901c39c84e3492d808857c66ec938e9d3c525d2baca116105a27d702b09a8ae7aac769bb17c95c2e45b99941382dbadd635191b1a50f9415894158ad1ec93734ebf3d59faa6aee288b23a5aa0c4bcd2c5e37e0312d952f88de531ca9458461f2ba25ed547d0c59a47ad19046bb5ab688e5204e0804b68cfd15a5046aa5423fe8d8a0058ba5caaf88ed8f005eee961b4601d314cbcff7f423361980307641da2c923455b82131dfd20656378e0526a8399b24f1216fb906c5f4924a12fbcd692f1e2b922af41f1c3ce36b062be3d0c9588e020cf8026121a17b165c433225e40caa35500a4c4865a8f8249f2a92232d7f05f5299e7bc16b337bd3f2dd2c97a058e29eca126327b20c57af8229ab551b50e06a89139ecae2f93096ee5b603f4306e6807163f96deaa2bc8269aa41fbb0669450a01252af4b60140a9eb0f887c5c7c60835e76b512abfea057791758638591f308550b2b65dd3f11a8592fa7dbdf6e248ff27b37fad0751822e7d203c465612296f5f733d86d04a3e5ed7a6d7a8ad915a126dd782fb153c2162f17aff67c64fa1e44d32a3f40b994a39275eba28d79789b85ba9ca68134335ebceaeb3d2b50cd4ec75e4110e14a5f576bc6ed063282dbb7771d15ac5e3082e361b0642fe56cba92cb3a83cd7998ee3f53b81c39be37d22c2c2c72594822c71e24590f55949872d1637a49a44af916bc7b83b425519b08825632018a94fcefd3bf04ceb46d1c96cff2ca9ec5fe30f1e9a9a34faacfeecc0754de43582953a0687b40ccea9e19a4265c6f79be5a6a3a6b0fbf77d48482fa1869fd2ad55493e30922d48c7aa9cf1828a97e9af28252aa832432d4613bd325a5a2570c1df319422692c621922c533449c3a459cb81d8f545cb3fe14ae74ae0df3c6b7d9be514181899f2c3b352a663df17bdb0215fcca4625bc1606890ae145d802c9a47362e4b2948291aa98d291caf6b8ce7efbd9d2f09d8661dab5cdb86121505785598a64a403a18a57ffd16d5e765b5f88af0b8829f8c98919946bebf9a14b555046cba08b71a15c634f2928e2a689253c5dd89b38e7946d9c8bd899f33dc17e4f1e3fe51d5b1cc1ab09cb872179201f5765db514692be0d93e7c6313c4063702eea8f311c23797686a3fd27b187b81e69a816c136e4f5d9d57a78f2f60644ed9312c47c0bb530dc0a25b13d75f5647dbde03b7cb9e00bedf238eb4ebd5d2e1e391997cbd327cfbe798af8c70df6fcf64acb84aba10a3ff5e2d7edbca4f64cdefdb1279fabf9596036ab6de8ee2e31e310f6623ff96c7eaaddad4471df103db437abe9e163d83e7f7c7bc2dd26ac437e6b063ee1729cb0bce7e19a6ff3b0935ada473c5ce563863d3ee2e1f631c36eb7a2b63fdc6f456d1f76ff18828d8f1af6ada8ed0f8f5b51db873d3f8660f363863d6f456d7bb8e58fd8922d7f04c11a7dccb0e9238441a38fd8928d3f8660e56386cd1f210c5af905d47e27ce8f737c538b84695865a79518593400de8158de5b5682c8c7d4c362af3880c259e4304e285b573df5530f0fb8155b5e2dbec3eed380c3e2ad675fbc7cbc3e7bfdc3834bbd6d5e9c593c1d71ac5b6c125568a1a04ed5ab483d9062c1154e03e594e6abb0ac72c111dfa6dddcf9a1bf30f509af0998f876572bc4ca3767e856c180a7a29533557c130e2bc645858f9791ae8f842a87ce7202b3875bca0a002df8e39a8786dc19623f5ef012d40f468be09a726f1eb34185b847769ba172052073ad79cba10768842060531eb6a9c441aa31723567681d6eeb2349dff5e77e506e48b9ebdc1064ccb1f09b2a16fa42a15fb47a3f54c779a4adc46265129ce84ba16325b8bef1934ce17b7a70d947aa866f258d0cdaca6fb11a11f53c464983b76116553b3acced1e230bf63c32855a1d762e49f52745c39691e1314fb8513dc3329c246478c4b76ff782d56452dc9231aa0790e1b83d642b03ddd2362da4bce5436c09195b4019b167b7dc11e68e0873fb53e22e59099e92114cea59e6a45bef1e9e6e70cd8e4d3a995430d39f3ccb1359161eb0453c225a8cb7444fc8409a88951fe2bfc7b19987b25e2b89bd41d676f8451a006f548076a72b3cf851875bf79c00cf5b85973f6f7e69681389b4c5a5375c398bf6185819aa14b628790b0e74b2ff8afdaa67b180d8f0df013963eea4adbe2015de6e0ec763914532688f3e1e535dd98f466535f28be3030c1fb3de2feeeaa7688a6300d7c333139cb696db83300106886a2dfcf727a95b274a6026997bb782e308e118b270cceadab1c68d04804cd86641ae3465539e2733ac4eb96adc6d3439090121e0b87a30c1ffbde50c1182fa793f3a921f344b38fef6ceb247c6a42d07c3a321b491c9c2255bd064bac6c271d455a967403bf52d7b64383a84f87df1dc941a8f01b9874a43e48002896ebbb6ff3a6d7ffc6999d1e0caa933f1c143167cc2e4cd55fa3861737656e9276cde9c65aea76c1b3b1567731477faefd49db1f73d79fc3790968cd53d9089cf768dd9c7c6f46fc991beb1fd293318bb070bf3bccdeed5b7e3588f49a99bbc18b1bccdec5ecfec392c668594edf38810794d61a8b619e2baa6b2abc4a1e77868447e8f1c2abb99eb59137bcc53f581ac967e860043377c13440d2682052d8d5003a11c5680b2b55afe0c0255d103b3b1986c773016f2a273849450728f0014024878580d322b156e660a1603392d0815954812694b3cead898e201b67a2d96fbb3b3449d5a6035d4578b095bccb4a2e095535bb71f1e006a21035269ab6ffb025955ac8ed2726cd6e28ce7a62de23e865304e9a34304338fe031cf6196af8130b0c5e5d82c5d64434741d8ba02a7a8acbb755b215e4bd4a1752f79c53e89cdb813da915644042165d9c36908ceab3488823fe09c62c5ad5d976035394c41409369203886f5d40632badb447555d12701de7042caf748839b97a00bea9d2bc25cc5923b62b71097efb415822a14577628904d7db5f02b329e8201bb2add0cba4ed7ca8f25c52cf3dd1810a46c6fd85c92eabac5cf05a803d3b49ca34491e1c61a400e2020c009168084f02a961e263558a89a8ae7a317147ba30018cfad11201091bba52e4412032bb18497b6010b89e14d30b8863675c226b43a629c5be091c4bd910c6d1dc480ff44f726f605c996ff0641bf5657cb645f2cc04a81295310bb230b2b237fcd227f641b93900562c1dbb187e5c54bc1c5f58fe530d1c35eb13056ee270824d61e4e96fa97b1086a57591af497a7f1fada12407595c563d73dd800eb34232298dd76d1f032766c2b2be8b7d147ab399f911dd4c450a32c47171926c5405518675272e8b18a743dc490c11a6db5a0710f16096d61c62d59062ad2d45ce847cad9e112722b9871d6a001d9f54875f56d8fd4552c75c3e04e106b4501602a0f3b23942abaf77b81252ba267ff23d17e11b19be5c4b08b0120b08d606926dd4fff96f260d9082530a0a8c8ad6ed9c4a8a53a98e93282e1534f24c014307931680f334caaa76fc14c729f03721e0305377775f9105d66a4792a19a609b011871f0c802c52b6640731c9ad6b13c84a400c2c5a0f1b961e0be1ee542760e018d529d2bae5ec54186a0dcab979ce890954cbe6a951764b004695b29319b130ca2defc67d0d03b3cfe6d311cfb0edf8ae0abf6a9901c80e30540b53786be4702c5cb38236da2aef8d73233240516a2fa64e2d47d8b2e8807112b29925ae3625f8c47f097f948ab27fdd142e6500e3a2ec482a3ecb8ae81372216670109fba56cf10a66630dd8190a3412e465aa8b6e5b09f238aced5d23bcd6cedd8d11ca6eed16699bd6c0e18834082355fede069ba2c3b6acf495a9b95fe109945d16c15574ffba890600c241aa59c1ca96bfc69291b3a77c79768c09a01e761b31bba844a158c07c972dda5256f1920dc2c838242a98e610588126c2b1ed841c584790654a31f7d375f1cf084f09768893102a9667076d34090a6ed11867466202de9e4d6b6953aa4061044b687b77c2d8928a28a767631a445f0a831638bae11d873562be0408094d2772bc4322da160b7446dd722782147cb4dd13366736c7b689f0adc0d03026a2b2ae3abe14f217f2bb29da1c666736fc7cfed735cc754fb7959570780273cff49e2564ee6ca4005d31ac9b724769c4145c2be9f5e19e65526e6ec3079c72eef0cb30f7688e7f58923520a3c232e01d90d1f896650f21a69ab1e81cc401dca06eb2791bcb8c49c2f1b4cd2d8ab5eec3ef291762ba9b8be81de59f5a02a38ab00ed723d06299ba31512f491493a1841f8bb183a260cc1860c15604cb4069b8a517e7f24ea2d3d9d77eddbe2897492464853252f06da2ca07a5b70a7bb1fa65ad3b50386c5cf999674b969c3726b9fe69d8d554f993c879f325bb353a6dd618b829e05316bb735379f876915007fb86135cf8598a0218859a711d3eeb0c5a3cf83980d293e9d37d16bc52b65af8b399b3d54e187685312add610449019ce663bab603b13877b25835439f135d613f712fe7f262385cba74d2bbf6dee5fb781f2f90cb354023e4a36a768738886091f49b1a8e4b98cb463a4303c77605f83888c94771efde4b2a94836d9d4a60bfa22ec81abd9ce0312b16471dc1e2b8850731b18cf4089ed916fa990ee1cba11f85236ceed3c86d306a1b4a62363fe3cf853c6087554c39fb5e24ea0c2b2b97f917bde572a8e8a4f1dec6b4eab787bb0cc3bdf6632520db51ba6bc01881a9a2a908b01ab7a1e23ad79a2594c5b6345798c75e43297f730a4ef6ad8e3704bc13d4ee6e53d1313a1d4e253c0f8dddb85536e77cf4bb7a2019a96e731d05de97ca4b2107cc203b1392f2bea51cd07547bb8b3c3dc606225b87005ae7db3d33b8ed42db0956e9dc9cac8a87009b6b5794f39da40eeb173adc078c3592927500ad5a0a4c384eb03809400d11de731b182b208a6e926fe0080e606c5d7ad1d0bced806421aa695fca0a0d4dabe9cc7442413da5a11f06103e5c0c38a5e457054e1550ca574070297c06878733e9ba704d601aed5db0d585719ec28fd3893610e00abf66a81816e38b6c1ea027b7097b449d8e6413684a3cf64f802dd55ab753ce8ee3eaea1e0bf67c30d65e4405d5071392ccce4d9141641ad5ee68a6a0f2febc5bfce63f86a3208a257b26e5c6c6e750ee6a0bca5ed7bf703059e7cb54a634378630418f87c4443ed56512830c3c8e30edd50c2e1473e13e150e17037416ce7dcadc4b78433b2b4ea003d293b35eb09e6dff889b4e0bff3301925995ccd9b8976598816aad5dac399685e1e680ea707058f2c0f3bee2095e75c283911f5accd738ab6e4cae2b18733d93e6ced39ad97c006c8615d72d97bf09cc9488ba573f03c71b41707fa3b12f4d37b5f98cdfbc23cdcfbc2deb657ef9cc718c9bdd75cbcbd70a1ee632c3f55dd50ad599c4cef368dd424f893cfc5086833719026c9fb699982453282f7b53a132ba0a1fbabd49e8a9db2c7067f01ac002be53c17b5a0eb2e0186ec6a9156a40a20b14310517e176af113a959b1324d649a0dc311410b040beb9f892cab1dbd13304c4b891deef81e1e7b3e177aa297010b599e2f1c0b563f546e8444f94483b4766266026ea905b215f69ecf49b01658fed2d056c9b29aab53b3eb71e53c8659d81a78795fd1ee0950d54edcba93ce659cc69c96e56760421b969fc4b361cf82c41fb5a98be7916fdd1c2d13fa6cd853182825c2a9ae561f52bd118632e799a408189441114ad3f35cd8f25c8261c5b5f330b1ac20556dade24138299e20a077ce8294dc9be70201a1d98a42d146a8c0f03f139b8e07524fc5f2388b953219b696f5fd3e1779c403febc821295bd90a4fad9f44ca2c3dc37dbbf796123f7cdf66f7226631cf9ed310e3ab731f6b18d716e63ccdb18cfc57a33a7531335dbadc66903b43b1f4959fb7442f6eca954fb627b5edaa71fe3d8177b6c639cdb629f8957ac6571c8a9b26e5949e4e988c0873b97610e87706a3ecc7a8aa21ece269f42e969c05da79041732b0f3c9f14aa86b499daac4ef1b8f0c5eb20cfc431d6b86cf9a76c7ba8713db394c956ac5d5f8571c97bab77b811c2993026a3ab327a0a9e380fac6d7c897c1eabcd65cf36aeae1e256fab7d2ef69a20c1a85507677564f6b2378738939dc365beb57358e8cc764e6146cf3b83199fc1fadc3a887da019e84c768f77926c76e8a9ae20556272a0f358efb2ed9db6ed9db2ad773b97bd23841e8743c93880a0c0e4f03b3cc299d81a95045d430b6a3107d61a30c7bade259e89bb0dc899d62e72dd6036d80120249ec9fe06ae282a860c34deaa3336bcf2e3c6b90619f9ab363afb3918cabf67c3b51d1ff4d86dad58b9b8d552d20d60f59f6050d10635a30fea97ca923b19145a2ed3d87aaaf0eeaa27ef91c8b06b643f15b06774006cdbbd3e8c8c0442f700de30628095e2adcc67f01613860bef85acb1591dde49dd6f75e81aab09ae0efd72f47a5b9f976a45ecd1c7147d4c8655660d7a82a769a254fa972abb3ba1ac4335ef50a6a8cc169423ce4fd186504abf369e20c1fb127caaf138c2f4de973092437e58eaf32759b57e6d44c147144f47f48b2c923b715e5372f7753dbaaf737297472bf336a6f19d0c6c1e075653df863693bc3db44fae31a54f43ad460ebad9c23d0db472e0a9e735ebfa015c9d1e0093c364187e825afa950db8c3212bc0a7c31056cec498e60ecca05150a26e260b0d203d601e2d967558ae801570c0c35303104ac49070806a12d10f4225bba5af8b7d59bc7adece102648a878d57311c77204d636b573f1c7f0a870c4e91c7b6a685c81d311da5e9466384c30a7546d6d39fa8131db33890d9509379d65faa462c84ad626a37afb8dd5baf264acef006044303c847a3e7b1098e682be3bd635039c350dad021050a897aa08794d6bbd32ad668a93ac15e042649e496b948b6d7c26f363a9413a5b7f1e548758b5116afc0d95aa58ce79031a1059b4b4443a9f446361ef2a50572207712b193d5328941cf996c7b4bb465eb56dcdb9be01c448368812ee91d190c83e0fb122869ee810d9a17fca9f89fb2132e4b7a08601686368c883cd72bc7a95038a1decc320222cd659f52933621956d48664198afb7c3d1b1f254e06f763fe74b1f632f0610af2a23aba1f422ad78af4780a83cd2c3ea2788a7749aeb7757cdef90a14ccaacb9b421b90a9b5130a15a07b86f903542dfbf8b2ccdba75cfe5a88b234fa3b88b2a59c0997df01bef0cb17871f3e19adb7761af72e2e2823a121d3e257bd2d13a86683d35c28034f043d312ece8349fe41c091e139b061663f1d6cf7d41ae7db6374dce938598d170fdbd21e8498fb9693db874afecf049b268bdc8e4407116b06d7dec4d1121f8a1a466fe254e910bb956e4e0376dbaf0e6c8d3ee50020c7a72ca91c28a3472819ae2e7963c4fde24d19c0a73a10f059dfb4d40faab8ca9bc8edc0b17e29949ff6240742ca523f14b54fdfcc432ca1bf613a48e86f0aebdb91d498d3fc73ab1f27acee8cb027c2aa3564d6e79e68697d0621ef0916a4eefd783e3907209fa48c96da215b3dbe41fd4eaf139c9645864e75584fc322d48f37b7f219fc1ae1954eb4ed360fa7d91d955df54cf65ae71284da1b16afb468def00f107b1bc470f14e9a05487ce54b9972768cdda58532c7a29fd6baaf0b8aa48be0baebb55aa1274af86cc6de5109555b92a5f71ea4b17d8ef21126c3dd32f3064425c3b3a7fa064475ca0d9f768cb5fb18ab971bd99db31aa3f04647cff0ea1b688ecc33c9946b3d6fd6a19f20ecce598d71ba7015d9b27c269dd918770520a3bcad00ce658cad79b6944c5febdecb36c63351520d27ed5a86376f46adcdb0061dfe797687c25a4b12a05dcad2d07db535514b8b3b7aff64bfea797ea442fa3546cf1dd8fc32132d5c9167d36baa4bc93d35243adcda56bc73674db5d6493555745acea102551ba8c1db95da3772883c1162fd38e3e5d7a077c925f4aa868a08fa3ce3ba010bfe3c39a4cc9a4ae8d4535f8a489aa17349732979831aa7331c75958291ce3416c1a1a197bc94397527524b63399dd799786b303c13d218a3a76acd9c5c99f473f1d880a43ed2e266a2de9377c7791b8eb833d0bd53d35ba572683274bf09a51e5a563ea81d59d9b35de3e34f366203d6edc90d8ac692dcec21ae69435dace3b661bdbb96ca3d238851c41b44b177e411ef745357832591501df4a5eb09dec1cc9bf592d960d0258d55104740bf189cfe11e2f07654dd609aa67e5faceb3d9c027543d91ec0f4afabe5f3a089087e3902046c1e0129cc71c480db44fb243298ff12591cb71cdda0f30a40460332b756022d7680cb3bc8395afd00b45c9f6e28bf24c3e923f45e61c03b02cccf7a41a866a5bddfd00020bbe5c05147d03a926c9f40d8ee1d803468e57824f7e9f5a393eb33e92bd83a107e3aa5be16efd281eefcb6d8e8eab01aa27e31c453fcb1a3210d79d3062b7a23e0ee187e4c067b34f00c72022cc8e4ada32c892b4c5be5553656dc1a7390752699ab35a19c480b10f4f969684755d1838b3278879056707b64a2bb266919c86a6bddb028fadeb21adbe0fd9cfa8bd9d428facb3875ed16486ca1603bceedf34dfe2582c15a767cac6c583b7a250dec7aab67403b935f9c35f96bad240acda9e67fa8cde13843c83ff12c1a245b9ec7e1b1cea9c42a9ccaea08a925508d53478a8fa7d9dbba1d7bf301bfdc6bfd4bd85abd58f266719a12686af8e6bc35b3f1cccc60189f0350a0cd1b29f6d4228341aba3117bf00132050143246a9550f65663fa34798f9824d1760b3ac578c3926aa89c962d4ad6aa4ed6d8ac4991a741aa0868d74a837fe9aa502ad2da5deb828cc98a35f16a601e03bc6e4e53f2c223eb8d4181adc1dfde2b51f6f67f74eccd6929b5d646c65b57146fe4c9d6bac256ca9a3756f76d23e5c6bfde1d776458b7ad95bdb79f60cd66b014b44f90598abcf820c57b89595e1a3081adf1337c23eb7e635a267144e69bf79313743f1c7b53c86cbd2fb79691d5da9978d7c7e648b786796179f8e3d81e7906efbdb27dae8695096bcbb9179f871cb2372b645fbae26d2eebb684de9595d7ad83a2153f5a3729ef9cd23d811b80165e9cdf1d216a2f39be3d604c4e77b95a607151a5243cf62aa0d32a54ef6be9ad3e9b3711457f9fbd5da8352429616f0abaf5a6f5566779af6f3d5663b6635bd0719d36f1f875714d61ddd268df41c506e66dba3f4191436faa516a9d6f623b9614985960bdad8ead84b70c7ad9eeed9d3fb18bfd8e37850b68261c9bf7f6dcf2ec0d1069eb232c9bb8d93a78e2ab16790cd3be76d2c1d6fbe93a4672f14e9d0329df0cbdb20d7bf830e72ed31c376c2b493e6645f1d66dc7811bdbd60382b11f0dca736f5b0a6583ffde5abce7d42bddf919b04e6fec3a5677d67a462ded22bb6e26cb890928de29feedbe425bd7540a5b6110a2be9f804191bbd4b8fd9341ffc11914ad4bb8fdefc6a0adab21589b9c32e88ec9c14756f446cefd846167dcdaaff3de7119b6259813ac72e44f7613a26dfce9a6c58617ff7efef4b6bdd5fb1cf6ad597a89c716c8e5c8a2d85f636b078d63eed6ebdaa01737fe8c4706b54e679eb7e03ddd6d69c917f8ccf9b3751cb100abe24470068d1b83fa6291534ce2c6a1de3b8ebca1e406595eb63671e4d623baaa7f0a1eadb35897f07ff2e83f328fd659bdf1fbdf8747b7d8c1372f9e7ff2ac9d6ca5ca7569a3ee57f0a84c5ada440fde99d35c3ac393d34b9233cc3e6ac3e6d196366768232f9d2642be92c6b9e41fb5e9d8146dcb3f6a1e0ed1cb31d299e4dfb74c69475590b437edcb5b9a6de77a2e9d45a820cb6ff48349b969e0ab5b535674b96d9602086156ed70b9ddb31ebbde71babaa0226f138a46f887ec8dfc77118b9a6986efb2b85bac1cadc8fd349f03a32131ea471c107643dc44f771f34d58958a8b1b6b4047915cba0fb7d7c6e6ed64c827eb90c230cdc44fdfc55b715b7b6eca26bd2558f7e6638f611f9e798e697321d306a2fbe47078f6f2d593e5f5d5e3e7afbe7e71f5ed83cb6f1fbfbe7af6fdbfe6443c16d50493c6b27fe066974475d6a5674a3c6bfd8d410e9446a91be44099ac3c75f5fd834b92542e97ab1ffceaf6af959a2a2fa3d424329abf5366d717d93be9a7de09d6b5ba62eb4443d60f1840b891d8030a540d0e7bf526c94004888c8ef0de58b9c15f54a2d729c69e642dae359b1f80a6a10fd9329a73a87ae35a6baf34d0329ddc274bde4ca0a4f950d0e6cbc03c45e092950ce8e67ddc3fee92e3d694cc328c96a5d06f2e6fded319ff7b47f8a4c6e56eb12a6e5c4499b684323f6eb6b173ca99c7d2b32499a37ceae99626a96dd32d896f9ceeff495bf3a7dfd9e74d2fd5bb35e5c1bcc05f33fbd8e64a757b2f8f7daed0bcfada9ee8e3f8a9a7398a20dda2d7ceefe3a65f39bd02332df98699f24e6196139484f7abeebf07dfef9dc1ac4b425e058e1b2fe06f56eb59d340dc1a870d3b5520720d1dee3045354c6f6143a8c244477d159fe86e6051c01a869dcf2c9e652075441657153d154d38fa4b446b018423071427e99f6af036fbfaa33322a58d537b58e60852f5f7246788e61ef609fd7866842e8805551c71a057a2d16ea8c5038468af8df012758bb80a7aeaa16f480466664455e37e0eb2941294539fd97c49d5a934b68c826dc6c571ba39f49f9f7247f8b8e013483b30d7aada06e69ca473db4dffbb58329fbc992d370a629d7e8ac18e08e804c01156d275a40db4881e9f48c69066ed63676c331554e8abac18865252079a94c45e6e7b76baf3c6c205ee27e6d5c00e58c76b678b1a0b4e256b6c26062321ae0a680b30151a0c024c240dab6214e59640d39b683b52c40cac278c198a87ac951b7a18697a1b4bf17695e741131e2d545d48ec86500a02c1123a08647a28275a5ba0623804141865e0c3b018dacaa67c4690b6617ef46cfa66acd3fba0b3f7069916073993c9d7a9c7605d0d5df8a9fb16f950debd19701e629461eb71db213523418ff2ea6db006ba20a814180005a9ab959cce882c34601000234459a27a16092047a0989b45e0d7e1476d36b8b1a2f4457fd673e9cc4d288468a2ec3290e884aec5608e16c1f88cc852b56433ec37efce4cca326d9d6ec43070473cb3cc90224784a9a2bb11df2f40ae1db7ed7773f75b053de7eb5ca12eb29a4c338c58b275269fdefadd1acee83dd54885ad77ed2db11aef1e274300a932d240ca2d6f96e6b0a143b4b7d540627a30c4100b26b67399c3696d51f449c46d12f13889e8b388368b787d163f75f4c16127fa296bffb0bb85529b8d97ce89a5743f73a90cad1f7fe63abe783b6c9dbc7690c8d2736a94e7273c74d5526e98ea0d87ae4fbe63a543c490dab2bd6f51f83cc32861587ae93c97b1963130d6023bc3071b6db0f1dc062b452d611e23c93a1d698d2d760600bb6a59afd9daecaaf89b2ad7550f009a6d35a82d32a02dea11757534d1546a4011d728d38136abea45fd23027162901100138825072a517ff2a1d8cd81ee6930eb747c144ec67a1ec4f39664aadb570377c271a1a075910e5e4f6c75acc088f28e466a910163c7e836cec5a4862c5093daa0d260536f1dcd6b804d5d5637a9813905933a1c4d6ab7a8ed242501a041d37253cca48e629cb519d4d12dea0840b6ae921f09edb74c1fbc738274ddc666516f0675dc0cea78625047b3a8e36e51c7a3451d37933aee26753c9ad4d16d6a808ca1f4852bcea172efe296059e774d85960568aa03ab0fbb3ab85d1d8e76b59bd56137abc36656bb551dddaa8e9b551dddac0e6656c753b33aba5d1d37bb3aee767574c33a6e86753c33c3ba629dcdb076bb3aec767538dad5665687cdac8e47b33aba5d1dcdae8e47bb3aba611d77c33a9e99615d07a9599d18c09740679bc110fe0009ba6e6675c4c993e0bf81cba5de7601efda11c51315164de5a0ad0cf09675f8aa0d1b7ca67c885dd7a4af641d943994cdd01634036b2a4445edd5e635202a2981604706510de78a15c4946a59f17af4aa2624ac5f33d2cacb3aad72429455e0e865bc25523b44ecb7beda4117720a421a65d9ca2bc22b0dab461886488b534e29b14a6a883d07642b17b87ff45fd6d56120d6ac32aba77630f8c1b6a279a92a0965bdaa4a8d62c5554f7230ec42320f1e63afa2a52ccecf4a3e396220a7160bdc29a467f0ae0683d94a4569826aa86e30b896fae390df38e44cab11840c2dde68d1009ec51c5e9e5884d0b6d51aea0a7483dcedaa86b19d1859fb34941d07a01cd502196bb4a2268edd9a096f7e5352a525488c19c0aee408da6e1521c0c935842b31d83c8c5e2c433c4eb811947322e5357283579363c5e91bf487233383e0c8c65a235be05e6d28207d82dcd1c95d55bb9a3185f6c2142547c2be026175ed504061852fdd0c38e070714df521771da54883f4a9aa902b62edc75df021d180f7644ca431a8dff1fea4a66295465fdb8c1d1aa8b548d4b03d8aae8e5e3f6c9550be9f6a186c7d4e0bae44661a0ff5aaa9a40af6c5c1135edcae57f72e2e1e72613c300312e2fdbb68fda73f701ec2aae6a17c5d01551a8e1553239ac16e1d6f507a404813e99055aa802b36510bd82e64358c96865256490d6125ec1caa5bbd2e37d7cfd90cf719bb4a811237795094d5bdf0a5ab5103390fcba8fa53aada99f5191d4c419f0e4ae56089bef045a9d4817d1587c1cfb1d7f5ba1550f53146e950c1f449f79801fac275a546054ca9aa2ac7ecb21c81cb4c3a3666734995359b5304855bddac320adb340575619b3dc38e871c40a1680df43bf25d2a720e210a2c49d18b29a3e52f4ae203321aa1fd1a248ad80f4e7bf13067a2a0b08fd8e0bf3a5427421e1cd9e48e037516544a75f7ea36f8e05057a72303bd903c09d1e44577ae90a18d5402b24b52b68a6db6cebfcd4c0db8eecc110390b711dd64357432fc5eb776732a46200c5d375514fa4928f8b3174eead1ce4a62b0fc367beb2baed354bbe661cde8918cddadd72570635cef2cfe1182280f99777d726e40d7550e6bae82dc7d0c4f166dddbdcf66c065aa08d301fb787777f7b5f17e7a23b20346bdf7adb80c7e02353b86d51e9fc730b9d13fc2302bcabf7b56a31c6609b0f619e272335755229e891ba214b5546cb8711f6fdcc71baf8df777f7bff9fdbd7308602349a10669c3dcc3e7312680a14a173b5bfdeefeab37dffcfedeff1f0000ffff5fe69651a1010100", "b1d50cc99a0abc25e4ad2cccf01cb5eb": "1f8b08000000000000ff7455df6fe3360c7eb6ff0ac24f49e0daef017a4071d71f03b2b43867dd806168158b8e8593454d92e30b8afcef03e5b897146b5e224be4c78fe427ca8afa87d821883a28323e4d5567c90598a549b653a1edb7454d5db9a36ddf34425379facf3e3b47b33f6469d290abd17b0dff6fd50d57934596265638d169daedd07d6e7f66f421786f1c698db2f458f70eb3749ea66509b7eb67501e7a8f1202418bda821f54a85bf01882323b0f5bc1a7646068d1218416d95358ab552db8228cb0456576e07a53c0376c44af03ef6612f7a8c976684256a47be162c46be00a14f71866d9fde3cbedfa39cb2f6de7d156580b8b537ac58db591f28db50c3d92115a83a33ea0076124744a4a8d8370080d3938b9b2976fa9d712b608121b655016b0699567a4d02218747b841a4d4007d4c0817af721cb222d4bdefa4e3dd7253f0b96c3ce516f7d0e18eaa228800948acb5702861f3f804575fe0dbe39f6bc618e376288c071523819012c439f940f02aac7d85856802bac5098c4b2c182286cb21b4228c6b1894d6b07edc402bf6381e181cce30395f042fbad83d4edbf5c8a93af4d4bb7a221c73f5203c0ca8f594f46f0184f674a21de1a7b23b84bac5fa074a502616939c44c7abc3452162f2af1557fa4e69f4afcc42c0d79bcdd787ab9bd56a44ccc113a830354ce8411c585eec6cb5a85182163e4cb1a2cf05f59cb9ab3056c43adca399c832c67b5b6265d9301018dca36371d4822f499136bda95969b3f98500e12d4d541375797d0d4669de48e2e724b6628dc36c5a3fda48898d925bb35fc2f4bb5d3fe7e9b8acd07b45662d3a5c42f6f2f656900d9ea315bc5770ad8ec7173f9a65799a24c7799a2609df853e50278262da07702895c33a665455ab9159f187c7599c2355b59acd27cf15edc0e1bf3dfa00716a6040e761d6281d172cfcc3bc38c3389b2dc5d3e4b18adf1194edee6f37b3accc7278a00e1f84919a0f93639a260e43ef0ce3a6c7788f274e63a3a6e38b5bc0323b9d9e32130694a9a98bc366a41fe5dc7023950743011e369ba7aa80ac0dc12ecb127f8ace6ae42998c1f59771df7f3838bb98bfe24b420f8b85a1b058001ab1d5c8752de26ce10971311e604320299266b001c1614d5d874642efe3d505ebe8e761091383f7d95d287e144a49b52fa3cda940d0914350a621d7c52867be9fcef67254efaf9ebf4bf3f7f7dceed8e2edbd2bd33b7366311bc1ce255c55abefa7462c2715f33dc8ac23d9c7c731cab3aa564f9cc4030a89ce2fa113f66f1f787cfd33febd657f5ddd911b849328af9e1c05ca96a7ce64c73c65851fd3ff020000ffff0e7737e578070000", "b928bc0be77a213dae14bb2edc434195": "1f8b08000000000000ff010000ffff0000000000000000", @@ -84,20 +86,18 @@ var _ = func() error { "ce502e4fca05fc0a18b16191ce2d7ca2": "1f8b08000000000000ff4ccbb10ac2400c80e1d97b8a583af41cee01040717c14504dd255ca31cdca562d2c5907717ede2f6f3c16f062fe407418f59cbc4b0dd415a52dcc37de60c030a6cf63fbbcc4529c295446f667d626c94ce28196b7993fb1797fb5f8708165628e980a50edd695238b667a546ac34aebb183c98118feee1130000ffff2bf5ff9191000000", "cef5ad5009e91adfaaf82d3b38c0c2c2": "1f8b08000000000000ff2a484cce4e4c4f55c84dcccce3e2cacc2dc82f2a5150b251b555c82f2829d60bc8294dcfcc0bc84e5750b5d34fce4d51e2e24a2bcd4b062bd7d054a8e6e24cce4dd173ad484d2e2d49d5d0e4aae502040000ffff0bec043151000000", "d37116f1e151db4cb9a9186baa84af28": "1f8b08000000000000ff24ccb1aec2300c05d0bd5f71d5b73c8612b1a18c4830b232a2d2baa9456223c711e2ef11b01f9d3f9cd450d4082c8b5a199d55a08256591278b71754a288d5fd516308897d6db7eda425084ff72aaf992c241d3eb41bc073c493f2a485aec9889c257580db28357ff788fef20370c5a12dcb9815ffc7f3a6efde010000fffff7ca089490000000", + "dc08af8525351f73b344bfdd98b50bf3": "1f8b08000000000000ffb2c930b42b49cd2dc8492c492dd6cf4dcccc492d2ad6cf49accc2f2dd12bc8292dced0cb28c9cdb1d1cf30b4e3e2b251b555a8cc4ccd495150b5e302040000ffff448386763b000000", "de49d3bbef3b765f3375df97e6190d32": "1f8b08000000000000ff4c8fcd6a14411485d7759fe2d810e906ad21b88b8e9b210b3722a80f505d7d7bbab0fea87bdb6408f3eed21367c8a26a730ee7fb6e75fe8f3b327c9a8842aaa5297a32dd9cb423d315e9884c770cbaaca3f525eda4cef79f76be8ccd753410ed7668a5e8214d685c1b0b6715e8c2189d307c49c9e5094f0b677817234f780aba9455e1f209b28eff2b427f5dbb6dedf1fec2b087d7f485cc6fe10700ddb8ceb38be5e397bb3d4a55b13f97d2f4bb4b8cbbafdd073a5fa41e9fd9afca70d3247031c22f214e571f81968be4c6bb496e4f580573744781abb595da82538e27bb8dfe5a8220c8f590f184e442b6dbd70f16df1425c71332f32b6171b57246c99edf020f69b234afd95f2dfb012f64c20c6e0d0ffb5be9167fbe24eff6c8216e553327b53f5ac81a73cfad0d644c11fbf81cb4bf1fc89ce94cff020000ffffea1157a3db010000", "e2475e65981b98fa738efc3c4b639c69": "1f8b08000000000000ffac8e414b03311085eff91543ee9b6dab450888aed89ba0d8f5bca4cda80be94ec8cc5661c97f9708ad16f5e6edf19837df575595f2b8c7407187835805e07b17702b1622b1bc24e4d239711bc768619a0c4561f390f0b97fcfb9fbb6560023633a5946c7fc46c99f94afc46261beb830333333f37246142c2c9512e44f8b318502d3d3a473c6617f9f40b7ab75dbdd366d73d3ac57ddd3e39d067df86aebfa180fe1fa48b0cbf3b345fdc3bdc0ae98c38e3c5efa9edd26a0ce59a998c88f5be969f8cbe53f35be68bfc97c040000ffff94a186dba3010000", - "e2b566d83e49c8c902967a5ddf7f8f42": "1f8b08000000000000ffbc544d6fdb300cbde757104633a4401da3d74cf15034c150602b82ade85d899858982c1912dd2c13f4df07f92389b734b7ed628916f5f8f8449209f9061bc59d9b2715df615a201768937c04c08afbdcfba9a9c84dbf1a816afad99aba0a8165c57d3e6299906ff988d5aa0750d2515a6b470785021a4b6a2535b6704ac605808de7a0a4fef162261af77d84675ee2f41b3a53db0d86b0e2544c6eefc037d83348d6a4614d3aadac2cb93d24e1163c8c5b4480478b9c109e710f43ca2b6b2ab421749121b4775816d9b0ac56f968c488af15f659b446f34d1d5959a168f953d426eebc07cbf50ee1a682d91cda700f44d641da45f21ee4167474993e9ab234fae5502124843f29397a312a72efa34f93fd8abb0d57f21742d4988abc87422dba3b03a305f8a0d7aefad8fbc7b5a3c9686dc4e1a4f9d658980cd579e5f6913bfc2ef54e6108b720355cf458a9da7215c2b9e68c6cbf3d2952be2bc95096f29a2e2dbac8236bef6fae309e7a1fa186f285f8c82c23919f073ed7edc28f36e2d10018b446ad546ae5aea0e4dc6550cb8342fe836653cd1e062e2b6e79f9b408617659f2638a4f0b08973a41eaad49ee203ef20c925789fbd814e37709a2903464d0f5c63f61b7e7564bbd3b115c0a49d709fe770545ac599bdc412238f1b4442a8c4866902c965f962fcbe3c1c6e8adb4653c79b008075383ab2d7e3a25b74047d61cfecaaf1b9227f354632cebfbe77c2c753dcbb26600c5e1745686b14bd20d6aea27f4780e15df49cdc9d849b793463724bad0bf030000ffff7c6741bce2050000", "e4ae59cf49ac7ffea86ac8585ca123cb": "1f8b08000000000000ff24c8b10ac2301000d0b9f71547a1a04bf203eae6262e7e411a2f6968930b978b0ee2bf8b747af0aaf3ab8b84a7e98c5cb599c7c2a2779709a70b40ca9545718c49973e1bcfd9469e7b086e634b2f2ada4680d08bc75b6a4ae540b8b7b9fe392289b0e007066bf1c9f866596110d22e054bdae00bbf000000ffffa4aa3fec83000000", "ea7821493d786621a392d346e687f744": "1f8b08000000000000ff7c8f414bfb401047cf994ff123d03fc99f9a20de8a15a478f5a078120fdbdd4db2b4bb136627f650fadd25d58bd07a1c78f3decc68eccef41e363aa2104716454545d9071da66d6339b679ec6eef5acb5b3125d5446d8bfbc51a3c6a6e5e07167d36d163f1b0890ee247f1d927cdd0c1633b759dd9f3cd451e966334c9d1a791ebc635fe9dd3cde69b3e52f196fd0a40f9a7bd5c52719e572895799fd1b1e0c0b20ba9c721e870b939efbd4ce969856e4ab6b2d1e1ffaf039630d267bc7f649590fa1a5e8405472a0af13a49420a7b2a4e4b3a11cd0e8414b4aa67429875135df3e8dc8fadbaf6784d27fa0a0000ffffb89c31799d010000", "ec8652e62d2eb70a8198fe338e649eb2": "1f8b08000000000000ff94544d8fa3300c3dc3afb0345a69f740c54799a9d2cbfe95405288066294ba2ab3abf9efab244009add4ae7273ece717bf17ef6ad4c4959606fec651af747255825a06459e0ee331fe8ee35672e1af2b5e7f36062f5a2435766818bcbde7bc94f21847031742e98641960e23f8e2a8c23139ab3f2e5ea111d224157ad45d870d82ea1b0b3cf53ccc2d77a4a8936768337b7b424d164632283cae8b5ca56a5ab2b1f4184713a16babc8d2e9b969944e2a24c29e4156b8ba294a383028b7bdf2a55788bc6a9f1d1c8c50e7a1e35f0c94ee949649d561fdb9c0334803606e7137f4488e940859a3e1a45033b868218d050b4a9513c593369e93a37d5faf7153ba13585f7aa9c925ac703a792206f9617efef952b992072c57ef59e95b0ca38b3c7043ce8b725fdc8f7ff1d2ad5b5b6ca4cdf37b69f74e8070acc42b4f76adcb7ec277973b9f42158a2f2003249c79bdff9cf6e9d6b09edc09916caa9b2eef54a319b8b1dffcf55697f63cf4e002b156fced50d9f382e6b5d4248d145b063eee727ef752280ebceb806b013f7b3ecefff5e3231dc65fb636fc3cc188bd79968166a59512ca49d0ef272ddef72fb4289eb488c2ff16a8e8e9ad72ee4d1cbad84bf7947859bc403c0d89af19bb5565f317cfa4ab8b6987cd4b2c4bd31ffff588a0f16a3745b73d332f18fbd07f010000ffffa680b9a8b2050000", "ecb1546dcc0221b6c0b61a1b5a50e58f": "1f8b08000000000000ff5c514d6edc3a0cdeeb14df5b3901fcdc7d16b9442f60ce88b2d89144839262f8f6853c13b4e8ca04cdef5751fe834c19bf7a6d886c8ca6e052fb982235acb71e0225c5ad4bf22b225510d6e54796cda88996ba42025a64d0be27b95fcbeb6ed77d71ae97a0d67aa1c6e99cffa835cebb1ad939a32aa822f77b1c5fc1a13d7924fdbaec64e68653fb0c2a1ecd0638f30c8131a574becedf64fa624426f3d8543d5a94b2d5f77118e94975636c2a655bf0f1e69c84413b19a3324bd9901952c6cefece328f700555335f94886a26b711e67bc2613a7ed0be73610fdf6d1cfe53de0cb5c10ea3026938a4c5abb8f57fbf22241abede9d33dec87ce25a67d478851ba8bb6606dd4d6b1d4e139d43836edadb8cc09c108cf92ac973e2c6c8bc40da54a18fe512d43235c46e6dc1c129cd6399658b0dcf2ed02bbf1c85a7a3d19ebf608fa2c7e29c4c2921f1287400be335446a0acbd62276bc3d8a1e6eb87739f9ff8a9485ab6d703462a8f8aa0064ae9520b52a3fb1d0000ffffd31e584a8b020000", "ecdf6a3b8924ecbd21b3179af40db25a": "1f8b08000000000000ff72c8cc2dc82f2a5150aa4bcacf2f292e294a2cd02f4e2e2ed68773f5405c256b2e844a87b4fca292c4f2d4e2fcdc54fdb4fc3c185b37ad2835551fa4393127472f37334f0fa213a135a9342d2d31275f890b100000ffff3e8ea61f77000000", - "ed86eff8c23b4590459b51a97a1087be": "1f8b08000000000000ff7c8ec14ac4301086ef7d8a217441c18d7a2d6d61d9931711ec0b24d9e95a4c9398996835e4dd655d1441e96d0efff77d933344e58e087580a603e90393dc3147826d2955ce308d802f5007b9f7f3ecddf01e1004e3c2e26bd16e3a18e5800bef22aa411d2f44ce7590f76a46f9a0c8283b7d6029e20a72f46fd4c0ed4db9844d7f72a3255ced68efedefcefe09cdb3f6cb7a273973dae1a1815159c2bfbdb3edce85c42baa1fcc1dbebffce7ac5a9d98bd0363155127343bd0ecb6948c412201d15bec04253d4f2cfa47f58aedf519e9abcf000000ffffdcd8bf6980010000", - "f16f61516506d3e11502bc1ff92cc0be": "1f8b08000000000000ffa454416fe23a10bef32be659428243f0839efae444aa047a1c5efbaa8afbcac193c46a62237ba0addadddfbe3201d681d0adb4a7d89ef9bef9c6f3c5a242a9d0650300a1f40ed6b5f43e656b6b486a838e854837e6eccbe1f41c53278d4aa61016be4966fbc5ab4f6650dbd29e30004242e5b0489918a6e0aca54749d5680cc38c6542372578b7ee094aef913cd78d2cd1f3c039f1bb9281ac29652c135c9e6471a5779f68bc3d6abc3d6a9cfe0da4a9461fcbaca659104123f682f5da36f8ad7488a44dc9821ec1ab699c3dfbb5897aac8836fe1fce4b4dd5369fac6dc34b9b6f8b42d6961fbea1eda3c442e650c8a44d67209d9649a595429332725b0c8dea0cbe421bdd48b89358a0a866c782caaeb70d1a92a4ad61577b08b58e0526daf2aee62039b7f6f9bae0795ce6aab26872a7e5613110fc68d6419f1ffbbc38ebf1afdfe6fb515f3171d7f8ed5ddd64732cb441054f764be805af6e3e53dce52499d79838f41b6bbcde4585f7914e1ab4c99e9cdea08a455068be331d7240f84a89ac7569525663419df1ed41a7c6d010ba4079bf582dff9f0b4ed54572f678b75af6471eeeee17fd91e5ddc3fcbfc5d379507072f18ccff40bcaad7acb0631629842611d8cdc18b401b7bf6a7887e1794dd73d0847eab2cfb39c96df4dee912aabce49f70a550f6f3f8d2e6074a2fa2b05f6ef62c5e0e303dc243c57f02305f6cec6f07e810670485b670e9917f1ef80b5c7cf80b536cf2b3b6af1e31e823f6bade57d900d7e9d48acadc2ac452fa55135ba0381e06de802d8b54728dd2a8f1dd33ae4b40d7f46ffd370fc443f5d612db10c84df4893c1a37d09a680fced778f5abc0daf94e02dc3a1c4cf000000ffffc823a11b30070000", + "efda84e11c1028891b0525cdd6c9ef10": "1f8b08000000000000ffa454516fda30107ee757dc2c2181b4e0419f5a39912a81c6c3da5515ef93832f89d5c446f6415bd1eeb74f26c012085da53dc5f6ddf7dd77be2f16054a852ee90108a537b02ca5f7315b5a43521b742c44da31679ff7a7a79832aa543486b0f05534d92d5e7c3481d2e6f6880110120a8759cc443f06672d3d482a0643e8272c11bacac1bb6547507a8fe4b9ae648e9e07ce91dfe40c6449316389e0f2288b2bbdf940e3f541e3f541e3f81b90a6127d5366314e82081ab0672c97b6c25fb943246d7216f4085e8c9bd993bf9b468f05d1cadf709e6b2ad6e968692b9edb749d65b2b47cff0d6d1f246632854c46753a03e9b48c0aad149a98915b63685427f019dac68d843b690a14c5e45050d9e5ba424392b435ec620fa1d6a1c0485bded61c24a7d63e5d163c6d96b9a8ac31b9e372bfe8097e306bafcb8f5d5e9c74f8d7afd3dda82f98b86dfcfaaeae922966daa08247bb26f48217571f296e73924c4b8c1cfa95355e6f1a857791561ad4c99e9c5ea16a8aa0d07c6b3ae480f0852259eadcc4acc48c5ae3db818e8da1217481f26eb698ff9c0a4ec55972f270bb987747ee6fef66dd91f9edfdf4c7ecf1342838b9e68c4ff40b4aad7a4d7a4d443f86cc3a18b82168036e77d5b085fe694dd73e0847eabccf939c9adf8dee900aab4e49770a55076f378dce6070a4fa1203fb3e5b30787b03370acf15fc8e816dd910b667680087b476669f79167f072c3d7e042cb5795ad8418dff0adb708f377bbaf76107e1ffb55a13dfcb0a3f4f2496566152a3e7d2a812dd9e40f03a74066cdb2594ae95371d543be6b80d7f4af75371f8347ec2cc5a620908bf92268107fb1c4c02e9ebbf1eb9e636bc5a82d70cfb127f020000ffff0dbe9ce240070000", + "f1a742fa26b62730d7736bc2bdfac3c1": "1f8b08000000000000ffb491316bf3400c4077ff0a213038e03864358e3f3e921632b4189a76577c17fbe8f964e44b4a38eebf17676849876e9db43ca4f750a5cc055a4bd3b4c1913abdec35292d58270055bfae1f94f11042c1a39f8a2756da168df0a825c66ad5afeba45a2973a993a44a377062191e59b27bfe8d644b937e31aeb33ac61c02b5deb02bbff63ed3a07f620df93e0bf7484342c37e176309bf9e28f63b888b1c06ed7b562560f37ac0b88000e9ad2bddc048e20dd90c43284e6cd51cb49afd8bde0f1617dfa435eefdc0d95fbb86db134ac0a37770f46ef941e28ceb300754e469d9b23b1919b004fc2f1aae7c86e92cfa1fe67064752d01b7e45a6de7d0b44eaa14e23c3f030000ffff4803cb13e1010000", "f565bf21889ed8876e21065a9a977d2b": "1f8b08000000000000ff34cdc16ec2301004d0fb7ec5c8a7a4aa927ba59eda5ecb851fd898b531246bcbb14108e5df5120ec6547a3274d627b662f605b42d499284c29e6828600e34339d6a1b371ea7d1caa733cc6fefdb3e841b2a196e8c219191fafa6fb531f54885c558ba0a1342dee04647c6323ff726db6b84bcfe115acf72b8eeb587ea216d1b2bf25f982e194c6607985fd698e6a3e09585a5ae8110000ffff7d25ad33bf000000", - "f66368e9dc94454a5dce0ebc39c1ac7a": "1f8b08000000000000ff7c52cd8a1b3d10bcfb29fa1318fc416686dc72900cf9bb267b302c3985b6a667d56b8d24a4f62c8ef1bb87b16cafc3929c24d155d5adaad6ff7df9fe79f3e3e12b3819fd7aa1eb01a01d613f5f00f44882107024a326a69714b328b031080531ea857b71a6a7892d35e7c73be0c0c2e89b62d19379afee85acc35c488cdacbd07cb89684c5d3fad37e18d04768e07884362629edc794da6f3852bb9911fc8be074d25d852f008ec706788010e50effc8e21e699bd0eee074aa0d96068a1c3c1547241b7c5aa96d6dd6da52d4ffb0bcaa51e8ff41c2943c5b148ee19ef8a74bb6e4a1499871bcf309f7e228085b96c34f893b0a0ababf702fe51b771ee42d1f96eb5709cf610799bc516c6350e0320d176229240f286ea578c4272add80d30c6ad9c6f307ce21e8ee1ab9dec6feb05e54dd9e27b01e4b316a1e073950be84560d4a98e7ac576af0585c3b2fd0ab2b157260f2fdcda8aee7e9aabe34f08c13169b39bd35f8f9e6afeeea4cbaab0bfa3b0000ffff85cad3beb8020000", "fb34aa975abbcb40d48be167668d4187": "1f8b08000000000000ffd2d5d5e54a492d4bcdc92fc84dcd2bb1e2525048c94ccc494d2eb152502a2eccc92c4935560209269624262516a75a295457ebe5179414eb05e5e797d4d6c6c3b80145a9699915b5b5f148a6e9410ce0e22a492da686d12063e0661614e5a794269764e6e751c164846130f301010000ffff301e0ded19010000", - "fcdb09ddf620bd512f46a230d266540b": "1f8b08000000000000ffb492516bdb3010c7dffd290ead8516629bbe1ac5a35bc2286c23d0b2f74b74b54565c948724b26eebb0fdbf146ba32d8608fe6effbdfef77482afd0c078321ac458f0de52da1222fea0c40b637754a85eb6328be3845a6d879d793677e77dfba1759b63775264ba59feb2c9383597a8c0e311f6c8847430aa62f6d8db634b71a7df6e31ce53a5237e500f2720d46dba70777b5acff8a1d15dfd07fc4403b337834cc3b8cedd5f50ad2d45681d8470bfb68736d1f9de06b48703917027cc0c3134407680c9c2b7df26ee8994f8b81e719591afdd7b0a4743c035ece35912638cfd06377b761ae5e019d2cefb56d0c3117771be0b72c5fd05b6d1bb182bd53c70ac456e9386affbbc05bd75e38fe8b8342db90172b100a23e61dc5d6295181d86c3f6f1fb63f8383b38fda776372eb098e6e8030787aff4b7e43217a777ce52fcbc1d4599612f871135cf450ad6126bd8dd107c89933d94f1363816dea94e0a25ffcc2018dfe4ec02ccb535e4d174be9e24fc229fdd6c1d3d392655f8f3c64d5b43bfb110000ffff8729a39981030000", "fd59f9c3d2c7ce0c05d1ff0f2c3cd0a5": "1f8b08000000000000ff6c8dd16a032110459f77be6210165c28e6079a40e86b1b02fd02575d235147744c1f4affbd74699616f27461cebd738a3657ed1d9a6401422a5419250cc207bef459194a3b4f735f161d6977cf12bb0fb9ad69926d0206f13cee910a37755ee1f9ea713c0898006ebae2f1a643d47374b8c7fb4a9ddcc7769713c0d2b3c19003cb093f61d8983a5a2b452562f1849be7fd42954f3a391c0f2fc94e7f07afa1b1cbf261f717feebbf51cf2c7f0ceba72ff80e0000ffff4170c27a17010000", "fd8cf2902df93c6d983a9dd3cf7c039e": "1f8b08000000000000ff4ccec14ac6301004e0b3798aa1a71624fdf111f4d2b33ec1fee9260d26d9b2dd8820bebb0839fca78161f89893c227250605cbd22ee7723d450d53ca76f4bb0f52d724f71e231559474ecead2b36a9bc51db0b2bf205c2ce917a311ca334c1c5fac5e8e7ff9e7048659c94d8bbd85b7814e68081fb3769c6dfb6805545f1e39e94ad6b43f0efdc76d6f9e5767b86fa0fd3dcd23c6d5c8a20aa54bc8e83cbe27edd5f000000ffff9034dbfedc000000", }) @@ -194,7 +194,7 @@ var _ = func() error { b.SetResolver("actions_header.go.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "249b50674fa80d5d2389e61231cdbc08"}) b.SetResolver("test.go.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "ce502e4fca05fc0a18b16191ce2d7ca2"}) b.SetResolver("tests_header.go.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "1aab4f3df928dd93d41d28e4f6a15660"}) - b.SetResolver("view.html.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "44a6873412ed570728aad35c300c999b"}) + b.SetResolver("view.plush.html.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "8086dcc0dc8cd747b27caae0808d1553"}) }() @@ -223,7 +223,7 @@ var _ = func() error { func() { b := packr.New("github.com/gobuffalo/buffalo/genny/mail/init/templates", "../mail/init/templates") b.SetResolver("mailers/mailers.go.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "4458f74dae2e5b725e2ccf002ce9ed98"}) - b.SetResolver("templates/mail/layout.html.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "7e4ac7be867ba59c2d5b2fd5252a4c06"}) + b.SetResolver("templates/mail/layout.plush.html.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "dc08af8525351f73b344bfdd98b50bf3"}) }() @@ -235,20 +235,20 @@ var _ = func() error { b.SetResolver("actions/render.go.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "593cbb702bb3c5a0fcbfa227df3a58f1"}) b.SetResolver("locales/all.en-us.yaml.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "d37116f1e151db4cb9a9186baa84af28"}) b.SetResolver("public/robots.txt.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "c7014dd1ea22c08568ecfba7316fca2e"}) - b.SetResolver("templates/_flash.html.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "5597b95c7800708f526fe349c8315960"}) - b.SetResolver("templates/application.html.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "f66368e9dc94454a5dce0ebc39c1ac7a"}) - b.SetResolver("templates/index.html.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "f16f61516506d3e11502bc1ff92cc0be"}) + b.SetResolver("templates/_flash.plush.html.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "617109ec9b8616e0de6f52cadc0ad126"}) + b.SetResolver("templates/application.plush.html.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "2b101e95a5f58f9db6a47dae28e04166"}) + b.SetResolver("templates/index.plush.html.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "efda84e11c1028891b0525cdd6c9ef10"}) }() func() { b := packr.New("github.com/gobuffalo/buffalo/genny/resource/templates/core", "../resource/templates/core") b.SetResolver("locales/folder-name.en-us.yaml.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "63b59db05ede78b10cb5f7da70d5553a"}) - b.SetResolver("templates/folder-name/_form.html.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "ed86eff8c23b4590459b51a97a1087be"}) - b.SetResolver("templates/folder-name/edit.html.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "32d6be02cb664211a2cdeac73239cf58"}) - b.SetResolver("templates/folder-name/index.html.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "e2b566d83e49c8c902967a5ddf7f8f42"}) - b.SetResolver("templates/folder-name/new.html.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "aa381894be941a89d61176150f6fd4a0"}) - b.SetResolver("templates/folder-name/show.html.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "fcdb09ddf620bd512f46a230d266540b"}) + b.SetResolver("templates/folder-name/_form.plush.html.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "a4145ffd5413f8f3115dc808cae80c3f"}) + b.SetResolver("templates/folder-name/edit.plush.html.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "f1a742fa26b62730d7736bc2bdfac3c1"}) + b.SetResolver("templates/folder-name/index.plush.html.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "6b9404501bcb97dedc55c936193973c7"}) + b.SetResolver("templates/folder-name/new.plush.html.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "6636bf271e9c01d1d5f067708b9de426"}) + b.SetResolver("templates/folder-name/show.plush.html.tmpl", packr.Pointer{ForwardBox: gk, ForwardPath: "a3279e1c13cbf42277bea34ba00e2d17"}) }() diff --git a/render/auto_test.go b/render/auto_test.go index f7b38caf7..8ccdc6de3 100644 --- a/render/auto_test.go +++ b/render/auto_test.go @@ -1,15 +1,13 @@ package render_test import ( - "os" - "path/filepath" "strings" "testing" "github.com/gobuffalo/buffalo" "github.com/gobuffalo/buffalo/render" "github.com/gobuffalo/httptest" - "github.com/gobuffalo/packr/v2" + "github.com/gobuffalo/packd" "github.com/stretchr/testify/require" ) @@ -26,6 +24,7 @@ func Test_Auto_DefaultContentType(t *testing.T) { re := render.New(render.Options{ DefaultContentType: "application/json", }) + app := buffalo.New(buffalo.Options{}) app.GET("/cars", func(c buffalo.Context) error { return c.Render(200, re.Auto(c, []string{"Honda", "Toyota", "Ford", "Chevy"})) @@ -41,9 +40,10 @@ func Test_Auto_DefaultContentType(t *testing.T) { func Test_Auto_JSON(t *testing.T) { r := require.New(t) + re := render.New(render.Options{}) app := buffalo.New(buffalo.Options{}) app.GET("/cars", func(c buffalo.Context) error { - return c.Render(200, render.Auto(c, []string{"Honda", "Toyota", "Ford", "Chevy"})) + return c.Render(200, re.Auto(c, []string{"Honda", "Toyota", "Ford", "Chevy"})) }) w := httptest.New(app) @@ -55,9 +55,10 @@ func Test_Auto_JSON(t *testing.T) { func Test_Auto_XML(t *testing.T) { r := require.New(t) + re := render.New(render.Options{}) app := buffalo.New(buffalo.Options{}) app.GET("/cars", func(c buffalo.Context) error { - return c.Render(200, render.Auto(c, []string{"Honda", "Toyota", "Ford", "Chevy"})) + return c.Render(200, re.Auto(c, []string{"Honda", "Toyota", "Ford", "Chevy"})) }) w := httptest.New(app) @@ -69,21 +70,26 @@ func Test_Auto_XML(t *testing.T) { func Test_Auto_HTML_List(t *testing.T) { r := require.New(t) - err := withHTMLFile("cars/index.html", "INDEX: <%= len(cars) %>", func(e *render.Engine) { - app := buffalo.New(buffalo.Options{}) - app.GET("/cars", func(c buffalo.Context) error { - return c.Render(200, e.Auto(c, Cars{ - {Name: "Ford"}, - {Name: "Chevy"}, - })) - }) + box := packd.NewMemoryBox() + err := box.AddString("cars/index.html", "INDEX: <%= len(cars) %>") + r.NoError(err) - w := httptest.New(app) - res := w.HTML("/cars").Get() + re := render.New(render.Options{ + TemplatesBox: box, + }) - r.Contains(res.Body.String(), "INDEX: 2") + app := buffalo.New(buffalo.Options{}) + app.GET("/cars", func(c buffalo.Context) error { + return c.Render(200, re.Auto(c, Cars{ + {Name: "Ford"}, + {Name: "Chevy"}, + })) }) - r.NoError(err) + + w := httptest.New(app) + res := w.HTML("/cars").Get() + + r.Contains(res.Body.String(), "INDEX: 2") } func Test_Auto_HTML_List_Plural(t *testing.T) { @@ -95,143 +101,90 @@ func Test_Auto_HTML_List_Plural(t *testing.T) { type People []Person - err := withHTMLFile("people/index.html", "INDEX: <%= len(people) %>", func(e *render.Engine) { - app := buffalo.New(buffalo.Options{}) - app.GET("/people", func(c buffalo.Context) error { - return c.Render(200, e.Auto(c, People{ - Person{Name: "Ford"}, - Person{Name: "Chevy"}, - })) - }) - - w := httptest.New(app) - res := w.HTML("/people").Get() - - r.Contains(res.Body.String(), "INDEX: 2") - }) + box := packd.NewMemoryBox() + err := box.AddString("people/index.html", "INDEX: <%= len(people) %>") r.NoError(err) -} - -func Test_Auto_HTML_List_Plural_MultiWord(t *testing.T) { - r := require.New(t) - - type RoomProvider struct { - Name string - } - - type RoomProviders []RoomProvider - err := withHTMLFile("room_providers/index.html", "INDEX: <%= len(roomProviders) %>", func(e *render.Engine) { - app := buffalo.New(buffalo.Options{}) - app.GET("/room_providers", func(c buffalo.Context) error { - return c.Render(200, e.Auto(c, RoomProviders{ - RoomProvider{Name: "Ford"}, - RoomProvider{Name: "Chevy"}, - })) - }) - - w := httptest.New(app) - res := w.HTML("/room_providers").Get() - - r.Contains(res.Body.String(), "INDEX: 2") + re := render.New(render.Options{ + TemplatesBox: box, }) - r.NoError(err) -} - -func Test_Auto_HTML_List_Plural_MultiWord_Dashed(t *testing.T) { - r := require.New(t) - type RoomProvider struct { - Name string - } - - type RoomProviders []RoomProvider - - err := withHTMLFile("room_providers/index.html", "INDEX: <%= len(roomProviders) %>", func(e *render.Engine) { - app := buffalo.New(buffalo.Options{}) - app.GET("/room-providers", func(c buffalo.Context) error { - return c.Render(200, e.Auto(c, RoomProviders{ - RoomProvider{Name: "Ford"}, - RoomProvider{Name: "Chevy"}, - })) - }) + app := buffalo.New(buffalo.Options{}) + app.GET("/people", func(c buffalo.Context) error { + return c.Render(200, re.Auto(c, People{ + Person{Name: "Ford"}, + Person{Name: "Chevy"}, + })) + }) - w := httptest.New(app) - res := w.HTML("/room-providers").Get() + w := httptest.New(app) + res := w.HTML("/people").Get() - r.Contains(res.Body.String(), "INDEX: 2") - }) - r.NoError(err) + r.Contains(res.Body.String(), "INDEX: 2") } func Test_Auto_HTML_Show(t *testing.T) { r := require.New(t) - err := withHTMLFile("cars/show.html", "Show: <%= car.Name %>", func(e *render.Engine) { - app := buffalo.New(buffalo.Options{}) - app.GET("/cars/{id}", func(c buffalo.Context) error { - return c.Render(200, e.Auto(c, Car{Name: "Honda"})) - }) - - w := httptest.New(app) - res := w.HTML("/cars/1").Get() - r.Contains(res.Body.String(), "Show: Honda") - }) + box := packd.NewMemoryBox() + err := box.AddString("cars/show.html", "Show: <%= car.Name %>") r.NoError(err) -} - -func Test_Auto_HTML_Show_MultiWord_Dashed(t *testing.T) { - r := require.New(t) - - type RoomProvider struct { - ID int - Name string - } - - err := withHTMLFile("room_providers/show.html", "SHOW: <%= roomProvider.Name %>", func(e *render.Engine) { - app := buffalo.New(buffalo.Options{}) - app.GET("/room-providers/{id}", func(c buffalo.Context) error { - return c.Render(200, e.Auto(c, RoomProvider{ID: 1, Name: "Ford"})) - }) - w := httptest.New(app) - res := w.HTML("/room-providers/1").Get() + re := render.New(render.Options{ + TemplatesBox: box, + }) - r.Contains(res.Body.String(), "SHOW: Ford") + app := buffalo.New(buffalo.Options{}) + app.GET("/cars/{id}", func(c buffalo.Context) error { + return c.Render(200, re.Auto(c, Car{Name: "Honda"})) }) + + w := httptest.New(app) + res := w.HTML("/cars/1").Get() + r.Contains(res.Body.String(), "Show: Honda") r.NoError(err) } func Test_Auto_HTML_New(t *testing.T) { r := require.New(t) - err := withHTMLFile("cars/new.html", "New: <%= car.Name %>", func(e *render.Engine) { - app := buffalo.New(buffalo.Options{}) - app.GET("/cars/new", func(c buffalo.Context) error { - return c.Render(200, e.Auto(c, Car{Name: "Honda"})) - }) + box := packd.NewMemoryBox() + err := box.AddString("cars/new.html", "New: <%= car.Name %>") + r.NoError(err) - w := httptest.New(app) - res := w.HTML("/cars/new").Get() - r.Contains(res.Body.String(), "New: Honda") + re := render.New(render.Options{ + TemplatesBox: box, }) - r.NoError(err) + + app := buffalo.New(buffalo.Options{}) + app.GET("/cars/new", func(c buffalo.Context) error { + return c.Render(200, re.Auto(c, Car{Name: "Honda"})) + }) + + w := httptest.New(app) + res := w.HTML("/cars/new").Get() + r.Contains(res.Body.String(), "New: Honda") } func Test_Auto_HTML_Create(t *testing.T) { r := require.New(t) - err := withHTMLFile("cars/new.html", "New: <%= car.Name %>", func(e *render.Engine) { - app := buffalo.New(buffalo.Options{}) - app.POST("/cars", func(c buffalo.Context) error { - return c.Render(201, e.Auto(c, Car{Name: "Honda"})) - }) + box := packd.NewMemoryBox() + err := box.AddString("cars/new.html", "New: <%= car.Name %>") + r.NoError(err) - w := httptest.New(app) - res := w.HTML("/cars").Post(nil) - r.Contains(res.Body.String(), "New: Honda") + re := render.New(render.Options{ + TemplatesBox: box, }) - r.NoError(err) + + app := buffalo.New(buffalo.Options{}) + app.POST("/cars", func(c buffalo.Context) error { + return c.Render(201, re.Auto(c, Car{Name: "Honda"})) + }) + + w := httptest.New(app) + res := w.HTML("/cars").Post(nil) + r.Contains(res.Body.String(), "New: Honda") } func Test_Auto_HTML_Create_Redirect(t *testing.T) { @@ -254,21 +207,26 @@ func Test_Auto_HTML_Create_Redirect(t *testing.T) { func Test_Auto_HTML_Create_Redirect_Error(t *testing.T) { r := require.New(t) - err := withHTMLFile("cars/new.html", "Create: <%= car.Name %>", func(e *render.Engine) { - app := buffalo.New(buffalo.Options{}) - app.POST("/cars", func(c buffalo.Context) error { - b := Car{ - Name: "Honda", - } - return c.Render(422, e.Auto(c, b)) - }) + box := packd.NewMemoryBox() + err := box.AddString("cars/new.html", "Create: <%= car.Name %>") + r.NoError(err) - w := httptest.New(app) - res := w.HTML("/cars").Post(nil) - r.Equal(422, res.Code) - r.Contains(res.Body.String(), "Create: Honda") + re := render.New(render.Options{ + TemplatesBox: box, }) - r.NoError(err) + + app := buffalo.New(buffalo.Options{}) + app.POST("/cars", func(c buffalo.Context) error { + b := Car{ + Name: "Honda", + } + return c.Render(422, re.Auto(c, b)) + }) + + w := httptest.New(app) + res := w.HTML("/cars").Post(nil) + r.Equal(422, res.Code) + r.Contains(res.Body.String(), "Create: Honda") } func Test_Auto_HTML_Create_Nested_Redirect(t *testing.T) { @@ -310,34 +268,44 @@ func Test_Auto_HTML_Destroy_Nested_Redirect(t *testing.T) { func Test_Auto_HTML_Edit(t *testing.T) { r := require.New(t) - err := withHTMLFile("cars/edit.html", "Edit: <%= car.Name %>", func(e *render.Engine) { - app := buffalo.New(buffalo.Options{}) - app.GET("/cars/{id}/edit", func(c buffalo.Context) error { - return c.Render(200, e.Auto(c, Car{Name: "Honda"})) - }) + box := packd.NewMemoryBox() + err := box.AddString("cars/edit.html", "Edit: <%= car.Name %>") + r.NoError(err) - w := httptest.New(app) - res := w.HTML("/cars/1/edit").Get() - r.Contains(res.Body.String(), "Edit: Honda") + re := render.New(render.Options{ + TemplatesBox: box, }) - r.NoError(err) + + app := buffalo.New(buffalo.Options{}) + app.GET("/cars/{id}/edit", func(c buffalo.Context) error { + return c.Render(200, re.Auto(c, Car{Name: "Honda"})) + }) + + w := httptest.New(app) + res := w.HTML("/cars/1/edit").Get() + r.Contains(res.Body.String(), "Edit: Honda") } func Test_Auto_HTML_Update(t *testing.T) { r := require.New(t) - err := withHTMLFile("cars/edit.html", "Update: <%= car.Name %>", func(e *render.Engine) { - app := buffalo.New(buffalo.Options{}) - app.PUT("/cars/{id}", func(c buffalo.Context) error { - return c.Render(200, e.Auto(c, Car{Name: "Honda"})) - }) + box := packd.NewMemoryBox() + err := box.AddString("cars/edit.html", "Update: <%= car.Name %>") + r.NoError(err) - w := httptest.New(app) - res := w.HTML("/cars/1").Put(nil) + re := render.New(render.Options{ + TemplatesBox: box, + }) - r.Contains(res.Body.String(), "Update: Honda") + app := buffalo.New(buffalo.Options{}) + app.PUT("/cars/{id}", func(c buffalo.Context) error { + return c.Render(200, re.Auto(c, Car{Name: "Honda"})) }) - r.NoError(err) + + w := httptest.New(app) + res := w.HTML("/cars/1").Put(nil) + + r.Contains(res.Body.String(), "Update: Honda") } func Test_Auto_HTML_Update_Redirect(t *testing.T) { @@ -361,22 +329,27 @@ func Test_Auto_HTML_Update_Redirect(t *testing.T) { func Test_Auto_HTML_Update_Redirect_Error(t *testing.T) { r := require.New(t) - err := withHTMLFile("cars/edit.html", "Update: <%= car.Name %>", func(e *render.Engine) { - app := buffalo.New(buffalo.Options{}) - app.PUT("/cars/{id}", func(c buffalo.Context) error { - b := Car{ - ID: 1, - Name: "Honda", - } - return c.Render(422, e.Auto(c, b)) - }) - - w := httptest.New(app) - res := w.HTML("/cars/1").Put(nil) - r.Equal(422, res.Code) - r.Contains(res.Body.String(), "Update: Honda") - }) + box := packd.NewMemoryBox() + err := box.AddString("cars/edit.html", "Update: <%= car.Name %>") r.NoError(err) + + re := render.New(render.Options{ + TemplatesBox: box, + }) + + app := buffalo.New(buffalo.Options{}) + app.PUT("/cars/{id}", func(c buffalo.Context) error { + b := Car{ + ID: 1, + Name: "Honda", + } + return c.Render(422, re.Auto(c, b)) + }) + + w := httptest.New(app) + res := w.HTML("/cars/1").Put(nil) + r.Equal(422, res.Code) + r.Contains(res.Body.String(), "Update: Honda") } func Test_Auto_HTML_Destroy_Redirect(t *testing.T) { @@ -397,29 +370,91 @@ func Test_Auto_HTML_Destroy_Redirect(t *testing.T) { r.Equal(302, res.Code) } -func withHTMLFile(name string, contents string, fn func(*render.Engine)) error { - tmpDir := filepath.Join(os.TempDir(), filepath.Dir(name)) - err := os.MkdirAll(tmpDir, 0766) - if err != nil { - return err +func Test_Auto_HTML_List_Plural_MultiWord(t *testing.T) { + r := require.New(t) + + type RoomProvider struct { + Name string } - defer os.Remove(tmpDir) - tmpFile, err := os.Create(filepath.Join(tmpDir, filepath.Base(name))) - if err != nil { - return err + type RoomProviders []RoomProvider + + box := packd.NewMemoryBox() + err := box.AddString("room_providers/index.html", "INDEX: <%= len(roomProviders) %>") + r.NoError(err) + + re := render.New(render.Options{ + TemplatesBox: box, + }) + + app := buffalo.New(buffalo.Options{}) + app.GET("/room_providers", func(c buffalo.Context) error { + return c.Render(200, re.Auto(c, RoomProviders{ + RoomProvider{Name: "Ford"}, + RoomProvider{Name: "Chevy"}, + })) + }) + + w := httptest.New(app) + res := w.HTML("/room_providers").Get() + + r.Contains(res.Body.String(), "INDEX: 2") +} + +func Test_Auto_HTML_List_Plural_MultiWord_Dashed(t *testing.T) { + r := require.New(t) + + type RoomProvider struct { + Name string } - defer os.Remove(tmpFile.Name()) - _, err = tmpFile.Write([]byte(contents)) - if err != nil { - return err + type RoomProviders []RoomProvider + + box := packd.NewMemoryBox() + err := box.AddString("room_providers/index.html", "INDEX: <%= len(roomProviders) %>") + r.NoError(err) + + re := render.New(render.Options{ + TemplatesBox: box, + }) + + app := buffalo.New(buffalo.Options{}) + app.GET("/room-providers", func(c buffalo.Context) error { + return c.Render(200, re.Auto(c, RoomProviders{ + RoomProvider{Name: "Ford"}, + RoomProvider{Name: "Chevy"}, + })) + }) + + w := httptest.New(app) + res := w.HTML("/room-providers").Get() + + r.Contains(res.Body.String(), "INDEX: 2") +} + +func Test_Auto_HTML_Show_MultiWord_Dashed(t *testing.T) { + r := require.New(t) + + type RoomProvider struct { + ID int + Name string } - e := render.New(render.Options{ - TemplatesBox: packr.New(os.TempDir(), os.TempDir()), + box := packd.NewMemoryBox() + err := box.AddString("room_providers/show.html", "SHOW: <%= roomProvider.Name %>") + r.NoError(err) + + re := render.New(render.Options{ + TemplatesBox: box, }) - fn(e) - return nil + app := buffalo.New(buffalo.Options{}) + app.GET("/room-providers/{id}", func(c buffalo.Context) error { + return c.Render(200, re.Auto(c, RoomProvider{ID: 1, Name: "Ford"})) + }) + + w := httptest.New(app) + res := w.HTML("/room-providers/1").Get() + + r.Contains(res.Body.String(), "SHOW: Ford") } diff --git a/render/download_test.go b/render/download_test.go index 5dd8e4437..488eee5c2 100644 --- a/render/download_test.go +++ b/render/download_test.go @@ -1,4 +1,4 @@ -package render_test +package render import ( "bytes" @@ -9,82 +9,79 @@ import ( "strconv" "testing" - "github.com/gobuffalo/buffalo/render" "github.com/stretchr/testify/require" ) +type dlRenderer func(context.Context, string, io.Reader) Renderer + +type dlContext struct { + context.Context + rw http.ResponseWriter +} + +func (c dlContext) Response() http.ResponseWriter { + return c.rw +} + var data = []byte("data") func Test_Download_KnownExtension(t *testing.T) { - assert := require.New(t) + r := require.New(t) - type di func(context.Context, string, io.Reader) render.Renderer - table := []di{ - render.Download, - render.New(render.Options{}).Download, + table := []dlRenderer{ + Download, + New(Options{}).Download, } - for _, d := range table { - ctx := testContext{rw: httptest.NewRecorder()} - re := d(ctx, "filename.pdf", bytes.NewReader(data)) - bb := new(bytes.Buffer) - err := re.Render(bb, nil) - - assert.NoError(err) - assert.Equal(data, bb.Bytes()) - assert.Equal(strconv.Itoa(len(data)), ctx.Response().Header().Get("Content-Length")) - assert.Equal("attachment; filename=filename.pdf", ctx.Response().Header().Get("Content-Disposition")) - assert.Equal("application/pdf", re.ContentType()) + for _, dl := range table { + ctx := dlContext{rw: httptest.NewRecorder()} + + re := dl(ctx, "filename.pdf", bytes.NewReader(data)) + + bb := &bytes.Buffer{} + r.NoError(re.Render(bb, nil)) + + r.Equal(data, bb.Bytes()) + r.Equal(strconv.Itoa(len(data)), ctx.Response().Header().Get("Content-Length")) + r.Equal("attachment; filename=filename.pdf", ctx.Response().Header().Get("Content-Disposition")) + r.Equal("application/pdf", re.ContentType()) } } func Test_Download_UnknownExtension(t *testing.T) { - assert := require.New(t) + r := require.New(t) - type di func(context.Context, string, io.Reader) render.Renderer - table := []di{ - render.Download, - render.New(render.Options{}).Download, + table := []dlRenderer{ + Download, + New(Options{}).Download, } - for _, d := range table { - ctx := testContext{rw: httptest.NewRecorder()} - re := d(ctx, "filename", bytes.NewReader(data)) - bb := new(bytes.Buffer) - err := re.Render(bb, nil) - - assert.NoError(err) - assert.Equal(data, bb.Bytes()) - assert.Equal(strconv.Itoa(len(data)), ctx.Response().Header().Get("Content-Length")) - assert.Equal("attachment; filename=filename", ctx.Response().Header().Get("Content-Disposition")) - assert.Equal("application/octet-stream", re.ContentType()) + for _, dl := range table { + ctx := dlContext{rw: httptest.NewRecorder()} + re := dl(ctx, "filename", bytes.NewReader(data)) + + bb := &bytes.Buffer{} + r.NoError(re.Render(bb, nil)) + + r.Equal(data, bb.Bytes()) + r.Equal(strconv.Itoa(len(data)), ctx.Response().Header().Get("Content-Length")) + r.Equal("attachment; filename=filename", ctx.Response().Header().Get("Content-Disposition")) + r.Equal("application/octet-stream", re.ContentType()) } } func Test_InvalidContext(t *testing.T) { - assert := require.New(t) + r := require.New(t) - type di func(context.Context, string, io.Reader) render.Renderer - table := []di{ - render.Download, - render.New(render.Options{}).Download, + table := []dlRenderer{ + Download, + New(Options{}).Download, } - for _, d := range table { - ctx := context.TODO() - re := d(ctx, "filename", bytes.NewReader(data)) - bb := new(bytes.Buffer) - err := re.Render(bb, nil) + for _, dl := range table { + re := dl(context.TODO(), "filename", bytes.NewReader(data)) - assert.Error(err) + bb := &bytes.Buffer{} + r.Error(re.Render(bb, nil)) } } - -type testContext struct { - context.Context - rw http.ResponseWriter -} - -func (c testContext) Response() http.ResponseWriter { - return c.rw -} diff --git a/render/func_test.go b/render/func_test.go index 3f95219a0..22d1baa65 100644 --- a/render/func_test.go +++ b/render/func_test.go @@ -1,34 +1,33 @@ -package render_test +package render import ( "bytes" "io" "testing" - "github.com/gobuffalo/buffalo/render" "github.com/stretchr/testify/require" ) func Test_Func(t *testing.T) { r := require.New(t) - type ji func(string, render.RendererFunc) render.Renderer - - table := []ji{ - render.Func, - render.New(render.Options{}).Func, + table := []rendFriend{ + Func, + New(Options{}).Func, } - for _, j := range table { + for _, tt := range table { bb := &bytes.Buffer{} - re := j("foo/bar", func(w io.Writer, data render.Data) error { + + re := tt("foo/bar", func(w io.Writer, data Data) error { _, err := w.Write([]byte(data["name"].(string))) return err }) r.Equal("foo/bar", re.ContentType()) - err := re.Render(bb, render.Data{"name": "Mark"}) + err := re.Render(bb, Data{"name": "Mark"}) r.NoError(err) r.Equal("Mark", bb.String()) } + } diff --git a/render/html_test.go b/render/html_test.go index 1065f726a..c9f659da8 100644 --- a/render/html_test.go +++ b/render/html_test.go @@ -1,89 +1,66 @@ -package render_test +package render import ( "bytes" - "os" - "path/filepath" "strings" "testing" - "github.com/gobuffalo/buffalo/render" - "github.com/gobuffalo/packr/v2" "github.com/stretchr/testify/require" ) -func Test_HTML(t *testing.T) { +const htmlLayout = "layout.html" +const htmlAltLayout = "alt_layout.plush.html" +const htmlTemplate = "my-template.html" + +func Test_HTML_WithoutLayout(t *testing.T) { + r := require.New(t) + + e := NewEngine() + + box := e.TemplatesBox + r.NoError(box.AddString(htmlTemplate, "<%= name %>")) + + h := e.HTML(htmlTemplate) + r.Equal("text/html; charset=utf-8", h.ContentType()) + bb := &bytes.Buffer{} + + r.NoError(h.Render(bb, Data{"name": "Mark"})) + r.Equal("Mark", strings.TrimSpace(bb.String())) +} + +func Test_HTML_WithLayout(t *testing.T) { + r := require.New(t) + + e := NewEngine() + e.HTMLLayout = htmlLayout + + box := e.TemplatesBox + r.NoError(box.AddString(htmlTemplate, "<%= name %>")) + r.NoError(box.AddString(htmlLayout, "<%= yield %>")) + + h := e.HTML(htmlTemplate) + r.Equal("text/html; charset=utf-8", h.ContentType()) + bb := &bytes.Buffer{} + + r.NoError(h.Render(bb, Data{"name": "Mark"})) + r.Equal("Mark", strings.TrimSpace(bb.String())) +} + +func Test_HTML_WithLayout_Override(t *testing.T) { r := require.New(t) - tmpDir := filepath.Join(os.TempDir(), "html_test") - err := os.MkdirAll(tmpDir, 0766) - r.NoError(err) - defer os.Remove(tmpDir) - - tmpFile, err := os.Create(filepath.Join(tmpDir, "test.html")) - r.NoError(err) - defer os.Remove(tmpFile.Name()) - - _, err = tmpFile.Write([]byte("<%= name %>")) - r.NoError(err) - - t.Run("without a layout", func(st *testing.T) { - r := require.New(st) - - j := render.New(render.Options{ - TemplatesBox: packr.New(tmpDir, tmpDir), - }).HTML - - re := j(filepath.Base(tmpFile.Name())) - r.Equal("text/html; charset=utf-8", re.ContentType()) - bb := &bytes.Buffer{} - err = re.Render(bb, map[string]interface{}{"name": "Mark"}) - r.NoError(err) - r.Equal("Mark", strings.TrimSpace(bb.String())) - }) - - t.Run("with a layout", func(st *testing.T) { - r := require.New(st) - - layout, err := os.Create(filepath.Join(tmpDir, "layout.html")) - r.NoError(err) - defer os.Remove(layout.Name()) - - _, err = layout.Write([]byte("<%= yield %>")) - r.NoError(err) - - re := render.New(render.Options{ - TemplatesBox: packr.New(tmpDir, tmpDir), - HTMLLayout: filepath.Base(layout.Name()), - }) - - st.Run("using just the HTMLLayout", func(sst *testing.T) { - r := require.New(sst) - h := re.HTML(filepath.Base(tmpFile.Name())) - - r.Equal("text/html; charset=utf-8", h.ContentType()) - bb := &bytes.Buffer{} - err = h.Render(bb, map[string]interface{}{"name": "Mark"}) - r.NoError(err) - r.Equal("Mark", strings.TrimSpace(bb.String())) - }) - - st.Run("overriding the HTMLLayout", func(sst *testing.T) { - r := require.New(sst) - nlayout, err := os.Create(filepath.Join(tmpDir, "layout2.html")) - r.NoError(err) - defer os.Remove(nlayout.Name()) - - _, err = nlayout.Write([]byte("<%= yield %>")) - r.NoError(err) - h := re.HTML(filepath.Base(tmpFile.Name()), filepath.Base(nlayout.Name())) - - r.Equal("text/html; charset=utf-8", h.ContentType()) - bb := &bytes.Buffer{} - err = h.Render(bb, map[string]interface{}{"name": "Mark"}) - r.NoError(err) - r.Equal("Mark", strings.TrimSpace(bb.String())) - }) - - }) + e := NewEngine() + e.HTMLLayout = htmlLayout + + box := e.TemplatesBox + r.NoError(box.AddString(htmlTemplate, "<%= name %>")) + r.NoError(box.AddString(htmlLayout, "<%= yield %>")) + r.NoError(box.AddString(htmlAltLayout, "<%= yield %>")) + + h := e.HTML(htmlTemplate, htmlAltLayout) + r.Equal("text/html; charset=utf-8", h.ContentType()) + bb := &bytes.Buffer{} + + r.NoError(h.Render(bb, Data{"name": "Mark"})) + r.Equal("Mark", strings.TrimSpace(bb.String())) } diff --git a/render/js_test.go b/render/js_test.go index 9dcef7e03..c1e82d568 100644 --- a/render/js_test.go +++ b/render/js_test.go @@ -13,6 +13,44 @@ import ( "github.com/stretchr/testify/require" ) +const jsLayout = "layout.js" +const jsAltLayout = "alt_layout.plush.js" +const jsTemplate = "my-template.js" + +func Test_JavaScript_WithoutLayout(t *testing.T) { + r := require.New(t) + + e := NewEngine() + + box := e.TemplatesBox + r.NoError(box.AddString(jsTemplate, "alert(<%= name %>)")) + + h := e.JavaScript(jsTemplate) + r.Equal("application/javascript", h.ContentType()) + bb := &bytes.Buffer{} + + r.NoError(h.Render(bb, Data{"name": "Mark"})) + r.Equal("alert(Mark)", strings.TrimSpace(bb.String())) +} + +// func Test_HTML_WithLayout(t *testing.T) { +// r := require.New(t) +// +// e := NewEngine() +// e.HTMLLayout = htmlLayout +// +// box := e.TemplatesBox +// r.NoError(box.AddString(htmlTemplate, "<%= name %>")) +// r.NoError(box.AddString(htmlLayout, "<%= yield %>")) +// +// h := e.HTML(htmlTemplate) +// r.Equal("text/html; charset=utf-8", h.ContentType()) +// bb := &bytes.Buffer{} +// +// r.NoError(h.Render(bb, Data{"name": "Mark"})) +// r.Equal("Mark", strings.TrimSpace(bb.String())) +// } + func Test_JavaScript(t *testing.T) { r := require.New(t) diff --git a/render/render.go b/render/render.go index 2cc8581d3..926258ef1 100644 --- a/render/render.go +++ b/render/render.go @@ -32,6 +32,9 @@ func New(opts Options) *Engine { if _, ok := opts.TemplateEngines["html"]; !ok { opts.TemplateEngines["html"] = plush.BuffaloRenderer } + if _, ok := opts.TemplateEngines["plush"]; !ok { + opts.TemplateEngines["html"] = plush.BuffaloRenderer + } if _, ok := opts.TemplateEngines["text"]; !ok { opts.TemplateEngines["text"] = plush.BuffaloRenderer } diff --git a/render/render_test.go b/render/render_test.go index 27f99746b..02d17e0df 100644 --- a/render/render_test.go +++ b/render/render_test.go @@ -1,5 +1,9 @@ package render +import ( + "github.com/gobuffalo/packd" +) + type Widget struct { Name string } @@ -7,3 +11,11 @@ type Widget struct { func (w Widget) ToPath() string { return w.Name } + +func NewEngine() *Engine { + return New(Options{ + TemplatesBox: packd.NewMemoryBox(), + }) +} + +type rendFriend func(string, RendererFunc) Renderer diff --git a/render/template.go b/render/template.go index 4efdb8128..7d2daf8bf 100644 --- a/render/template.go +++ b/render/template.go @@ -9,7 +9,9 @@ import ( "sort" "strings" + "github.com/gobuffalo/buffalo/internal/takeon/github.com/gobuffalo/syncx" "github.com/gobuffalo/buffalo/internal/takeon/github.com/markbates/errx" + "github.com/gobuffalo/packd" "github.com/sirupsen/logrus" ) @@ -17,13 +19,58 @@ type templateRenderer struct { *Engine contentType string names []string + aliases syncx.StringMap } func (s templateRenderer) ContentType() string { return s.contentType } +func (s templateRenderer) resolve(name string) ([]byte, error) { + if s.TemplatesBox == nil { + return nil, fmt.Errorf("no templates box is defined") + } + + if s.TemplatesBox.Has(name) { + return s.TemplatesBox.Find(name) + } + + v, ok := s.aliases.Load(name) + if !ok { + return nil, fmt.Errorf("could not find template %s", name) + } + + return s.TemplatesBox.Find(v) +} + func (s *templateRenderer) Render(w io.Writer, data Data) error { + if s.TemplatesBox != nil { + err := s.TemplatesBox.Walk(func(p string, f packd.File) error { + base := filepath.Base(p) + + dir := filepath.Dir(p) + + var exts []string + sep := strings.Split(base, ".") + if len(sep) >= 1 { + base = sep[0] + } + if len(sep) > 1 { + exts = sep[1:] + } + + for _, ext := range exts { + pn := filepath.Join(dir, base+"."+ext) + s.aliases.Store(pn, p) + } + + return nil + }) + if err != nil { + return err + } + } + var body template.HTML var err error for _, name := range s.names { @@ -61,7 +108,8 @@ func (s templateRenderer) partialFeeder(name string) (string, error) { name = filepath.Join(d, "_"+f) name = fixExtension(name, ct) - return s.TemplatesBox.FindString(name) + b, err := s.resolve(name) + return string(b), err } func (s templateRenderer) exec(name string, data Data) (template.HTML, error) { @@ -86,7 +134,7 @@ func (s templateRenderer) exec(name string, data Data) (template.HTML, error) { break } candidateName = rawName + "." + strings.ToLower(l) + ext - if s.TemplatesBox.Has(candidateName) { + if _, err := s.resolve(candidateName); err == nil { // Replace name with the existing suffixed version templateName = candidateName break @@ -100,7 +148,7 @@ func (s templateRenderer) exec(name string, data Data) (template.HTML, error) { data["current_template"] = templateName } - source, err := s.TemplatesBox.Find(templateName) + source, err := s.resolve(templateName) if err != nil { return "", err } @@ -190,5 +238,6 @@ func (e *Engine) Template(c string, names ...string) Renderer { Engine: e, contentType: c, names: names, + aliases: syncx.StringMap{}, } } diff --git a/resource.go b/resource.go index fb53391f5..915ae2f4e 100644 --- a/resource.go +++ b/resource.go @@ -30,9 +30,9 @@ type Resource interface { Destroy(Context) error } -// HasMiddleware can be implemented to specify additional +// Middler can be implemented to specify additional // middleware specific to the resource -type HasMiddleware interface { +type Middler interface { Use() []MiddlewareFunc } diff --git a/route_mappings.go b/route_mappings.go index 1a5f5e33d..df36c9853 100644 --- a/route_mappings.go +++ b/route_mappings.go @@ -145,7 +145,7 @@ type editable interface { func (a *App) Resource(p string, r Resource) *App { g := a.Group(p) - if mw, ok := r.(HasMiddleware); ok { + if mw, ok := r.(Middler); ok { g.Use(mw.Use()...) }