From c0a7b75c9cfb0772bdf5ec7362775f5f7798a3a0 Mon Sep 17 00:00:00 2001 From: Brad Ison Date: Mon, 3 Jan 2022 17:33:53 +0100 Subject: [PATCH] Automate CSS-inlining for default HTML email template (#2798) * Automate CSS-inlining for default HTML email template The original HTML email template was added in `template/email.html`. It looks like the CSS was manually inlined. Most likely using the premailer.dialect.ca web form, which is mentioned in the README for the Mailgun transactional-email-templates project. The resulting HTML with inlined CSS was then copied into `template/default.tmpl`. This has resulted in `email.html` and `default.tmpl` diverging at times. This commit adds build automation to inline the CSS automatically using [juice][1]. The Go template containing the resulting HTML has been moved into its own file to avoid the script that performs the CSS inlining having to parse the `default.tmpl` file to insert it there. Fixes #1939. [1]: https://www.npmjs.com/package/juice Signed-off-by: Brad Ison * Update asset/assets_vfsdata.go Signed-off-by: Brad Ison --- Makefile | 6 +- asset/asset.go | 2 +- asset/assets_vfsdata.go | 12 ++- template/Dockerfile | 7 ++ template/Makefile | 17 ++++ template/default.tmpl | 128 ----------------------------- template/email.tmpl | 175 ++++++++++++++++++++++++++++++++++++++++ template/inline-css.js | 40 +++++++++ template/template.go | 35 ++++---- 9 files changed, 275 insertions(+), 147 deletions(-) create mode 100644 template/Dockerfile create mode 100644 template/Makefile create mode 100644 template/email.tmpl create mode 100755 template/inline-css.js diff --git a/Makefile b/Makefile index 5520656a..16db86c5 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,7 @@ DOCKER_ARCHS ?= amd64 armv7 arm64 ppc64le s390x include Makefile.common FRONTEND_DIR = $(BIN_DIR)/ui/app +TEMPLATE_DIR = $(BIN_DIR)/template DOCKER_IMAGE_NAME ?= alertmanager STATICCHECK_IGNORE = @@ -28,13 +29,16 @@ build-all: assets apiv2 build .PHONY: assets assets: asset/assets_vfsdata.go -asset/assets_vfsdata.go: ui/app/script.js ui/app/index.html ui/app/lib template/default.tmpl +asset/assets_vfsdata.go: ui/app/script.js ui/app/index.html ui/app/lib template/default.tmpl template/email.tmpl GO111MODULE=$(GO111MODULE) $(GO) generate $(GOOPTS) ./asset @$(GOFMT) -w ./asset ui/app/script.js: $(shell find ui/app/src -iname *.elm) api/v2/openapi.yaml cd $(FRONTEND_DIR) && $(MAKE) script.js +template/email.tmpl: template/email.html + cd $(TEMPLATE_DIR) && $(MAKE) email.tmpl + .PHONY: apiv2 apiv2: api/v2/models api/v2/restapi api/v2/client diff --git a/asset/asset.go b/asset/asset.go index c098f38d..b4959299 100644 --- a/asset/asset.go +++ b/asset/asset.go @@ -39,7 +39,7 @@ var static http.FileSystem = filter.Keep( var templates http.FileSystem = filter.Keep( http.Dir("../template"), func(path string, fi os.FileInfo) bool { - return path == "/" || path == "/default.tmpl" + return path == "/" || path == "/default.tmpl" || path == "/email.tmpl" }, ) diff --git a/asset/assets_vfsdata.go b/asset/assets_vfsdata.go index d689f260..ab7f4b3f 100644 --- a/asset/assets_vfsdata.go +++ b/asset/assets_vfsdata.go @@ -163,9 +163,16 @@ var Assets = func() http.FileSystem { "/templates/default.tmpl": &vfsgen۰CompressedFileInfo{ name: "default.tmpl", modTime: time.Date(1970, 1, 1, 0, 0, 1, 0, time.UTC), - uncompressedSize: 17526, + uncompressedSize: 4278, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x02\xff\xec\x1b\xfd\x6f\xdb\xb6\xf2\x77\xfd\x15\x37\x0d\x0f\x6b\x00\x7f\xa5\xdd\x8a\xc5\xb1\xf3\xe0\x3a\x4a\x23\x3c\xc7\x0e\x6c\xa5\x5d\x31\x0c\x01\x2d\x9d\x6d\xb6\x12\xa9\x91\x54\x1c\x2f\xf5\xff\xfe\x40\x4a\xfe\x90\x3f\x12\xa7\xe8\x92\xec\x3d\x2f\xd8\x66\x51\xf7\x7d\xc7\xbb\xa3\x48\xde\xdd\x41\x80\x03\xca\x10\xec\xeb\x6b\x12\xa2\x50\x11\x61\x64\x88\xc2\x86\xe9\xb4\xb1\xf4\x7c\x77\x07\xc8\x02\x98\x4e\xad\xad\x28\x57\xdd\x96\xc6\xba\xbb\x83\x92\x73\xab\x50\x30\x12\x5e\x75\x5b\x30\x9d\x96\x7f\x2c\x1b\x38\xf9\x6f\x81\x3e\xd2\x1b\x14\x75\x0d\xd4\xcd\x1e\xe0\x2b\x24\x22\xfc\x33\x41\x31\x49\xd1\x33\x46\x79\x4e\x32\xe9\x7f\x46\x5f\x69\x0e\xbf\x6b\xec\x9e\x22\x2a\x91\xf0\x15\x14\xbf\x8a\x63\x14\x29\x2a\x1d\x00\xfe\x39\x7f\x69\x0f\xa8\xa0\x6c\xa8\x71\xaa\x1a\xc7\x28\x24\x4b\x67\x66\x14\xbe\x42\x88\x6c\x99\xe3\x1f\xa0\x81\xde\x0b\x9e\xc4\x2d\xd2\xc7\x50\x96\x7a\x5c\x28\x0c\x2e\x09\x15\xb2\xf4\x81\x84\x09\x6a\x86\x9f\x39\x65\x60\x83\xa6\x0a\x29\xcb\xa1\x82\x57\x9a\x56\xa9\xc9\xa3\x88\xb3\x14\xf9\x20\x1b\x5b\xa2\x77\x00\xd3\xe9\xab\xbb\x3b\x18\x53\x35\xca\x03\x97\xba\x18\xf1\x1b\xcc\x73\x6f\x93\x08\x65\x66\xd1\x4d\xdc\xe7\x82\x1f\xcc\x7f\x6d\x71\x53\x80\xd2\x17\x34\x56\x94\x33\xfb\x1e\x1b\x2b\xbc\x55\xa9\x4b\xaf\x43\x2a\x55\x06\x2a\x08\x1b\x22\x94\x60\x3a\x4d\xe5\xaa\x5a\x8b\xc1\x75\x3b\x69\xab\x14\x8d\x21\xb5\xf8\xfa\xa9\x0e\x73\x05\x32\xc1\x52\xe6\x0d\xc6\xb8\x22\x5a\xa6\x1c\xc9\xa5\xe1\x6f\xa3\xdb\xe3\x89\xf0\xb1\x9a\x3a\x13\x19\x0a\xa2\xb8\x48\x23\xd1\xda\x60\xa8\x9c\x0d\x64\x48\xfc\x2f\xa5\x00\x07\x24\x09\x55\x49\x51\x15\x62\x66\x05\x85\x51\x1c\x12\x95\x8f\xc5\xd2\x36\x93\xe7\xe9\x24\x52\xcf\x86\x68\x13\xa9\xfc\x9c\xdb\x91\xde\x80\x84\x61\x9f\xf8\x5f\xd6\xe8\x6d\x14\x5f\x13\x85\xaf\xf0\x10\x60\x48\xd9\x97\x9d\x25\xf0\x33\x09\x68\x60\xef\x86\x10\x0b\xd4\xd1\xb5\x23\xf4\x92\x40\xf7\x5a\xcc\xa4\x9c\x1d\x45\xa6\x3e\x67\x18\xf1\xcf\xd4\xde\x1d\x3e\x11\xe1\xae\x12\xef\xae\xdc\x80\x73\x95\x26\xd8\x2d\x41\x18\x6b\xd5\x82\x44\x4d\xe6\x28\xeb\xf3\xf7\x71\xe1\xb8\x4e\xd1\x0f\x29\x32\xf5\xed\x01\xb9\x8d\xe2\xa2\x08\x7c\x9b\xcf\xd6\xe9\x52\x26\x15\x61\x3e\xca\x0d\x74\xd7\x12\x56\x69\xbb\x55\x79\x2c\x87\xc8\x28\xce\x09\x47\x28\x25\x19\x7e\xdb\xfc\x5e\x23\xb6\xee\xa1\x2c\xbf\x6f\x49\x67\x1b\x13\xba\xb5\x52\x4e\x72\xf5\xea\x00\x2a\x50\x9c\x4e\xad\x74\x10\xd2\x41\x93\x38\xef\xb7\x48\xbe\xe8\x19\x26\xc5\x25\x8d\x36\xf0\xeb\xa2\xe4\xe1\x0d\x06\x2b\x1c\x67\xc3\xbb\xf3\x9c\x61\xac\x71\x2d\xee\x62\x52\x69\xf2\xf8\xe3\xa3\x29\xe7\xf5\x31\xfa\x23\xa2\x1e\xeb\x73\x6b\xef\xbf\x7b\xfc\xb7\xdc\x17\x5e\x89\x70\x8d\xde\x46\xff\x6c\xf1\xfa\x8a\x7f\x14\xbf\xd6\xc5\x72\x6b\x26\x5d\x07\x8f\x89\x50\x93\x47\xc0\x2b\x32\xdc\x15\x9a\x0c\x91\xa9\xeb\xd5\x12\x97\x8f\xaf\x1b\xea\x2b\x2e\x78\x2c\x17\x61\xab\x88\xc2\xeb\x7c\xa0\xed\x63\xe9\x71\xb9\x60\xdd\xaa\xc8\x14\x55\x93\xeb\x80\xca\x38\x24\x93\xeb\x2d\xdd\xd4\xc3\x89\x7b\x9d\x72\xc4\x19\x55\x5c\x1b\xe4\x5a\x71\x1e\x3e\xb2\x24\x2e\xd3\xc6\x88\xd0\x70\x11\x07\x8b\x05\xcb\xa3\xa5\xcc\x53\x1a\xa9\xc8\x88\x65\xd5\x7e\x38\xed\x34\xbd\x4f\x97\x0e\xe8\x21\xb8\xbc\x7a\xd7\x72\x9b\x60\x17\xcb\xe5\x8f\x6f\x9a\xe5\xf2\xa9\x77\x0a\xbf\x9d\x7b\x17\x2d\x38\x2c\x55\xc0\x13\x84\x49\xaa\x83\x8d\x84\xe5\xb2\xd3\xb6\xc1\x1e\x29\x15\x57\xcb\xe5\xf1\x78\x5c\x1a\xbf\x29\x71\x31\x2c\x7b\xdd\xf2\xad\xa6\x75\xa8\x91\xb3\x9f\x45\xb5\x84\x59\x0a\x54\x60\x9f\x58\xb5\x1f\x8a\x45\xab\xa7\x26\x21\x02\x61\x01\x18\x26\x01\x0a\xaa\x1d\x3a\x10\x3c\x02\x4d\x5a\x56\xcb\xe5\x21\x55\xa3\xa4\x5f\xf2\x79\x54\xd6\x3a\x0c\x13\x56\x36\xe4\x88\x9f\xd2\x2b\x1a\xd5\x8a\x33\x73\x48\xcb\xb2\xbc\x11\xc2\x85\xeb\x41\x8b\xfa\xc8\x24\xc2\xab\x0b\xd7\x3b\xb0\xac\x26\x8f\x27\x82\x0e\x47\x0a\x5e\xf9\x07\xf0\xba\x72\xf8\x33\x5c\xa4\x14\x2d\xeb\x12\x45\x44\xa5\xa4\x9c\x01\x95\x30\x42\x81\xfd\x09\x0c\x05\x61\x0a\x83\x02\x0c\x04\x22\xf0\x01\xf8\x23\x22\x86\x58\x00\xc5\x81\xb0\x09\xc4\x28\x24\x67\xc0\xfb\x8a\x50\xa6\xe3\x9f\x80\xcf\xe3\x89\xc5\x07\xa0\x46\x54\x82\xe4\x03\x35\x26\x22\xd5\x90\x48\xc9\x7d\x4a\x14\x06\x10\x70\x3f\x89\x90\xa5\x13\x17\x06\x34\x44\x09\xaf\xd4\x08\xc1\xee\x65\x18\xf6\x81\x61\x12\x20\x09\x2d\xca\x40\xbf\x9b\xbd\x32\x6b\x3d\x9e\x28\x10\x28\x95\xa0\xc6\x0a\x05\xa0\xcc\x0f\x93\x40\xcb\x30\x7b\x1d\xd2\x88\x66\x1c\x34\xba\x51\x5c\x5a\x8a\x43\x22\xb1\x60\xe4\x2c\x40\xc4\x03\x3a\xd0\xff\x47\xa3\x56\x9c\xf4\x43\x2a\x47\x05\x08\xa8\x26\xdd\x4f\x14\x16\x40\xea\x41\x63\xc7\x82\xd6\xa3\xcc\x05\x48\x0c\x43\xcb\xe7\x31\x45\x09\x46\xd7\x85\x74\x06\x46\x8b\x1e\x6b\x83\xaa\xcc\x44\x52\x8f\x8c\x47\x3c\xca\x6b\x42\xa5\x35\x48\x04\xa3\x72\x84\x06\x27\xe0\x20\xb9\xe1\xa8\xa3\x59\x8f\x68\xf0\x01\x0f\x43\x3e\xd6\xaa\xf9\x9c\x05\x34\x5b\xde\x19\x27\x93\xbe\x5e\xe2\xfa\x73\xbf\x32\xae\xa8\x9f\x9a\xdb\x38\x20\x5e\x78\x35\x7b\x25\x47\x24\x0c\xa1\x8f\x99\xc1\x30\x00\xca\x80\x2c\xa9\x23\x34\x7b\xdd\x1f\x2a\x4a\x42\x88\xb9\x30\xfc\x56\xd5\x2c\x59\x96\x77\xee\x40\xaf\x73\xe6\x7d\x6c\x74\x1d\x70\x7b\x70\xd9\xed\x7c\x70\x4f\x9d\x53\xb0\x1b\x3d\x70\x7b\x76\x01\x3e\xba\xde\x79\xe7\xca\x83\x8f\x8d\x6e\xb7\xd1\xf6\x3e\x41\xe7\x0c\x1a\xed\x4f\xf0\x1f\xb7\x7d\x5a\x00\xe7\xb7\xcb\xae\xd3\xeb\x41\xa7\x6b\xb9\x17\x97\x2d\xd7\x39\x2d\x80\xdb\x6e\xb6\xae\x4e\xdd\xf6\x7b\x78\x77\xe5\x41\xbb\xe3\x41\xcb\xbd\x70\x3d\xe7\x14\xbc\x0e\x68\x86\x19\x29\xd7\xe9\x69\x62\x17\x4e\xb7\x79\xde\x68\x7b\x8d\x77\x6e\xcb\xf5\x3e\x15\xac\x33\xd7\x6b\x6b\x9a\x67\x9d\x2e\x34\xe0\xb2\xd1\xf5\xdc\xe6\x55\xab\xd1\x85\xcb\xab\xee\x65\xa7\xe7\x40\xa3\x7d\x0a\xed\x4e\xdb\x6d\x9f\x75\xdd\xf6\x7b\xe7\xc2\x69\x7b\x25\x70\xdb\xd0\xee\x80\xf3\xc1\x69\x7b\xd0\x3b\x6f\xb4\x5a\x9a\x95\xd5\xb8\xf2\xce\x3b\x5d\x2d\x1f\x34\x3b\x97\x9f\xba\xee\xfb\x73\x0f\xce\x3b\xad\x53\xa7\xdb\x83\x77\x0e\xb4\xdc\xc6\xbb\x96\x93\xb2\x6a\x7f\x82\x66\xab\xe1\x5e\x14\xe0\xb4\x71\xd1\x78\xef\x18\xac\x8e\x77\xee\x74\x2d\x0d\x96\x4a\x07\x1f\xcf\x1d\x3d\xa4\xf9\x35\xda\xd0\x68\x7a\x6e\xa7\xad\xd5\x68\x76\xda\x5e\xb7\xd1\xf4\x0a\xe0\x75\xba\xde\x1c\xf5\xa3\xdb\x73\x0a\xd0\xe8\xba\x3d\x6d\x90\xb3\x6e\xe7\xa2\x60\x69\x73\x76\xce\x34\x88\xdb\xd6\x78\x6d\x27\xa5\xa2\x4d\x0d\x39\x8f\x74\xba\xe6\xf9\xaa\xe7\xcc\x09\xc2\xa9\xd3\x68\xb9\xed\xf7\x3d\x8d\xac\x55\x9c\x01\x97\xac\x62\xf1\xc4\xaa\x99\x14\x78\x1b\x85\x4c\xd6\x37\x24\xb6\xc3\xa3\xa3\xa3\x34\x9f\xd9\xbb\x01\x49\x9d\xdc\xea\xf6\x80\x33\x55\x1c\x90\x88\x86\x93\x2a\xfc\x74\x8e\xe1\x0d\x2a\xea\x13\x68\x63\x82\x3f\x15\x60\x3e\x50\x80\x86\xa0\x24\x2c\x80\x24\x4c\x16\x25\x0a\x3a\x38\x86\x3e\xbf\x2d\x4a\xfa\x97\xae\xc5\xd0\xe7\x22\x40\x51\xec\xf3\xdb\x63\x30\x44\x25\xfd\x0b\xab\x70\xf8\x73\x7c\x7b\x0c\x11\x11\x43\xca\xaa\x50\x39\xd6\xb9\x75\x84\x24\x78\x4e\xfe\x11\x2a\x02\xba\xa2\xd6\xed\x1b\x8a\x63\x3d\x8b\x6c\x3d\x7b\x15\x32\x55\xb7\xc7\x34\x50\xa3\x7a\x80\x37\xd4\xc7\xa2\x79\x78\x3e\x63\x41\x79\x26\xae\x76\x66\x11\xff\x4c\xe8\x4d\xdd\x6e\xa6\xa2\x16\xbd\x49\x8c\x4b\x82\xeb\x56\xa4\xac\x9d\x7b\x6c\x2a\x81\x44\x55\xbf\xf2\xce\x8a\xbf\x3e\xb3\xf8\xe6\xdb\xc6\xf3\xb9\xfb\xbe\x5e\xa4\x56\x36\xc2\x9d\x58\x56\xad\xac\x83\x52\xff\xe8\xf3\x60\x02\x54\x61\x24\x7d\x1e\x63\xdd\xb6\xcd\x83\x9a\xe8\xdf\xd9\x8c\x92\xfe\x08\x23\x62\x66\x94\xa3\xab\xfb\xc5\xac\xf7\x7d\x52\x25\x8b\x63\xec\x7f\xa1\xaa\x98\xbe\x88\x38\x57\x23\x83\x94\xd6\x06\x4a\x24\x06\x0b\x20\x1d\x1b\x06\xbb\x48\x82\xcf\x89\x54\x55\x60\x9c\xe1\x31\x8c\x50\x57\xa6\x2a\x1c\x56\x2a\xff\x3a\x86\x90\x32\x2c\xce\x87\x4a\x6f\x31\x3a\x06\x33\x03\x52\x00\xf8\x81\x46\x7a\xb2\x10\xa6\x8e\xa1\x4f\xfc\x2f\x43\xc1\x13\x16\x14\x7d\x1e\x72\x51\x85\x1f\x07\x6f\xf5\xdf\xb2\xf9\x21\x26\x41\x60\xa4\xd2\xd1\xd0\x1f\x1a\xc8\xba\x9d\x41\xda\xda\xde\x8a\xf4\x9f\x3a\x3c\x96\x54\xda\x51\x8f\x8d\xb2\x03\xd4\x94\x78\xc6\x3c\x06\xa0\x25\x78\xe2\x4c\x7a\x83\x42\x13\x09\x8b\x24\xa4\x43\x56\x05\xc5\xe3\xbc\xa1\x6e\xcc\x8b\xba\xad\x78\x6c\x9f\xd4\xca\x2a\x58\x08\x9a\x66\x56\xfb\x6d\xa5\x62\xbf\x00\xa1\xb3\xa5\x55\x15\xfa\x21\xf7\xbf\xe4\x62\x3b\x22\xb7\xc5\x2c\x48\xde\x56\x2a\xf1\x6d\xee\xa5\x1f\x22\x11\x9a\xa1\x1a\xe5\xc6\xb7\x4d\x94\xb9\x71\x80\x24\x8a\xaf\x4c\x89\x9c\xb5\x8c\xa1\x00\x6a\x01\xbd\x79\xea\xb0\xca\xeb\xbb\x6a\x9c\xfb\x95\x98\xc9\xad\x9d\x6c\x26\x73\xe6\x67\x6d\x09\x1b\x7c\x0c\xc3\x0c\xba\x6e\x57\xd2\x67\x19\x13\x7f\xf6\xfc\xa4\x8a\x66\x2f\x05\x09\x68\x22\xab\xf0\xc6\x8c\x6d\x48\x00\x83\x41\x2e\x8b\xa5\x68\x55\x38\x8c\x6f\x41\xf2\x90\x06\xf0\x23\x1e\xe9\xbf\x7c\x62\x18\x0c\x96\x6c\xf1\x12\xb2\xc3\x42\x92\xa7\xcb\x12\x6f\xb7\x4e\xb8\x9c\x75\x0d\xca\x38\x2b\x35\xbf\x54\x2a\xc7\x60\x4a\x54\x06\xef\x23\x53\x28\x36\xf9\xcb\xfc\x5b\x31\x4e\x59\xf7\x9b\xf3\xf6\x97\xd7\xaf\x9b\x9b\x0b\xd0\x6b\x1d\xd7\x36\x64\xf3\x2d\x65\xb0\xec\xbd\x14\x77\xf3\x8c\x9c\xfd\xb3\xd8\x53\x9d\x6f\xa6\x82\xf9\x58\xb2\xf1\x5b\xd2\x01\x1c\xc2\x74\x2a\xe7\x1f\x3c\x60\xc0\x05\x2c\xf6\xfd\xb6\xec\xbb\xc2\x74\xba\xc2\x15\x96\x77\x01\xeb\xb9\x3d\xc0\x35\xb0\xec\xd3\x4a\xce\xf9\xf3\x1c\x3c\x7f\x16\xfb\x30\xdd\xa5\x98\x2d\x82\xe7\x30\x0d\x9e\xfb\x62\xe3\xc5\xe7\xbe\xad\x66\x7f\x59\x41\xf0\xd2\x43\xa1\x02\x95\x59\x2e\xb9\x2f\x1c\x32\x35\x08\x8c\x04\x0e\xea\xf6\x2e\x3b\x06\x4f\x1c\x0f\xb3\xa4\x79\x76\x76\x96\x25\xdf\x00\x7d\x2e\xcc\x37\xb9\xd9\xf2\x20\xb7\x20\x78\xad\x97\x03\xb9\xbc\xdd\xe7\x61\xb0\x39\x71\xfb\x89\x90\x9a\x7a\xcc\x69\x3a\x30\x6f\x28\x28\x33\x44\xb3\xbe\x62\x25\xc1\xff\xa2\x05\x33\xf4\xcc\x47\xd4\x01\x17\x51\x15\x7c\x12\x53\x45\x42\xfa\x17\x6e\x4c\xfa\x6f\x7e\xfe\x15\x03\xb2\xa1\x5e\xaf\x41\x64\xc3\xc6\xca\xd5\xb4\x90\xcf\x07\xe7\xdd\x5b\x7c\x9b\xb9\xf7\xe4\x03\xc5\x31\x50\x06\x0f\x7e\x1d\xaf\x95\xc9\xc6\x18\x5e\x49\xbc\x9b\xd3\xef\x3c\x75\xdf\xbb\xf9\xb1\xa1\x28\xec\xa7\xec\xdf\x33\x65\xa5\x12\x9c\x0d\x9f\xcf\xb4\xbf\x6f\x3f\xb9\xf5\x47\xb6\xf3\x55\x2b\xa7\x42\x7e\x87\xa8\xdb\xd0\x30\x64\x6f\x66\xc7\x93\x56\xb7\xd0\xf6\x71\xf8\xff\x11\x87\x69\x6b\x3a\x0f\xb5\x5a\x5f\x3c\xeb\x77\xc4\x4d\x36\x7a\xe0\x5c\xde\xf6\xc3\x73\xcf\xac\xcc\xf6\x79\xb7\xa9\x16\x2c\x36\xd1\xd3\x4a\xf0\xec\x91\xb1\x24\xd1\x4b\x09\x8f\x07\x2d\xfa\xe0\x61\xcb\x7f\x68\xb0\x2c\x77\x98\xab\xa7\x3f\x9f\xa9\xa1\x9c\xb5\x5b\x6b\x3d\x65\xc2\x02\x14\xba\xfb\xcb\x87\x53\x7a\x7e\x55\x37\x51\x2f\x2f\xc7\x7c\x5b\x35\xdd\xb1\xbd\x5b\x3e\x6b\xb2\xd1\xbd\xfb\xae\xf0\xc5\x54\xe3\x17\x58\xfd\x6a\xa3\x17\x28\xd3\x3f\x7a\x06\xdf\xd7\x11\xef\x27\xd6\xff\xfe\x72\x6b\x7e\x66\x6f\xb1\xe0\x9a\x0d\x3d\xc3\x92\x6b\xf9\x04\xe1\x3e\x1a\xf7\x8b\xae\xfd\xa2\x6b\xbf\xe8\xda\x2f\xba\xf6\x8b\xae\xfd\xa2\x6b\x87\x7a\x5a\x2b\x9b\xfd\xb8\x93\x47\x6c\x85\xce\x51\x16\x23\x4f\x7e\x12\x23\x77\x34\x69\xe9\xa4\xc9\xc2\xd1\x47\x47\x47\xf7\x6d\x70\xe7\x77\x76\xd7\xb7\x24\x5f\xca\x4e\xef\xcb\x69\x5f\x9e\xb2\x75\x79\xbd\xb5\x75\xd9\xb8\x89\xf6\x90\xcb\x97\x7a\x9b\x95\x73\x0d\xf9\x53\x58\xcb\xe9\x2a\x7f\x55\xdd\x7e\x5a\xd5\x73\x1a\xed\x9c\xaa\x90\x29\xe8\x4f\x76\xdb\x87\x5b\xcf\x1d\x6b\xe7\x1d\x56\x33\x43\xad\x1c\xd0\x9b\x93\xf4\xbf\x56\x3e\x4d\xfc\x43\x8e\xd7\xa5\x2a\x2e\xf2\x57\xad\xdc\xe7\xc1\x44\x8f\x8c\x54\x14\x9e\x58\xd6\xe6\xfb\x3b\x71\x22\x47\xfc\x06\xc5\x77\xb8\xff\xbd\x46\xea\xef\xbf\x0f\xf6\x7d\xae\x83\xed\x7e\x1b\xec\xfb\x5d\x06\x5b\xe2\xb9\x83\x25\x17\x77\xb2\x1f\x73\x27\x74\xf9\x36\x36\x93\xdf\xe5\x92\xd6\x32\x9d\xbd\x7b\x1f\xe3\xde\xff\x06\x00\x00\xff\xff\x0a\xd2\x4d\x62\x76\x44\x00\x00"), + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x02\xff\xec\x57\x41\x6f\xdb\x3a\x0c\xbe\xe7\x57\x10\x7e\x97\xe6\x10\xf7\x9d\x0b\x14\x0f\xc5\xc3\xb6\x4b\x31\x0c\x29\xb2\xcb\x30\x18\xaa\xcd\xb8\x6a\x65\xc9\x95\xe8\xb4\x81\xe3\xff\x3e\xc8\x76\x13\x2b\xb2\x53\x3b\xe8\x6e\xbd\xd5\x2c\xf9\x91\xfa\xf8\x89\x54\xca\x12\x12\x5c\x73\x89\x10\x44\x11\x13\xa8\x29\x63\x92\xa5\xa8\x03\xa8\xaa\x9b\xce\x77\x59\x02\xca\x04\xaa\x6a\x36\x18\xb2\x5a\xde\xda\xa8\xb2\x84\xf0\xcb\x2b\xa1\x96\x4c\xac\x96\xb7\x50\x55\x97\xff\x5c\xd6\x7e\xe6\x3f\x8d\x31\xf2\x0d\xea\x6b\xeb\xb4\x6c\x3f\x60\x07\x85\x16\xcf\x05\xea\x6d\x13\xde\x26\x72\x33\x99\xe2\xfe\x11\x63\xb2\x19\x7e\xd9\xe8\x3b\x62\x54\x18\xd8\x01\xa9\x55\x9e\xa3\x6e\x42\xf9\x1a\xf0\x79\xff\xcf\x60\xcd\x35\x97\xa9\x8d\xb9\xb2\x31\xf5\x81\x4c\xf8\xb5\xb6\xc2\x0e\x04\xca\x6e\xc6\xdf\x60\x9d\xbe\x69\x55\xe4\xb7\xec\x1e\x85\x09\xef\x94\x26\x4c\x7e\x30\xae\x4d\xf8\x93\x89\x02\x6d\xc2\x47\xc5\x25\x04\x60\x51\xa1\x49\x99\x12\x5c\x58\xac\xf0\x7f\x95\x65\x4a\x36\xc1\xf3\xd6\xd6\xc1\x9b\x43\x55\x5d\x94\x25\xbc\x70\x7a\x70\x9d\xc3\x25\x66\x6a\x83\x6e\xf6\xef\x2c\x43\xd3\x32\xda\x97\x7d\x5f\xf8\x7c\xff\xd7\x40\x9b\x12\x34\xb1\xe6\x39\x71\x25\x83\x13\x1c\x13\xbe\x52\xd3\xd2\x48\x70\x43\xad\xab\x66\x32\x45\x08\xa1\xaa\x9a\xba\xae\x66\x07\xa3\xcf\x93\x65\x65\x51\x13\x69\xcb\xb7\x5f\xd7\xb0\x3f\x40\x5b\x58\x93\xfc\x46\x4a\x45\xcc\xd6\xe4\x40\x76\xcc\xe7\xe1\xde\xa9\x42\xc7\x78\xd5\x34\x13\x25\x6a\x46\x4a\x37\x4a\x9c\xf5\x10\xe5\x70\x60\x04\x8b\x9f\xc2\x04\xd7\xac\x10\x14\x12\x27\x81\x2d\x0b\x84\x59\x2e\x18\xb9\x5a\x0c\x87\x28\x77\x71\x0a\x63\x6f\x43\xd6\x07\xe5\xde\xb9\x91\x78\x6b\x26\xc4\x3d\x8b\x9f\x3c\xbc\xde\xf2\x2d\x28\xec\xe0\x3d\x47\xc1\xe5\xd3\xe8\x0a\xe2\xb6\x02\x9e\x04\xe3\x02\x72\x8d\x56\x5d\x23\xbd\x3b\x05\x9d\x64\xac\x1e\x39\x23\x4b\xe6\xb1\x92\x98\xa9\x47\x1e\x8c\xf7\x2f\xb4\x18\x5b\xf1\xf8\xc3\xad\x95\xa2\x66\xc0\x0e\x88\x30\xb7\x47\x4b\x0a\xda\xee\x43\xfc\xfb\x3b\x4d\x8e\x3e\x62\x2c\x38\x4a\x3a\x5f\x90\x43\x88\x87\x25\x70\x5e\xcf\x7c\x5c\x2e\x0d\x31\x19\xa3\xe9\xc1\xf5\x06\x56\x38\xcc\xaa\xca\x4d\x8a\x92\xe3\x1e\x38\x43\x63\x58\x7a\xde\xfd\xf6\xc0\xfc\x0e\xb5\xf3\x7d\x60\x9c\xf5\x0e\xf4\xd9\xd1\x3a\x71\xf6\xd5\x1c\xfe\x85\x45\x55\xcd\x1a\x23\x34\xc6\x7a\x70\x9e\x66\xc4\x5d\x7a\x75\x92\x45\xe7\x44\x3d\xf9\x96\x68\x94\xd8\x60\x72\x94\xf1\xcd\x3c\x3e\xe7\x5b\x84\x97\x75\x31\x86\x52\x53\xcf\xf1\xe9\x6a\x72\xba\xfe\x82\xf1\x03\xa3\xa9\x3d\x9f\x7d\xf6\xef\x44\xff\xba\xef\xc2\x95\x16\x1e\x5e\x6f\x7f\x06\xba\x7e\xd4\x1f\x52\x91\x5d\x96\x83\x93\xd4\x77\xcf\x99\xa6\xed\x04\x7f\x62\xe9\x58\x6f\x96\xa2\xa4\xe8\x78\xc5\xb9\xfa\xda\xf0\x98\x94\x56\xb9\x39\xc8\x96\x18\x61\xe4\x0a\xed\x53\x4b\xd3\x66\x81\xcf\x2a\x4a\xe2\xb4\x8d\x12\x6e\x72\xc1\xb6\xd1\xc0\x6b\xea\xfd\xc1\xed\x23\x67\x4a\x72\x52\x96\x90\x88\x94\x12\x13\x57\xa2\xb3\xbb\x0a\xf3\xa0\x36\xa8\x3f\xe0\xfd\xe8\x41\xfd\x7d\x3d\x7d\x8c\x9c\xc6\xab\xe9\xe3\xc4\xd4\xc9\x39\x82\xc9\xc3\x9b\x6e\xca\x4e\xe9\xbe\xe6\x64\xe7\xb2\x1f\x7e\x95\x4e\xff\x8d\xd0\xc1\xf9\x6c\xef\x94\xf6\xfe\x09\x00\x00\xff\xff\xe9\xb6\x75\xcb\xb6\x10\x00\x00"), + }, + "/templates/email.tmpl": &vfsgen۰CompressedFileInfo{ + name: "email.tmpl", + modTime: time.Date(1970, 1, 1, 0, 0, 1, 0, time.UTC), + uncompressedSize: 13888, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x02\xff\xec\x1a\x7f\x6f\xda\x48\xf6\x7f\x7f\x8a\xb7\x5e\x9d\xb6\x95\x30\x90\xa4\x8d\x1a\x7e\xe9\x28\x98\xc4\x3a\x62\x22\x70\xda\xad\x4e\xa7\xd5\x60\x3f\xf0\xec\xda\x33\xbe\x99\x21\xc0\xe6\xf2\xdd\x4f\x33\x06\x62\x08\x69\xbb\xab\x53\x61\xaf\x69\xd4\xc4\x33\x7e\xef\xcd\xfb\xfd\xde\x78\xc6\xba\xbf\x87\x08\x27\x94\x21\xd8\x98\x12\x9a\x94\x23\x9c\x90\x59\xa2\xca\x72\x36\xfe\x15\x43\x65\xc3\xc3\xc3\xfd\x3d\x28\x4c\xb3\x84\x28\x04\xfb\x97\x5f\x36\x6f\xca\xf9\x3b\x64\x11\x3c\x3c\x3c\x4f\x29\x56\x69\xa2\xc9\x58\x8d\x1f\x1c\xc7\x1a\xa9\x65\x82\x40\x58\x04\x57\xc1\x75\x1f\x22\x14\xf4\x0e\x23\x98\x08\x9e\x42\xac\x54\x26\x6b\x95\xca\x94\xaa\x78\x36\x2e\x87\x3c\xad\x68\x4a\xd3\x19\xab\x28\x41\x98\x24\xa1\xa2\x9c\x91\xc4\x31\x0b\x38\x6b\xa6\xa4\x65\x59\x41\x8c\x70\xed\x05\xd0\xa7\x21\x32\x89\xf0\xea\xda\x0b\x5e\x5b\x56\x87\x67\x4b\x41\xa7\xb1\x82\x57\xe1\x6b\x38\xad\x9e\xbc\x81\xeb\x9c\xa2\x65\xdd\xa0\x48\xa9\x94\x94\x33\xa0\x12\x62\x14\x38\x5e\xc2\x54\x10\xa6\x30\x2a\xc1\x44\x20\x02\x9f\x40\x18\x13\x31\xc5\x12\x28\x0e\x84\x2d\x21\x43\x21\x39\x03\x3e\x56\x84\x32\xca\xa6\x40\x20\xe4\xd9\xd2\xe2\x13\x50\x31\x95\x20\xf9\x44\xcd\x89\xc8\x25\x24\x52\xf2\x90\x12\x85\x11\x44\x3c\x9c\xa5\xc8\x14\xd1\x12\xc0\x84\x26\x28\xe1\x95\x8a\x11\xec\xd1\x0a\xc3\x7e\x6d\x16\x89\x90\x24\x16\x65\xa0\xdf\xad\x5f\xc1\x9c\xaa\x98\xcf\x14\x08\x94\x4a\x50\xa3\x85\x12\x50\x16\x26\xb3\x48\xf3\xb0\x7e\x9d\xd0\x94\xae\x56\xd0\xe8\x46\x70\x69\x29\x0e\x33\x89\x25\xc3\x67\x09\x52\x1e\xd1\x89\xfe\x8b\x46\xac\x6c\x36\x4e\xa8\x8c\x4b\x10\x51\x4d\x7a\x3c\x53\x58\x02\xa9\x27\x8d\x1e\x4b\x5a\x8e\x0a\x17\x20\x31\x49\xac\x90\x67\x14\x25\x18\x59\x1f\xb9\x33\x30\x9a\xf5\x4c\x2b\x54\xad\x54\x24\xf5\xcc\x3c\xe6\xe9\xb6\x24\x54\x5a\x93\x99\x60\x54\xc6\x68\x70\x22\x0e\x92\x9b\x15\xb5\x4f\xe9\x19\x0d\x3e\xe1\x49\xc2\xe7\x5a\xb4\x90\xb3\x88\x6a\x89\x64\x2d\x37\x32\x19\xf3\x3b\x34\xb2\xe4\x76\x65\x5c\xd1\x30\x57\xb7\x31\x40\xf6\x68\xd5\xd5\x2b\x19\x93\x24\x81\x31\xae\x14\x86\x11\x50\x06\xa4\x20\x8e\xd0\xcb\x4b\x45\x98\xa2\x24\x81\x8c\x0b\xb3\xde\xae\x98\x65\xcb\x0a\xae\x5c\x18\x0d\x7a\xc1\xc7\xf6\xd0\x05\x6f\x04\x37\xc3\xc1\x07\xaf\xeb\x76\xc1\x6e\x8f\xc0\x1b\xd9\x25\xf8\xe8\x05\x57\x83\xdb\x00\x3e\xb6\x87\xc3\xb6\x1f\x7c\x82\x41\x0f\xda\xfe\x27\xf8\x87\xe7\x77\x4b\xe0\xfe\x7c\x33\x74\x47\x23\x18\x0c\x2d\xef\xfa\xa6\xef\xb9\xdd\x12\x78\x7e\xa7\x7f\xdb\xf5\xfc\x4b\x78\x7f\x1b\x80\x3f\x08\xa0\xef\x5d\x7b\x81\xdb\x85\x60\x00\x7a\xc1\x15\x29\xcf\x1d\x69\x62\xd7\xee\xb0\x73\xd5\xf6\x83\xf6\x7b\xaf\xef\x05\x9f\x4a\x56\xcf\x0b\x7c\x4d\xb3\x37\x18\x42\x1b\x6e\xda\xc3\xc0\xeb\xdc\xf6\xdb\x43\xb8\xb9\x1d\xde\x0c\x46\x2e\xb4\xfd\x2e\xf8\x03\xdf\xf3\x7b\x43\xcf\xbf\x74\xaf\x5d\x3f\x28\x83\xe7\x83\x3f\x00\xf7\x83\xeb\x07\x30\xba\x6a\xf7\xfb\x7a\x29\xab\x7d\x1b\x5c\x0d\x86\x9a\x3f\xe8\x0c\x6e\x3e\x0d\xbd\xcb\xab\x00\xae\x06\xfd\xae\x3b\x1c\xc1\x7b\x17\xfa\x5e\xfb\x7d\xdf\xcd\x97\xf2\x3f\x41\xa7\xdf\xf6\xae\x4b\xd0\x6d\x5f\xb7\x2f\x5d\x83\x35\x08\xae\xdc\xa1\xa5\xc1\x72\xee\xe0\xe3\x95\xab\xa7\xf4\x7a\x6d\x1f\xda\x9d\xc0\x1b\xf8\x5a\x8c\xce\xc0\x0f\x86\xed\x4e\x50\x82\x60\x30\x0c\x36\xa8\x1f\xbd\x91\x5b\x82\xf6\xd0\x1b\x69\x85\xf4\x86\x83\xeb\x92\xa5\xd5\x39\xe8\x69\x10\xcf\xd7\x78\xbe\x9b\x53\xd1\xaa\x86\x2d\x8b\x0c\x86\x66\x7c\x3b\x72\x37\x04\xa1\xeb\xb6\xfb\x9e\x7f\x39\xd2\xc8\x5a\xc4\x35\x70\xd9\x72\x9c\x96\xd5\xf8\xa1\x3b\xe8\x04\x9f\x6e\x5c\xd0\x49\x0a\x6e\x6e\xdf\xf7\xbd\x0e\xd8\x4e\xa5\xf2\xf1\xac\x53\xa9\x74\x83\x2e\xfc\x6c\xd2\xd4\x49\xb9\x0a\x81\x4e\x41\x34\xcf\x40\x95\x8a\xeb\xdb\x60\xeb\x84\x55\xab\x54\xe6\xf3\x79\x79\x7e\x56\xe6\x62\x5a\x09\x86\x95\x85\xa6\x75\xa2\x91\x57\x8f\x8e\x2a\x60\x96\x23\x15\xd9\x2d\xab\x61\x16\x5c\xa4\x09\x93\xcd\x3d\x64\x4e\x2e\x2e\x2e\x72\x6c\x1b\xa4\xce\x98\x4d\x3b\x25\x62\x4a\x59\x0d\xaa\x75\x98\x70\xa6\x9c\x09\x49\x69\xb2\xac\xc1\x4f\x57\x98\xdc\xa1\xa2\x21\x01\x1f\x67\xf8\x53\x09\x36\x13\x25\x68\x0b\x4a\x92\x12\x48\xc2\xa4\x23\x51\xd0\x49\x1d\xc6\x7c\xe1\x48\xfa\x3b\x65\xd3\x1a\x8c\xb9\x88\x50\x38\x63\xbe\x58\x11\x95\xf4\x77\xac\xc1\xc9\x9b\x6c\x51\x37\x4c\x22\x89\x5a\x56\x23\x45\x45\x80\x91\x14\x9b\xf6\x1d\xc5\xb9\x8e\x10\x5b\x47\xa6\x42\xa6\x9a\xf6\x9c\x46\x2a\x6e\x46\x78\x47\x43\x74\xcc\xc0\x5e\xe3\x68\xc1\x1c\xfc\xf7\x8c\xde\x35\xed\x4e\x0e\xef\x04\xcb\x0c\x0b\xd8\x0a\x17\xaa\xa2\x05\xad\x9b\x54\x2b\x51\x35\x6f\x83\x9e\xf3\x4e\xd3\x50\x54\x25\xd8\xfa\x5c\xf9\x69\x54\x72\x18\xab\x61\xb4\xd4\xb2\xfe\x9e\x62\x44\x09\x70\x96\x2c\x41\x86\x02\x91\x99\xd4\xf0\x2a\x25\x8b\x9c\xb7\x1a\x9c\xbf\xa9\x66\x8b\xd7\x70\x6f\x01\x8c\x79\xb4\x34\x0f\x00\x19\x89\x22\xa3\x93\x2a\xfc\x40\x53\x2d\x22\x61\xaa\x6e\x01\x3c\x58\x16\x40\x7c\x52\xb2\xe2\xd3\x92\x15\x9f\x95\xac\xf8\xcd\x0a\xc5\x68\x6c\x8e\x3a\x0d\xd5\xe0\x5d\x75\x17\x11\x60\x6d\xb2\xd3\x6a\xb6\x80\x2a\xbc\xcd\x16\xfb\x69\x17\xe9\xe5\x16\x38\x3d\x7d\x06\xf6\xf4\x29\xec\xc9\xbb\x67\x60\xcf\xf6\xc0\x9e\xef\x87\x2d\x6b\x7b\x10\xca\x50\x7c\x49\x1d\x00\x2b\x35\x9e\x54\xab\x7f\x7b\x96\x14\x32\xf5\x55\x7a\x5d\x03\x3b\x73\x41\xb2\x5d\x8c\x93\xea\x33\xcc\x52\x76\xc7\x75\x66\xbf\xff\x22\x3f\x0f\x56\xa3\xb2\xf2\x8c\x46\x25\xf7\x66\xab\x61\xac\x4e\x15\xa6\x32\xe4\x19\x9a\x27\xb5\xcc\x70\x13\x87\x32\x8c\x31\x25\x26\x0e\x5d\xdd\x68\x5c\xa3\x94\x64\x8a\x07\x8b\x44\x70\xe6\x38\xfe\x8d\x2a\x27\x7f\x91\x72\xae\x62\x83\x94\x57\x2c\x4a\x24\x46\x8f\x40\x3a\xa0\x0c\xb6\x43\xa2\x5f\x67\x52\xd5\x80\x71\x86\x75\x88\x57\x8e\xaa\xf5\x54\x87\x84\x32\x74\x36\x53\xe5\x73\x4c\xeb\x30\x26\xe1\x6f\x53\xc1\x67\x2c\x72\x42\x9e\x70\x51\x83\x1f\x27\xe7\xfa\xa7\x5e\xd4\xb1\x4e\x0c\x56\x43\x91\x71\x82\x10\x26\x44\xca\xa6\xad\x15\x6a\x2c\x78\x38\x15\x7d\x2d\xef\xf9\xa8\x69\xeb\x91\x0d\xe3\xa9\x01\x6e\xda\x2b\x60\xbb\x65\x01\x34\x94\x38\x60\xce\xd5\x1e\xdd\x50\xd1\xc1\x14\x79\x87\x42\x13\x49\x1c\x92\xd0\x29\xab\x81\xe2\x59\xdd\x86\x3b\x33\x6a\xda\x8a\x67\x76\xab\x51\x51\xd1\x23\xa3\x2b\x1f\xd8\x24\x90\x8d\x8a\xcf\xab\xd5\x8d\x3f\x1c\x8e\x77\xdd\xd8\x66\x09\x59\xd6\x60\x9c\xf0\xf0\xb7\x3a\x14\x2b\x41\xb5\xaa\xd1\x36\x3a\x06\x32\x53\xbc\x0e\x61\x82\x44\xe8\xa5\x54\xbc\x2b\xba\x91\x1a\xa0\x11\xd1\xbb\xa2\xe0\xc8\xd4\x37\x16\xf5\xcb\x52\xec\xca\xbd\x49\xab\xba\x1a\xd5\x37\xa2\x68\x23\x16\x63\x39\x25\x94\xed\x44\x49\x88\x49\xb2\xc2\x6e\xda\xd5\x7c\x2c\x33\x12\xae\xc7\xc7\x14\xf3\x13\x43\x40\x23\xd5\xe0\x24\x5b\x80\xe4\x09\x8d\xe0\x47\xbc\xd0\x3f\xeb\x57\x8e\x20\x11\x9d\xc9\x1a\x9c\x69\x4d\x14\xb3\xc0\x64\x52\x50\xcc\x31\xa4\x82\xf5\xbf\xfb\x7b\xa0\x13\x98\x2a\x78\x95\x20\x83\x72\x3b\x41\xa1\x64\xb9\x47\x05\x65\xd3\xd7\x50\xd5\xdb\xeb\x22\x78\x21\x30\x89\x06\x05\xf3\xdb\x99\x13\xa1\x37\xad\xdf\xcc\x64\x7b\x03\x72\xa7\x1d\xa9\xc3\x96\xf1\xb6\x9a\xaa\xb7\xd5\xea\xae\xe3\x82\xa9\x6f\x2b\x7a\x21\x32\x85\x62\x9f\x59\xcd\xff\xaa\x16\x6c\x8f\x97\xb8\xe7\x6f\x4f\x4f\x3b\x3b\xb1\x0d\xab\xe7\x9c\x66\xd1\x2b\x72\xf0\xa7\x06\xc1\x44\xe2\x13\xc5\xeb\xdc\xf8\x8c\xf6\xa7\x9c\x47\xdf\xbb\xea\xcf\xdf\xbd\xbf\xa8\xf6\xbe\x5a\xf5\x39\xf8\x1e\xd5\xe7\xdf\x9c\x00\x76\xe6\x57\x81\x01\xff\x01\x1d\x26\x0f\x0f\xb9\xe6\xf7\x06\xcf\x6b\x38\x81\x87\x07\xb9\x21\x06\x13\x2e\x34\x09\x41\xd8\x14\xa1\x7c\x29\xf8\x2c\xeb\x93\x31\x26\xb2\x3c\xe2\x42\x61\x74\x43\xa8\x90\x4f\x57\xcd\xd7\xf5\x49\xaa\x7d\xa1\xa9\x9f\x3f\x90\x64\xa6\x07\xf0\x94\xbf\x3d\x7c\x3f\x56\xd3\xcd\x58\x1c\x67\x0e\xda\xa9\xf6\xeb\xb6\xdd\x3e\xaa\x5e\xe5\xd1\x67\xcf\x4c\x9d\xdb\x5b\xbf\x77\x4a\xdf\x5f\xa1\xda\x3d\xe1\xfd\x98\x3c\xe3\x59\xff\x30\xbd\xc7\xb1\x3a\x48\x15\xaa\xab\x66\xe8\xb3\x4e\xb2\x12\x8e\x40\x2c\x70\xd2\xb4\x77\x3e\x47\x98\x04\x93\x12\x46\xa6\x28\x6e\x87\xfd\xfc\xb3\x84\xbd\xd9\x19\x29\xe6\x64\x82\xa6\x44\x2c\x0f\xa7\x05\x93\xb6\x23\x0c\xb9\x30\xdf\x86\xd7\x1b\xc2\x75\x4a\xee\xf5\x7a\x7b\x53\xf5\xd9\x9b\x77\x18\x91\xc7\x76\x6a\xd5\x4a\x6d\x4f\x3b\x9b\xdd\x55\xb6\x58\x55\x89\xad\xad\xe5\xa9\xde\x58\x6e\x15\x96\x31\x4f\xa2\xfd\xa5\x24\x9c\x09\xa9\x57\xce\x38\xcd\x27\x36\x2d\x2c\x65\x86\xe8\xaa\x93\xdd\x29\x39\x6f\x37\x32\x9a\xef\x6c\x13\x2e\xd2\x1a\x84\x24\xa3\x8a\x24\xf4\x77\xac\xdb\xad\x0f\x14\xe7\x40\x19\x7c\xc6\x74\xeb\xcf\x49\x64\xaf\x63\xef\xa4\xe8\xfd\x89\xfa\x4f\x35\x6a\x2f\x71\xfc\xad\xe3\x58\x2a\xc1\xd9\xf4\x70\x0a\xff\xe7\x63\x9b\xb2\x72\x8b\x4d\xb7\xf2\x2f\xc8\x27\x1a\x95\x9c\xc9\xff\x81\x2f\xee\x6d\x94\xa0\xd0\xe7\x6c\x73\xf2\xe2\x9d\xdf\xb9\x77\xe6\x1d\xef\xc6\x01\x1b\xe3\xe3\x32\x7e\xd1\x73\xf7\x36\xe7\x85\x5e\x1c\x9a\x50\xec\xc6\x0f\x2a\xca\xf3\x91\xb8\xaf\x66\x30\xc6\xf3\x63\x5c\x99\x57\x8c\x83\x7b\x45\x81\xa3\xe3\x70\x8d\x2f\xea\x73\x9d\xdd\x1e\x19\xff\x7f\x70\x94\x62\x13\x5a\xbe\x44\x86\x82\x28\xae\xdb\x4e\xd3\x73\x1e\x2a\xff\xed\x36\x8c\x4f\xfa\xcd\x19\x8b\x50\xe8\x0e\xae\x6e\xb7\x46\x7c\x26\x42\xd4\x8d\xd6\xb1\xe5\x96\x3f\x57\x59\xbf\xb2\x01\x1c\xa2\xe4\xc9\x1d\x46\xcf\xb4\x80\x2f\x7d\xe3\xd1\x57\xe6\xa3\xab\x84\x8d\xf8\xe8\x38\xfa\x0b\x47\xf4\xe7\xba\xe5\x97\x40\xfb\x5e\x37\x68\xeb\xb4\x5d\xd8\xa2\xad\xa7\x0e\xb0\x49\xdb\x70\xf3\xe2\xa3\x2f\xdb\xb4\x97\x6d\xda\xcb\x36\xed\x65\x9b\xf6\xb2\x4d\x7b\xd9\xa6\xfd\xf1\xda\xda\xa8\x98\x83\xbf\xd6\x1f\x38\x88\xdd\xa0\x3c\xce\x14\x2e\x01\x4d\x38\x37\x27\xd7\x87\xb2\x6d\xf1\x8e\xdb\xd6\xfd\xa5\x8d\xd5\x2f\x2e\x2e\x3e\x73\x07\x68\xff\x51\xe8\xb1\x1c\x3b\x1f\x8f\x03\x6e\xdd\xec\xa0\x53\x96\x1f\x5d\xc1\x61\x3a\x9c\xaf\x6c\x68\xf6\x9f\xb5\x15\xdd\xa2\x28\xf6\xe9\x93\x16\x68\xe7\x76\x46\x6b\x2b\xbb\xb9\x0b\x85\x82\x91\xe4\x1b\x27\xb7\xcf\xe4\xae\x2f\x88\xd6\x1a\x21\x53\x30\x5e\x7e\xdd\x61\xe0\xd3\x64\xf3\xe4\x7a\xc6\x6e\x2a\x69\x54\x22\x7a\xd7\xca\x7f\x5b\xdb\x79\xe5\x2f\x72\xaf\x33\x17\xf1\x31\xe1\x35\x2a\x63\x1e\x2d\xcd\x0d\x6a\x95\x26\x2d\xcb\x7a\x4c\xab\xff\x0d\x00\x00\xff\xff\xdc\x5c\x67\xbb\x40\x36\x00\x00"), }, } fs["/"].(*vfsgen۰DirInfo).entries = []os.FileInfo{ @@ -214,6 +221,7 @@ var Assets = func() http.FileSystem { } fs["/templates"].(*vfsgen۰DirInfo).entries = []os.FileInfo{ fs["/templates/default.tmpl"].(os.FileInfo), + fs["/templates/email.tmpl"].(os.FileInfo), } return fs diff --git a/template/Dockerfile b/template/Dockerfile new file mode 100644 index 00000000..19d4be51 --- /dev/null +++ b/template/Dockerfile @@ -0,0 +1,7 @@ +FROM node + +ENV NODE_PATH="/usr/local/lib/node_modules" + +RUN npm install juice -g + +ENTRYPOINT [""] diff --git a/template/Makefile b/template/Makefile new file mode 100644 index 00000000..93e0d498 --- /dev/null +++ b/template/Makefile @@ -0,0 +1,17 @@ +DOCKER_IMG := altermanager-template +DOCKER_RUN_CURRENT_USER := docker run --user=$(shell id -u $(USER)):$(shell id -g $(USER)) +DOCKER_CMD := $(DOCKER_RUN_CURRENT_USER) --rm -t -v $(PWD):/app -w /app $(DOCKER_IMG) + +ifeq ($(NO_DOCKER), true) + DOCKER_CMD= +endif + +template-image: + @(if [ "$(NO_DOCKER)" != "true" ] ; then \ + echo ">> build template docker image"; \ + docker build -t $(DOCKER_IMG) . > /dev/null; \ + fi; ) + +email.tmpl: template-image email.html + @echo ">> inline css for html email template" + $(DOCKER_CMD) ./inline-css.js diff --git a/template/default.tmpl b/template/default.tmpl index 35e4b4c5..1ac84eae 100644 --- a/template/default.tmpl +++ b/template/default.tmpl @@ -77,134 +77,6 @@ Alerts Resolved: {{ define "victorops.default.entity_display_name" }}{{ template "__subject" . }}{{ end }} {{ define "victorops.default.monitoring_tool" }}{{ template "__alertmanager" . }}{{ end }} -{{ define "email.default.subject" }}{{ template "__subject" . }}{{ end }} -{{ define "email.default.html" }} - - - - - - -{{ template "__subject" . }} - - - - - - - - - - - -
-
- - - - - - - -
- {{ .Alerts | len }} alert{{ if gt (len .Alerts) 1 }}s{{ end }} for {{ range .GroupLabels.SortedPairs }} - {{ .Name }}={{ .Value }} - {{ end }} -
- - - - - {{ if gt (len .Alerts.Firing) 0 }} - - - - {{ end }} - {{ range .Alerts.Firing }} - - - - {{ end }} - - {{ if gt (len .Alerts.Resolved) 0 }} - {{ if gt (len .Alerts.Firing) 0 }} - - - - {{ end }} - - - - {{ end }} - {{ range .Alerts.Resolved }} - - - - {{ end }} -
- View in {{ template "__alertmanager" . }} -
- [{{ .Alerts.Firing | len }}] Firing -
- Labels
- {{ range .Labels.SortedPairs }}{{ .Name }} = {{ .Value }}
{{ end }} - {{ if gt (len .Annotations) 0 }}Annotations
{{ end }} - {{ range .Annotations.SortedPairs }}{{ .Name }} = {{ .Value }}
{{ end }} - Source
-
-
-
-
-
- [{{ .Alerts.Resolved | len }}] Resolved -
- Labels
- {{ range .Labels.SortedPairs }}{{ .Name }} = {{ .Value }}
{{ end }} - {{ if gt (len .Annotations) 0 }}Annotations
{{ end }} - {{ range .Annotations.SortedPairs }}{{ .Name }} = {{ .Value }}
{{ end }} - Source
-
-
- -
-
- - - - -{{ end }} - {{ define "pushover.default.title" }}{{ template "__subject" . }}{{ end }} {{ define "pushover.default.message" }}{{ .CommonAnnotations.SortedPairs.Values | join " " }} {{ if gt (len .Alerts.Firing) 0 }} diff --git a/template/email.tmpl b/template/email.tmpl new file mode 100644 index 00000000..63a76525 --- /dev/null +++ b/template/email.tmpl @@ -0,0 +1,175 @@ + +{{ define "email.default.subject" }}{{ template "__subject" . }}{{ end }} +{{ define "email.default.html" }} + + + + + + +{{ template "__subject" . }} + + + + + + + + + + + +
+
+ + + {{ if gt (len .Alerts.Firing) 0 }} + + + + + +
+ {{ else }} + + {{ end }} + {{ .Alerts | len }} alert{{ if gt (len .Alerts) 1 }}s{{ end }} for {{ range .GroupLabels.SortedPairs }} + {{ .Name }}={{ .Value }} + {{ end }} +
+ + + + + {{ if gt (len .Alerts.Firing) 0 }} + + + + {{ end }} + {{ range .Alerts.Firing }} + + + + {{ end }} + + {{ if gt (len .Alerts.Resolved) 0 }} + {{ if gt (len .Alerts.Firing) 0 }} + + + + {{ end }} + + + + {{ end }} + {{ range .Alerts.Resolved }} + + + + {{ end }} +
+ View in {{ template "__alertmanager" . }} +
+ [{{ .Alerts.Firing | len }}] Firing +
+ Labels
+ {{ range .Labels.SortedPairs }}{{ .Name }} = {{ .Value }}
{{ end }} + {{ if gt (len .Annotations) 0 }}Annotations
{{ end }} + {{ range .Annotations.SortedPairs }}{{ .Name }} = {{ .Value }}
{{ end }} + Source
+
+
+
+
+
+ [{{ .Alerts.Resolved | len }}] Resolved +
+ Labels
+ {{ range .Labels.SortedPairs }}{{ .Name }} = {{ .Value }}
{{ end }} + {{ if gt (len .Annotations) 0 }}Annotations
{{ end }} + {{ range .Annotations.SortedPairs }}{{ .Name }} = {{ .Value }}
{{ end }} + Source
+
+
+ +
+
+ + + + +{{ end }} diff --git a/template/inline-css.js b/template/inline-css.js new file mode 100755 index 00000000..23c82cd3 --- /dev/null +++ b/template/inline-css.js @@ -0,0 +1,40 @@ +#!/usr/bin/env node + +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +const juice = require('juice') +const fs = require('fs') + +const inputFile = 'email.html' +const outputFile = 'email.tmpl' + +var inputData = '' + +try { + inputData = fs.readFileSync(inputFile, 'utf8') +} catch (err) { + console.error(err) + process.exit(1) +} + +var templateData = juice(inputData) + +const outputData = ` +{{ define "email.default.subject" }}{{ template "__subject" . }}{{ end }} +{{ define "email.default.html" }} +${templateData} +{{ end }} +` + +fs.writeFileSync(outputFile, outputData) diff --git a/template/template.go b/template/template.go index fed6a3bd..2c1b62db 100644 --- a/template/template.go +++ b/template/template.go @@ -18,6 +18,7 @@ import ( tmplhtml "html/template" "io/ioutil" "net/url" + "path" "path/filepath" "regexp" "sort" @@ -46,25 +47,29 @@ func FromGlobs(paths ...string) (*Template, error) { text: tmpltext.New("").Option("missingkey=zero"), html: tmplhtml.New("").Option("missingkey=zero"), } - var err error t.text = t.text.Funcs(tmpltext.FuncMap(DefaultFuncs)) t.html = t.html.Funcs(tmplhtml.FuncMap(DefaultFuncs)) - f, err := asset.Assets.Open("/templates/default.tmpl") - if err != nil { - return nil, err - } - defer f.Close() - b, err := ioutil.ReadAll(f) - if err != nil { - return nil, err - } - if t.text, err = t.text.Parse(string(b)); err != nil { - return nil, err - } - if t.html, err = t.html.Parse(string(b)); err != nil { - return nil, err + defaultTemplates := []string{"default.tmpl", "email.tmpl"} + + for _, file := range defaultTemplates { + f, err := asset.Assets.Open(path.Join("/templates", file)) + if err != nil { + return nil, err + } + defer f.Close() + b, err := ioutil.ReadAll(f) + if err != nil { + return nil, err + } + if t.text, err = t.text.Parse(string(b)); err != nil { + return nil, err + } + if t.html, err = t.html.Parse(string(b)); err != nil { + return nil, err + } + } for _, tp := range paths {