summaryrefslogtreecommitdiff
path: root/vendor/github.com/jung-kurt/gofpdf
diff options
context:
space:
mode:
authorFelix Hanley <felix@userspace.com.au>2016-11-21 15:56:46 +0000
committerFelix Hanley <felix@userspace.com.au>2016-11-21 15:56:46 +0000
commit411565dc3c87851017376545383d4afa65d9f833 (patch)
tree44733ff8242c193a95115b27f9e4e88ad3eadde1 /vendor/github.com/jung-kurt/gofpdf
parent98da73fe927ee67b62c1f286b0adb649a20c373c (diff)
downloadcrjw-maps-411565dc3c87851017376545383d4afa65d9f833.tar.gz
crjw-maps-411565dc3c87851017376545383d4afa65d9f833.tar.bz2
Add vendor code
Diffstat (limited to 'vendor/github.com/jung-kurt/gofpdf')
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/compare.go146
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/contrib/barcode/barcode.go238
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/contrib/ghostscript/ghostscript.go68
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/contrib/httpimg/httpimg.go43
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/contrib/tiff/tiff.go83
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/def.go378
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/doc.go234
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/embedded.go559
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/font.go456
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/fpdf.go3856
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/fpdftrans.go213
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/htmlbasic.go211
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/internal/example/example.go126
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/internal/files/bin/bin.go28
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/internal/files/files.go1691
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/layer.go121
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/license.txt23
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/list/list.go59
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/makefont/doc.go23
-rwxr-xr-xvendor/github.com/jung-kurt/gofpdf/makefont/makefontbin0 -> 3568652 bytes
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/makefont/makefont.go71
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/png.go212
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/protect.go114
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/svgbasic.go210
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/svgwrite.go58
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/template.go269
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/template_impl.go123
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/ttfparser.go374
-rw-r--r--vendor/github.com/jung-kurt/gofpdf/util.go314
29 files changed, 10301 insertions, 0 deletions
diff --git a/vendor/github.com/jung-kurt/gofpdf/compare.go b/vendor/github.com/jung-kurt/gofpdf/compare.go
new file mode 100644
index 0000000..416e545
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/compare.go
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2015 Kurt Jung (Gmail: kurt.w.jung)
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package gofpdf
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "sort"
+)
+
+type sortType struct {
+ length int
+ less func(int, int) bool
+ swap func(int, int)
+}
+
+func (s *sortType) Len() int {
+ return s.length
+}
+
+func (s *sortType) Less(i, j int) bool {
+ return s.less(i, j)
+}
+
+func (s *sortType) Swap(i, j int) {
+ s.swap(i, j)
+}
+
+func gensort(Len int, Less func(int, int) bool, Swap func(int, int)) {
+ sort.Sort(&sortType{length: Len, less: Less, swap: Swap})
+}
+
+func writeBytes(leadStr string, startPos int, sl []byte) {
+ var pos, max int
+ var b byte
+ fmt.Printf("%s %07x", leadStr, startPos)
+ max = len(sl)
+ for pos < max {
+ fmt.Printf(" ")
+ for k := 0; k < 8; k++ {
+ if pos < max {
+ fmt.Printf(" %02x", sl[pos])
+ } else {
+ fmt.Printf(" ")
+ }
+ pos++
+ }
+ }
+ fmt.Printf(" |")
+ pos = 0
+ for pos < max {
+ b = sl[pos]
+ if b < 32 || b >= 128 {
+ b = '.'
+ }
+ fmt.Printf("%c", b)
+ pos++
+ }
+ fmt.Printf("|\n")
+}
+
+func checkBytes(pos int, sl1, sl2 []byte) (eq bool) {
+ eq = bytes.Equal(sl1, sl2)
+ if !eq {
+ writeBytes("<", pos, sl1)
+ writeBytes(">", pos, sl2)
+ }
+ return
+}
+
+// CompareBytes compares the bytes referred to by sl1 with those referred to by
+// sl2. Nil is returned if the buffers are equal, otherwise an error.
+func CompareBytes(sl1, sl2 []byte) (err error) {
+ var posStart, posEnd, len1, len2, length int
+ var diffs bool
+
+ len1 = len(sl1)
+ len2 = len(sl2)
+ length = len1
+ if length > len2 {
+ length = len2
+ }
+ for posStart < length-1 {
+ posEnd = posStart + 16
+ if posEnd > length {
+ posEnd = length
+ }
+ if !checkBytes(posStart, sl1[posStart:posEnd], sl2[posStart:posEnd]) {
+ diffs = true
+ }
+ posStart = posEnd
+ }
+ if diffs {
+ err = fmt.Errorf("documents are different")
+ }
+ return
+}
+
+// ComparePDFs reads and compares the full contents of the two specified
+// readers byte-for-byte. Nil is returned if the buffers are equal, otherwise
+// an error.
+func ComparePDFs(rdr1, rdr2 io.Reader) (err error) {
+ var b1, b2 *bytes.Buffer
+ _, err = b1.ReadFrom(rdr1)
+ if err == nil {
+ _, err = b2.ReadFrom(rdr2)
+ if err == nil {
+ err = CompareBytes(b1.Bytes(), b2.Bytes())
+ }
+ }
+ return
+}
+
+// ComparePDFFiles reads and compares the full contents of the two specified
+// files byte-for-byte. Nil is returned if the file contents are equal, or if
+// the second file is missing, otherwise an error.
+func ComparePDFFiles(file1Str, file2Str string) (err error) {
+ var sl1, sl2 []byte
+ sl1, err = ioutil.ReadFile(file1Str)
+ if err == nil {
+ sl2, err = ioutil.ReadFile(file2Str)
+ if err == nil {
+ err = CompareBytes(sl1, sl2)
+ } else {
+ // Second file is missing; treat this as success
+ err = nil
+ }
+ }
+ return
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/contrib/barcode/barcode.go b/vendor/github.com/jung-kurt/gofpdf/contrib/barcode/barcode.go
new file mode 100644
index 0000000..0649564
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/contrib/barcode/barcode.go
@@ -0,0 +1,238 @@
+// Copyright (c) 2015 Jelmer Snoeck (Gmail: jelmer.snoeck)
+//
+// Permission to use, copy, modify, and distribute this software for any purpose
+// with or without fee is hereby granted, provided that the above copyright notice
+// and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+// Package barcode provides helper methods for adding barcodes of different
+// types to your pdf document. It relies on the github.com/boombuler/barcode
+// package for the barcode creation.
+package barcode
+
+import (
+ "bytes"
+ "errors"
+ "github.com/boombuler/barcode"
+ "github.com/boombuler/barcode/codabar"
+ "github.com/boombuler/barcode/code128"
+ "github.com/boombuler/barcode/code39"
+ "github.com/boombuler/barcode/datamatrix"
+ "github.com/boombuler/barcode/ean"
+ "github.com/boombuler/barcode/qr"
+ "github.com/boombuler/barcode/twooffive"
+ "github.com/jung-kurt/gofpdf"
+ "github.com/ruudk/golang-pdf417"
+ "image/jpeg"
+ "io"
+ "strconv"
+ "sync"
+)
+
+// barcodes represents the barcodes that have been registered through this
+// package. They will later be used to be scaled and put on the page.
+// RubenN: made this a struct with a mutex to prevent race condition
+var barcodes struct {
+ sync.Mutex
+ cache map[string]barcode.Barcode
+}
+
+// barcodePdf is a partial PDF implementation that only implements a subset of
+// functions that are required to add the barcode to the PDF.
+type barcodePdf interface {
+ GetConversionRatio() float64
+ GetImageInfo(imageStr string) *gofpdf.ImageInfoType
+ Image(imageNameStr string, x, y, w, h float64, flow bool, tp string, link int, linkStr string)
+ RegisterImageReader(imgName, tp string, r io.Reader) *gofpdf.ImageInfoType
+ SetError(err error)
+}
+
+// Barcode puts a registered barcode in the current page.
+//
+// The size should be specified in the units used to create the PDF document.
+//
+// Positioning with x, y and flow is inherited from Fpdf.Image().
+func Barcode(pdf barcodePdf, code string, x, y, w, h float64, flow bool) {
+ barcodes.Lock()
+ unscaled, ok := barcodes.cache[code]
+ barcodes.Unlock()
+
+ if !ok {
+ err := errors.New("Barcode not found")
+ pdf.SetError(err)
+ return
+ }
+
+ bname := uniqueBarcodeName(code, x, y)
+ info := pdf.GetImageInfo(bname)
+
+ if info == nil {
+ bcode, err := barcode.Scale(
+ unscaled,
+ int(convertTo96Dpi(pdf, w)),
+ int(convertTo96Dpi(pdf, h)),
+ )
+
+ if err != nil {
+ pdf.SetError(err)
+ return
+ }
+
+ err = registerScaledBarcode(pdf, bname, bcode)
+ if err != nil {
+ pdf.SetError(err)
+ return
+ }
+ }
+
+ pdf.Image(bname, x, y, 0, 0, flow, "jpg", 0, "")
+}
+
+// Register registers a barcode but does not put it on the page. Use Barcode()
+// with the same code to put the barcode on the PDF page.
+func Register(bcode barcode.Barcode) string {
+ barcodes.Lock()
+ if len(barcodes.cache) == 0 {
+ barcodes.cache = make(map[string]barcode.Barcode)
+ }
+
+ key := barcodeKey(bcode)
+ barcodes.cache[key] = bcode
+ barcodes.Unlock()
+
+ return key
+}
+
+// RegisterCodabar registers a barcode of type Codabar to the PDF, but not to
+// the page. Use Barcode() with the return value to put the barcode on the page.
+func RegisterCodabar(pdf barcodePdf, code string) string {
+ bcode, err := codabar.Encode(code)
+ return registerBarcode(pdf, bcode, err)
+}
+
+// RegisterCode128 registers a barcode of type Code128 to the PDF, but not to
+// the page. Use Barcode() with the return value to put the barcode on the page.
+func RegisterCode128(pdf barcodePdf, code string) string {
+ bcode, err := code128.Encode(code)
+ return registerBarcode(pdf, bcode, err)
+}
+
+// RegisterCode39 registers a barcode of type Code39 to the PDF, but not to
+// the page. Use Barcode() with the return value to put the barcode on the page.
+//
+// includeChecksum and fullASCIIMode are inherited from code39.Encode().
+func RegisterCode39(pdf barcodePdf, code string, includeChecksum, fullASCIIMode bool) string {
+ bcode, err := code39.Encode(code, includeChecksum, fullASCIIMode)
+ return registerBarcode(pdf, bcode, err)
+}
+
+// RegisterDataMatrix registers a barcode of type DataMatrix to the PDF, but not
+// to the page. Use Barcode() with the return value to put the barcode on the
+// page.
+func RegisterDataMatrix(pdf barcodePdf, code string) string {
+ bcode, err := datamatrix.Encode(code)
+ return registerBarcode(pdf, bcode, err)
+}
+
+// RegisterPdf417 registers a barcode of type Pdf417 to the PDF, but not to the
+// page. code is the string to be encoded. columns specifies the number of
+// barcode columns; this should be a value between 1 and 30 inclusive.
+// securityLevel specifies an error correction level between zero and 8
+// inclusive. Barcodes for use with FedEx must set columns to 10 and
+// securityLevel to 5. Use Barcode() with the return value to put the barcode
+// on the page.
+func RegisterPdf417(pdf barcodePdf, code string, columns int, securityLevel int) string {
+ bcode := pdf417.Encode(code, columns, securityLevel)
+ return registerBarcode(pdf, bcode, nil)
+}
+
+// RegisterEAN registers a barcode of type EAN to the PDF, but not to the page.
+// It will automatically detect if the barcode is EAN8 or EAN13. Use Barcode()
+// with the return value to put the barcode on the page.
+func RegisterEAN(pdf barcodePdf, code string) string {
+ bcode, err := ean.Encode(code)
+ return registerBarcode(pdf, bcode, err)
+}
+
+// RegisterQR registers a barcode of type QR to the PDF, but not to the page.
+// Use Barcode() with the return value to put the barcode on the page.
+//
+// The ErrorCorrectionLevel and Encoding mode are inherited from qr.Encode().
+func RegisterQR(pdf barcodePdf, code string, ecl qr.ErrorCorrectionLevel, mode qr.Encoding) string {
+ bcode, err := qr.Encode(code, ecl, mode)
+ return registerBarcode(pdf, bcode, err)
+}
+
+// RegisterTwoOfFive registers a barcode of type TwoOfFive to the PDF, but not
+// to the page. Use Barcode() with the return value to put the barcode on the
+// page.
+//
+// The interleaved bool is inherited from twooffive.Encode().
+func RegisterTwoOfFive(pdf barcodePdf, code string, interleaved bool) string {
+ bcode, err := twooffive.Encode(code, interleaved)
+ return registerBarcode(pdf, bcode, err)
+}
+
+// registerBarcode registers a barcode internally using the Register() function.
+// In case of an error generating the barcode it will not be registered and will
+// set an error on the PDF. It will return a unique key for the barcode type and
+// content that can be used to put the barcode on the page.
+func registerBarcode(pdf barcodePdf, bcode barcode.Barcode, err error) string {
+ if err != nil {
+ pdf.SetError(err)
+ }
+
+ return Register(bcode)
+}
+
+// uniqueBarcodeName makes sure every barcode has a unique name for its
+// dimensions. Scaling a barcode image results in quality loss, which could be
+// a problem for barcode readers.
+func uniqueBarcodeName(code string, x, y float64) string {
+ xStr := strconv.FormatFloat(x, 'E', -1, 64)
+ yStr := strconv.FormatFloat(y, 'E', -1, 64)
+
+ return "barcode-" + code + "-" + xStr + yStr
+}
+
+// barcodeKey combines the code type and code value into a unique identifier for
+// a barcode type. This is so that we can store several barcodes with the same
+// code but different type in the barcodes map.
+func barcodeKey(bcode barcode.Barcode) string {
+ return bcode.Metadata().CodeKind + bcode.Content()
+}
+
+// registerScaledBarcode registers a barcode with its exact dimensions to the
+// PDF but does not put it on the page. Use Fpdf.Image() with the same code to
+// add the barcode to the page.
+func registerScaledBarcode(pdf barcodePdf, code string, bcode barcode.Barcode) error {
+ buf := new(bytes.Buffer)
+ err := jpeg.Encode(buf, bcode, nil)
+
+ if err != nil {
+ return err
+ }
+
+ reader := bytes.NewReader(buf.Bytes())
+ pdf.RegisterImageReader(code, "jpg", reader)
+
+ return nil
+}
+
+// convertTo96DPI converts the given value, which is based on a 72 DPI value
+// like the rest of the PDF document, to a 96 DPI value that is required for
+// an Image.
+//
+// Doing this through the Fpdf.Image() function would mean that it uses a 72 DPI
+// value and stretches it to a 96 DPI value. This results in quality loss which
+// could be problematic for barcode scanners.
+func convertTo96Dpi(pdf barcodePdf, value float64) float64 {
+ return value * pdf.GetConversionRatio() / 72 * 96
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/contrib/ghostscript/ghostscript.go b/vendor/github.com/jung-kurt/gofpdf/contrib/ghostscript/ghostscript.go
new file mode 100644
index 0000000..3196c34
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/contrib/ghostscript/ghostscript.go
@@ -0,0 +1,68 @@
+package main
+
+// This command demonstrates the use of ghotscript to reduce the size
+// of generated PDFs. This is based on a comment made by farkerhaiku:
+// https://github.com/jung-kurt/gofpdf/issues/57#issuecomment-185843315
+
+import (
+ "fmt"
+ "os"
+ "os/exec"
+
+ "github.com/jung-kurt/gofpdf"
+)
+
+func report(fileStr string, err error) {
+ if err == nil {
+ var info os.FileInfo
+ info, err = os.Stat(fileStr)
+ if err == nil {
+ fmt.Printf("%s: OK, size %d\n", fileStr, info.Size())
+ } else {
+ fmt.Printf("%s: bad stat\n", fileStr)
+ }
+ } else {
+ fmt.Printf("%s: %s\n", fileStr, err)
+ }
+}
+
+func newPdf() (pdf *gofpdf.Fpdf) {
+ pdf = gofpdf.New("P", "mm", "A4", "../../font")
+ pdf.SetCompression(false)
+ pdf.AddFont("Calligrapher", "", "calligra.json")
+ pdf.AddPage()
+ pdf.SetFont("Calligrapher", "", 35)
+ pdf.Cell(0, 10, "Enjoy new fonts with FPDF!")
+ return
+}
+
+func full(name string) {
+ report(name, newPdf().OutputFileAndClose(name))
+}
+
+func min(name string) {
+ cmd := exec.Command("gs", "-sDEVICE=pdfwrite",
+ "-dCompatibilityLevel=1.4",
+ "-dPDFSETTINGS=/screen", "-dNOPAUSE", "-dQUIET",
+ "-dBATCH", "-sOutputFile="+name, "-")
+ inPipe, err := cmd.StdinPipe()
+ if err == nil {
+ errChan := make(chan error, 1)
+ go func() {
+ errChan <- cmd.Start()
+ }()
+ err = newPdf().Output(inPipe)
+ if err == nil {
+ report(name, <-errChan)
+ } else {
+ report(name, err)
+ }
+ } else {
+ report(name, err)
+ }
+}
+
+func main() {
+ full("full.pdf")
+ min("min.pdf")
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/contrib/httpimg/httpimg.go b/vendor/github.com/jung-kurt/gofpdf/contrib/httpimg/httpimg.go
new file mode 100644
index 0000000..7cbf281
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/contrib/httpimg/httpimg.go
@@ -0,0 +1,43 @@
+package httpimg
+
+import (
+ "io"
+ "net/http"
+
+ "github.com/jung-kurt/gofpdf"
+)
+
+// httpimgPdf is a partial interface that only implements the functions we need
+// from the PDF generator to put the HTTP images on the PDF.
+type httpimgPdf interface {
+ GetImageInfo(imageStr string) *gofpdf.ImageInfoType
+ ImageTypeFromMime(mimeStr string) string
+ RegisterImageReader(imgName, tp string, r io.Reader) *gofpdf.ImageInfoType
+ SetError(err error)
+}
+
+// Register registers a HTTP image. Downloading the image from the provided URL
+// and adding it to the PDF but not adding it to the page. Use Image() with the
+// same URL to add the image to the page.
+func Register(f httpimgPdf, urlStr, tp string) (info *gofpdf.ImageInfoType) {
+ info = f.GetImageInfo(urlStr)
+
+ if info != nil {
+ return
+ }
+
+ resp, err := http.Get(urlStr)
+
+ if err != nil {
+ f.SetError(err)
+ return
+ }
+
+ defer resp.Body.Close()
+
+ if tp == "" {
+ tp = f.ImageTypeFromMime(resp.Header["Content-Type"][0])
+ }
+
+ return f.RegisterImageReader(urlStr, tp, resp.Body)
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/contrib/tiff/tiff.go b/vendor/github.com/jung-kurt/gofpdf/contrib/tiff/tiff.go
new file mode 100644
index 0000000..3f13a38
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/contrib/tiff/tiff.go
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2016 Kurt Jung (Gmail: kurt.w.jung)
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+// Package tiff allows standard (LZW-compressed) TIFF images to be used in
+// documents generated with gofpdf.
+package tiff
+
+import (
+ "bytes"
+ "fmt"
+ "image"
+ "image/png"
+ "io"
+ "os"
+
+ "github.com/jung-kurt/gofpdf"
+ "golang.org/x/image/tiff"
+)
+
+// RegisterReader registers a TIFF image, adding it to the PDF file but not
+// adding it to the page. imgName specifies the name that will be used in the
+// call to Image() that actually places the image in the document. options
+// specifies various image properties; in this case, the ImageType property
+// should be set to "tiff". The TIFF image is a reader from the reader
+// specified by r.
+func RegisterReader(fpdf *gofpdf.Fpdf, imgName string, options gofpdf.ImageOptions, r io.Reader) (info *gofpdf.ImageInfoType) {
+ var err error
+ var img image.Image
+ var buf bytes.Buffer
+ if fpdf.Ok() {
+ if options.ImageType == "tiff" || options.ImageType == "tif" {
+ img, err = tiff.Decode(r)
+ if err == nil {
+ err = png.Encode(&buf, img)
+ if err == nil {
+ options.ImageType = "png"
+ info = fpdf.RegisterImageOptionsReader(imgName, options, &buf)
+ }
+ }
+ } else {
+ err = fmt.Errorf("expecting \"tiff\" or \"tif\" as image type, got \"%s\"", options.ImageType)
+ }
+ if err != nil {
+ fpdf.SetError(err)
+ }
+ }
+ return
+}
+
+// RegisterFile registers a TIFF image, adding it to the PDF file but not
+// adding it to the page. imgName specifies the name that will be used in the
+// call to Image() that actually places the image in the document. options
+// specifies various image properties; in this case, the ImageType property
+// should be set to "tiff". The TIFF image is read from the file specified by
+// tiffFileStr.
+func RegisterFile(fpdf *gofpdf.Fpdf, imgName string, options gofpdf.ImageOptions, tiffFileStr string) (info *gofpdf.ImageInfoType) {
+ var f *os.File
+ var err error
+
+ if fpdf.Ok() {
+ f, err = os.Open(tiffFileStr)
+ if err == nil {
+ info = RegisterReader(fpdf, imgName, options, f)
+ f.Close()
+ } else {
+ fpdf.SetError(err)
+ }
+ }
+ return
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/def.go b/vendor/github.com/jung-kurt/gofpdf/def.go
new file mode 100644
index 0000000..54abbd1
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/def.go
@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 2013-2014 Kurt Jung (Gmail: kurt.w.jung)
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package gofpdf
+
+import (
+ "bytes"
+ "io"
+ "time"
+)
+
+// Version of FPDF from which this package is derived
+const (
+ cnFpdfVersion = "1.7"
+)
+
+type blendModeType struct {
+ strokeStr, fillStr, modeStr string
+ objNum int
+}
+
+type gradientType struct {
+ tp int // 2: linear, 3: radial
+ clr1Str, clr2Str string
+ x1, y1, x2, y2, r float64
+ objNum int
+}
+
+// SizeType fields Wd and Ht specify the horizontal and vertical extents of a
+// document element such as a page.
+type SizeType struct {
+ Wd, Ht float64
+}
+
+// PointType fields X and Y specify the horizontal and vertical coordinates of
+// a point, typically used in drawing.
+type PointType struct {
+ X, Y float64
+}
+
+// XY returns the X and Y components of the receiver point.
+func (p PointType) XY() (float64, float64) {
+ return p.X, p.Y
+}
+
+// ImageInfoType contains size, color and other information about an image
+type ImageInfoType struct {
+ data []byte
+ smask []byte
+ i int
+ n int
+ w float64
+ h float64
+ cs string
+ pal []byte
+ bpc int
+ f string
+ dp string
+ trns []int
+ scale float64 // document scaling factor
+ dpi float64
+}
+
+// PointConvert returns the value of pt, expressed in points (1/72 inch), as a
+// value expressed in the unit of measure specified in New(). Since font
+// management in Fpdf uses points, this method can help with line height
+// calculations and other methods that require user units.
+func (f *Fpdf) PointConvert(pt float64) (u float64) {
+ return pt / f.k
+}
+
+// PointToUnitConvert is an alias for PointConvert.
+func (f *Fpdf) PointToUnitConvert(pt float64) (u float64) {
+ return pt / f.k
+}
+
+// UnitToPointConvert returns the value of u, expressed in the unit of measure
+// specified in New(), as a value expressed in points (1/72 inch). Since font
+// management in Fpdf uses points, this method can help with setting font sizes
+// based on the sizes of other non-font page elements.
+func (f *Fpdf) UnitToPointConvert(u float64) (pt float64) {
+ return u * f.k
+}
+
+// Extent returns the width and height of the image in the units of the Fpdf
+// object.
+func (info *ImageInfoType) Extent() (wd, ht float64) {
+ return info.Width(), info.Height()
+}
+
+// Width returns the width of the image in the units of the Fpdf object.
+func (info *ImageInfoType) Width() float64 {
+ return info.w / (info.scale * info.dpi / 72)
+}
+
+// Height returns the height of the image in the units of the Fpdf object.
+func (info *ImageInfoType) Height() float64 {
+ return info.h / (info.scale * info.dpi / 72)
+}
+
+// SetDpi sets the dots per inch for an image. PNG images MAY have their dpi
+// set automatically, if the image specifies it. DPI information is not
+// currently available automatically for JPG and GIF images, so if it's
+// important to you, you can set it here. It defaults to 72 dpi.
+func (info *ImageInfoType) SetDpi(dpi float64) {
+ info.dpi = dpi
+}
+
+type fontFileType struct {
+ length1, length2 int64
+ n int
+ embedded bool
+ content []byte
+}
+
+type linkType struct {
+ x, y, wd, ht float64
+ link int // Auto-generated internal link ID or...
+ linkStr string // ...application-provided external link string
+}
+
+type intLinkType struct {
+ page int
+ y float64
+}
+
+// outlineType is used for a sidebar outline of bookmarks
+type outlineType struct {
+ text string
+ level, parent, first, last, next, prev int
+ y float64
+ p int
+}
+
+// InitType is used with NewCustom() to customize an Fpdf instance.
+// OrientationStr, UnitStr, SizeStr and FontDirStr correspond to the arguments
+// accepted by New(). If the Wd and Ht fields of Size are each greater than
+// zero, Size will be used to set the default page size rather than SizeStr. Wd
+// and Ht are specified in the units of measure indicated by UnitStr.
+type InitType struct {
+ OrientationStr string
+ UnitStr string
+ SizeStr string
+ Size SizeType
+ FontDirStr string
+}
+
+// FontLoader is used to read fonts (JSON font specification and zlib compressed font binaries)
+// from arbitrary locations (e.g. files, zip files, embedded font resources).
+//
+// Open provides an io.Reader for the specified font file (.json or .z). The file name
+// never includes a path. Open returns an error if the specified file cannot be opened.
+type FontLoader interface {
+ Open(name string) (io.Reader, error)
+}
+
+// Fpdf is the principal structure for creating a single PDF document
+type Fpdf struct {
+ page int // current page number
+ n int // current object number
+ offsets []int // array of object offsets
+ templates map[int64]Template // templates used in this document
+ templateObjects map[int64]int // template object IDs within this document
+ buffer fmtBuffer // buffer holding in-memory PDF
+ pages []*bytes.Buffer // slice[page] of page content; 1-based
+ state int // current document state
+ compress bool // compression flag
+ k float64 // scale factor (number of points in user unit)
+ defOrientation string // default orientation
+ curOrientation string // current orientation
+ stdPageSizes map[string]SizeType // standard page sizes
+ defPageSize SizeType // default page size
+ curPageSize SizeType // current page size
+ pageSizes map[int]SizeType // used for pages with non default sizes or orientations
+ unitStr string // unit of measure for all rendered objects except fonts
+ wPt, hPt float64 // dimensions of current page in points
+ w, h float64 // dimensions of current page in user unit
+ lMargin float64 // left margin
+ tMargin float64 // top margin
+ rMargin float64 // right margin
+ bMargin float64 // page break margin
+ cMargin float64 // cell margin
+ x, y float64 // current position in user unit
+ lasth float64 // height of last printed cell
+ lineWidth float64 // line width in user unit
+ fontpath string // path containing fonts
+ fontLoader FontLoader // used to load font files from arbitrary locations
+ coreFonts map[string]bool // array of core font names
+ fonts map[string]fontDefType // array of used fonts
+ fontFiles map[string]fontFileType // array of font files
+ diffs []string // array of encoding differences
+ fontFamily string // current font family
+ fontStyle string // current font style
+ underline bool // underlining flag
+ currentFont fontDefType // current font info
+ fontSizePt float64 // current font size in points
+ fontSize float64 // current font size in user unit
+ ws float64 // word spacing
+ images map[string]*ImageInfoType // array of used images
+ pageLinks [][]linkType // pageLinks[page][link], both 1-based
+ links []intLinkType // array of internal links
+ outlines []outlineType // array of outlines
+ outlineRoot int // root of outlines
+ autoPageBreak bool // automatic page breaking
+ acceptPageBreak func() bool // returns true to accept page break
+ pageBreakTrigger float64 // threshold used to trigger page breaks
+ inHeader bool // flag set when processing header
+ headerFnc func() // function provided by app and called to write header
+ inFooter bool // flag set when processing footer
+ footerFnc func() // function provided by app and called to write footer
+ zoomMode string // zoom display mode
+ layoutMode string // layout display mode
+ title string // title
+ subject string // subject
+ author string // author
+ keywords string // keywords
+ creator string // creator
+ creationDate time.Time // override for dcoument CreationDate value
+ aliasNbPagesStr string // alias for total number of pages
+ pdfVersion string // PDF version number
+ fontDirStr string // location of font definition files
+ capStyle int // line cap style: butt 0, round 1, square 2
+ joinStyle int // line segment join style: miter 0, round 1, bevel 2
+ dashArray []float64 // dash array
+ dashPhase float64 // dash phase
+ blendList []blendModeType // slice[idx] of alpha transparency modes, 1-based
+ blendMap map[string]int // map into blendList
+ blendMode string // current blend mode
+ alpha float64 // current transpacency
+ gradientList []gradientType // slice[idx] of gradient records
+ clipNest int // Number of active clipping contexts
+ transformNest int // Number of active transformation contexts
+ err error // Set if error occurs during life cycle of instance
+ protect protectType // document protection structure
+ layer layerRecType // manages optional layers in document
+ catalogSort bool // sort resource catalogs in document
+ colorFlag bool // indicates whether fill and text colors are different
+ color struct {
+ // Composite values of colors
+ draw, fill, text clrType
+ }
+}
+
+type encType struct {
+ uv int
+ name string
+}
+
+type encListType [256]encType
+
+type fontBoxType struct {
+ Xmin, Ymin, Xmax, Ymax int
+}
+
+// Font flags for FontDescType.Flags as defined in the pdf specification.
+const (
+ // FontFlagFixedPitch is set if all glyphs have the same width (as
+ // opposed to proportional or variable-pitch fonts, which have
+ // different widths).
+ FontFlagFixedPitch = 1 << 0
+ // FontFlagSerif is set if glyphs have serifs, which are short
+ // strokes drawn at an angle on the top and bottom of glyph stems.
+ // (Sans serif fonts do not have serifs.)
+ FontFlagSerif = 1 << 1
+ // FontFlagSymbolic is set if font contains glyphs outside the
+ // Adobe standard Latin character set. This flag and the
+ // Nonsymbolic flag shall not both be set or both be clear.
+ FontFlagSymbolic = 1 << 2
+ // FontFlagScript is set if glyphs resemble cursive handwriting.
+ FontFlagScript = 1 << 3
+ // FontFlagNonsymbolic is set if font uses the Adobe standard
+ // Latin character set or a subset of it.
+ FontFlagNonsymbolic = 1 << 5
+ // FontFlagItalic is set if glyphs have dominant vertical strokes
+ // that are slanted.
+ FontFlagItalic = 1 << 6
+ // FontFlagAllCap is set if font contains no lowercase letters;
+ // typically used for display purposes, such as for titles or
+ // headlines.
+ FontFlagAllCap = 1 << 16
+ // SmallCap is set if font contains both uppercase and lowercase
+ // letters. The uppercase letters are similar to those in the
+ // regular version of the same typeface family. The glyphs for the
+ // lowercase letters have the same shapes as the corresponding
+ // uppercase letters, but they are sized and their proportions
+ // adjusted so that they have the same size and stroke weight as
+ // lowercase glyphs in the same typeface family.
+ SmallCap = 1 << 18
+ // ForceBold determines whether bold glyphs shall be painted with
+ // extra pixels even at very small text sizes by a conforming
+ // reader. If the ForceBold flag is set, features of bold glyphs
+ // may be thickened at small text sizes.
+ ForceBold = 1 << 18
+)
+
+// FontDescType (font descriptor) specifies metrics and other
+// attributes of a font, as distinct from the metrics of individual
+// glyphs (as defined in the pdf specification).
+type FontDescType struct {
+ // The maximum height above the baseline reached by glyphs in this
+ // font (for example for "S"). The height of glyphs for accented
+ // characters shall be excluded.
+ Ascent int
+ // The maximum depth below the baseline reached by glyphs in this
+ // font. The value shall be a negative number.
+ Descent int
+ // The vertical coordinate of the top of flat capital letters,
+ // measured from the baseline (for example "H").
+ CapHeight int
+ // A collection of flags defining various characteristics of the
+ // font. (See the FontFlag* constants.)
+ Flags int
+ // A rectangle, expressed in the glyph coordinate system, that
+ // shall specify the font bounding box. This should be the smallest
+ // rectangle enclosing the shape that would result if all of the
+ // glyphs of the font were placed with their origins coincident
+ // and then filled.
+ FontBBox fontBoxType
+ // The angle, expressed in degrees counterclockwise from the
+ // vertical, of the dominant vertical strokes of the font. (The
+ // 9-o’clock position is 90 degrees, and the 3-o’clock position
+ // is –90 degrees.) The value shall be negative for fonts that
+ // slope to the right, as almost all italic fonts do.
+ ItalicAngle int
+ // The thickness, measured horizontally, of the dominant vertical
+ // stems of glyphs in the font.
+ StemV int
+ // The width to use for character codes whose widths are not
+ // specified in a font dictionary’s Widths array. This shall have
+ // a predictable effect only if all such codes map to glyphs whose
+ // actual widths are the same as the value of the MissingWidth
+ // entry. (Default value: 0.)
+ MissingWidth int
+}
+
+type fontDefType struct {
+ Tp string // "Core", "TrueType", ...
+ Name string // "Courier-Bold", ...
+ Desc FontDescType // Font descriptor
+ Up int // Underline position
+ Ut int // Underline thickness
+ Cw [256]int // Character width by ordinal
+ Enc string // "cp1252", ...
+ Diff string // Differences from reference encoding
+ File string // "Redressed.z"
+ Size1, Size2 int // Type1 values
+ OriginalSize int // Size of uncompressed font file
+ I int // 1-based position in font list, set by font loader, not this program
+ N int // Set by font loader
+ DiffN int // Position of diff in app array, set by font loader
+}
+
+type fontInfoType struct {
+ Data []byte
+ File string
+ OriginalSize int
+ FontName string
+ Bold bool
+ IsFixedPitch bool
+ UnderlineThickness int
+ UnderlinePosition int
+ Widths [256]int
+ Size1, Size2 uint32
+ Desc FontDescType
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/doc.go b/vendor/github.com/jung-kurt/gofpdf/doc.go
new file mode 100644
index 0000000..a0af537
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/doc.go
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2013-2014 Kurt Jung (Gmail: kurt.w.jung)
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+Package gofpdf implements a PDF document generator with high level support for
+text, drawing and images.
+
+Features
+
+• Choice of measurement unit, page format and margins
+
+• Page header and footer management
+
+• Automatic page breaks, line breaks, and text justification
+
+• Inclusion of JPEG, PNG, GIF, TIFF and basic path-only SVG images
+
+• Colors, gradients and alpha channel transparency
+
+• Outline bookmarks
+
+• Internal and external links
+
+• TrueType, Type1 and encoding support
+
+• Page compression
+
+• Lines, Bézier curves, arcs, and ellipses
+
+• Rotation, scaling, skewing, translation, and mirroring
+
+• Clipping
+
+• Document protection
+
+• Layers
+
+• Templates
+
+gofpdf has no dependencies other than the Go standard library. All tests pass
+on Linux, Mac and Windows platforms. Like FPDF version 1.7, from which gofpdf
+is derived, this package does not yet support UTF-8 fonts. However, support is
+provided to translate UTF-8 runes to code page encodings.
+
+Installation
+
+To install the package on your system, run
+
+ go get github.com/jung-kurt/gofpdf
+
+Later, to receive updates, run
+
+ go get -u -v github.com/jung-kurt/gofpdf/...
+
+Quick Start
+
+The following Go code generates a simple PDF file.
+
+ pdf := gofpdf.New("P", "mm", "A4", "")
+ pdf.AddPage()
+ pdf.SetFont("Arial", "B", 16)
+ pdf.Cell(40, 10, "Hello, world")
+ err := pdf.OutputFileAndClose("hello.pdf")
+
+See the functions in the fpdf_test.go file (shown as examples in this
+documentation) for more advanced PDF examples.
+
+Errors
+
+If an error occurs in an Fpdf method, an internal error field is set. After
+this occurs, Fpdf method calls typically return without performing any
+operations and the error state is retained. This error management scheme
+facilitates PDF generation since individual method calls do not need to be
+examined for failure; it is generally sufficient to wait until after Output()
+is called. For the same reason, if an error occurs in the calling application
+during PDF generation, it may be desirable for the application to transfer the
+error to the Fpdf instance by calling the SetError() method or the SetErrorf()
+method. At any time during the life cycle of the Fpdf instance, the error state
+can be determined with a call to Ok() or Err(). The error itself can be
+retrieved with a call to Error().
+
+Conversion Notes
+
+This package is a relatively straightforward translation from the original FPDF
+library written in PHP (despite the caveat in the introduction to Effective
+Go). The API names have been retained even though the Go idiom would suggest
+otherwise (for example, pdf.GetX() is used rather than simply pdf.X()). The
+similarity of the two libraries makes the original FPDF website a good source
+of information. It includes a forum and FAQ.
+
+However, some internal changes have been made. Page content is built up using
+buffers (of type bytes.Buffer) rather than repeated string concatenation.
+Errors are handled as explained above rather than panicking. Output is
+generated through an interface of type io.Writer or io.WriteCloser. A number of
+the original PHP methods behave differently based on the type of the arguments
+that are passed to them; in these cases additional methods have been exported
+to provide similar functionality. Font definition files are produced in JSON
+rather than PHP.
+
+Example PDFs
+
+A side effect of running "go test ./..." is the production of a number of
+example PDFs. These can be found in the gofpdf/pdf directory after the tests
+complete.
+
+Please note that these examples run in the context of a test. In order run an
+example as a standalone application, you'll need to examine fpdf_test.go for
+some helper routines, for example exampleFilename() and summary().
+
+Example PDFs can be compared with reference copies in order to verify that they
+have been generated as expected. This comparison will be performed if a PDF
+with the same name as the example PDF is placed in the gofpdf/pdf/reference
+directory. The routine that summarizes an example will look for this file and,
+if found, will call ComparePDFFiles() to check the example PDF for equality
+with its reference PDF. If differences exist between the two files they will be
+printed to standard output and the test will fail. If the reference file is
+missing, the comparison is considered to succeed. In order to successfully
+compare two PDFs, the placement of internal resources must be consistent and
+the internal creation timestamps must be the same. To do this, the methods
+SetCatalogSort() and SetCreationDate() need to be called for both files. This
+is done automatically for all examples.
+
+Nonstandard Fonts
+
+Nothing special is required to use the standard PDF fonts (courier, helvetica,
+times, zapfdingbats) in your documents other than calling SetFont().
+
+In order to use a different TrueType or Type1 font, you will need to generate a
+font definition file and, if the font will be embedded into PDFs, a compressed
+version of the font file. This is done by calling the MakeFont function or
+using the included makefont command line utility. To create the utility, cd
+into the makefont subdirectory and run "go build". This will produce a
+standalone executable named makefont. Select the appropriate encoding file from
+the font subdirectory and run the command as in the following example.
+
+ ./makefont --embed --enc=../font/cp1252.map --dst=../font ../font/calligra.ttf
+
+In your PDF generation code, call AddFont() to load the font and, as with the
+standard fonts, SetFont() to begin using it. Most examples, including the
+package example, demonstrate this method. Good sources of free, open-source
+fonts include http://www.google.com/fonts/ and http://dejavu-fonts.org/.
+
+Related Packages
+
+The draw2d package (https://github.com/llgcode/draw2d) is a two dimensional
+vector graphics library that can generate output in different forms. It uses
+gofpdf for its document production mode.
+
+Contributing Changes
+
+gofpdf is a global community effort and you are invited to make it even better.
+If you have implemented a new feature or corrected a problem, please consider
+contributing your change to the project. A contribution that does not directly
+pertain to the core functionality of gofpdf should be placed in its own
+directory directly beneath the `contrib` directory.
+
+Here are guidelines for making submissions. Your change should
+
+• be compatible with the MIT License
+
+• be properly documented
+
+• be formatted with `go fmt`
+
+• include an example in fpdf_test.go if appropriate
+
+• conform to the standards of golint (https://github.com/golang/lint) and
+go vet (https://godoc.org/golang.org/x/tools/cmd/vet), that is, `golint .` and
+`go vet .` should not generate any warnings
+
+• not diminish test coverage (https://blog.golang.org/cover)
+
+Pull requests (https://help.github.com/articles/using-pull-requests/) work
+nicely as a means of contributing your changes.
+
+License
+
+gofpdf is released under the MIT License. It is copyrighted by Kurt Jung and
+the contributors acknowledged below.
+
+Acknowledgments
+
+This package's code and documentation are closely derived from the FPDF library
+(http://www.fpdf.org/) created by Olivier Plathey, and a number of font and
+image resources are copied directly from it. Drawing support is adapted from
+the FPDF geometric figures script by David Hernández Sanz. Transparency
+support is adapted from the FPDF transparency script by Martin Hall-May.
+Support for gradients and clipping is adapted from FPDF scripts by Andreas
+Würmser. Support for outline bookmarks is adapted from Olivier Plathey by
+Manuel Cornes. Layer support is adapted from Olivier Plathey. Support for
+transformations is adapted from the FPDF transformation script by Moritz Wagner
+and Andreas Würmser. PDF protection is adapted from the work of Klemen
+Vodopivec for the FPDF product. Lawrence Kesteloot provided code to allow an
+image's extent to be determined prior to placement. Support for vertical
+alignment within a cell was provided by Stefan Schroeder. Ivan Daniluk
+generalized the font and image loading code to use the Reader interface while
+maintaining backward compatibility. Anthony Starks provided code for the
+Polygon function. Robert Lillack provided the Beziergon function and corrected
+some naming issues with the internal curve function. Claudio Felber provided
+implementations for dashed line drawing and generalized font loading. Stani
+Michiels provided support for multi-segment path drawing with smooth line
+joins, line join styles, enhanced fill modes, and has helped greatly with
+package presentation and tests. Templating is adapted by Marcus Downing from
+the FPDF_Tpl library created by Jan Slabon and Setasign. Jelmer Snoeck
+contributed packages that generate a variety of barcodes and help with
+registering images on the web. Additionally, he augmented the basic HTML
+functionality with aligned text. Kent Quirk implemented backwards-compatible
+support for reading DPI from images that support it, and for setting DPI
+manually and then having it properly taken into account when calculating image
+size. Paulo Coutinho provided support for static embedded fonts. Bruno Michel
+has provided valuable assistance with the code.
+
+Roadmap
+
+• Handle UTF-8 source text natively. Until then, automatic translation of
+UTF-8 runes to code page bytes is provided.
+
+• Improve test coverage as reported by the coverage tool.
+
+*/
+package gofpdf
diff --git a/vendor/github.com/jung-kurt/gofpdf/embedded.go b/vendor/github.com/jung-kurt/gofpdf/embedded.go
new file mode 100644
index 0000000..1d947b0
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/embedded.go
@@ -0,0 +1,559 @@
+/*
+ * Copyright (c) 2014 Kurt Jung (Gmail: kurt.w.jung)
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package gofpdf
+
+// Embedded standard fonts
+
+import (
+ "strings"
+)
+
+var embeddedFontList = map[string]string{
+ "courierBI": `{"Tp":"Core","Name":"Courier-BoldOblique","Up":-100,"Ut":50,"I":256,"Cw":[600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600]}`,
+ "courierB": `{"Tp":"Core","Name":"Courier-Bold","Up":-100,"Ut":50,"I":256,"Cw":[600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600]}`,
+ "courierI": `{"Tp":"Core","Name":"Courier-Oblique","Up":-100,"Ut":50,"I":256,"Cw":[600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600]}`,
+ "courier": `{"Tp":"Core","Name":"Courier","Up":-100,"Ut":50,"I":256,"Cw":[600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600]}`,
+ "helveticaBI": `{"Tp":"Core","Name":"Helvetica-BoldOblique","Up":-100,"Ut":50,"Cw":[278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,333,474,556,556,889,722,238,333,333,389,584,278,333,278,278,556,556,556,556,556,556,556,556,556,556,333,333,584,584,584,611,975,722,722,722,722,667,611,778,722,278,556,722,611,833,722,778,667,778,722,667,611,722,667,944,667,667,611,333,278,333,584,556,333,556,611,556,611,556,333,611,611,278,278,556,278,889,611,611,611,611,389,556,333,611,556,778,556,556,500,389,280,389,584,350,556,350,278,556,500,1000,556,556,333,1000,667,333,1000,350,611,350,350,278,278,500,500,350,556,1000,333,1000,556,333,944,350,500,667,278,333,556,556,556,556,280,556,333,737,370,556,584,333,737,333,400,584,333,333,333,611,556,278,333,333,365,556,834,834,834,611,722,722,722,722,722,722,1000,722,667,667,667,667,278,278,278,278,722,722,778,778,778,778,778,584,778,722,722,722,722,667,667,611,556,556,556,556,556,556,889,556,556,556,556,556,278,278,278,278,611,611,611,611,611,611,611,584,611,611,611,611,611,556,611,556]}`,
+ "helveticaB": `{"Tp":"Core","Name":"Helvetica-Bold","Up":-100,"Ut":50,"Cw":[278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,333,474,556,556,889,722,238,333,333,389,584,278,333,278,278,556,556,556,556,556,556,556,556,556,556,333,333,584,584,584,611,975,722,722,722,722,667,611,778,722,278,556,722,611,833,722,778,667,778,722,667,611,722,667,944,667,667,611,333,278,333,584,556,333,556,611,556,611,556,333,611,611,278,278,556,278,889,611,611,611,611,389,556,333,611,556,778,556,556,500,389,280,389,584,350,556,350,278,556,500,1000,556,556,333,1000,667,333,1000,350,611,350,350,278,278,500,500,350,556,1000,333,1000,556,333,944,350,500,667,278,333,556,556,556,556,280,556,333,737,370,556,584,333,737,333,400,584,333,333,333,611,556,278,333,333,365,556,834,834,834,611,722,722,722,722,722,722,1000,722,667,667,667,667,278,278,278,278,722,722,778,778,778,778,778,584,778,722,722,722,722,667,667,611,556,556,556,556,556,556,889,556,556,556,556,556,278,278,278,278,611,611,611,611,611,611,611,584,611,611,611,611,611,556,611,556]}`,
+ "helveticaI": `{"Tp":"Core","Name":"Helvetica-Oblique","Up":-100,"Ut":50,"Cw":[278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,355,556,556,889,667,191,333,333,389,584,278,333,278,278,556,556,556,556,556,556,556,556,556,556,278,278,584,584,584,556,1015,667,667,722,722,667,611,778,722,278,500,667,556,833,722,778,667,778,722,667,611,722,667,944,667,667,611,278,278,278,469,556,333,556,556,500,556,556,278,556,556,222,222,500,222,833,556,556,556,556,333,500,278,556,500,722,500,500,500,334,260,334,584,350,556,350,222,556,333,1000,556,556,333,1000,667,333,1000,350,611,350,350,222,222,333,333,350,556,1000,333,1000,500,333,944,350,500,667,278,333,556,556,556,556,260,556,333,737,370,556,584,333,737,333,400,584,333,333,333,556,537,278,333,333,365,556,834,834,834,611,667,667,667,667,667,667,1000,722,667,667,667,667,278,278,278,278,722,722,778,778,778,778,778,584,778,722,722,722,722,667,667,611,556,556,556,556,556,556,889,500,556,556,556,556,278,278,278,278,556,556,556,556,556,556,556,584,611,556,556,556,556,500,556,500]}`,
+ "helvetica": `{"Tp":"Core","Name":"Helvetica","Up":-100,"Ut":50,"Cw":[278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,355,556,556,889,667,191,333,333,389,584,278,333,278,278,556,556,556,556,556,556,556,556,556,556,278,278,584,584,584,556,1015,667,667,722,722,667,611,778,722,278,500,667,556,833,722,778,667,778,722,667,611,722,667,944,667,667,611,278,278,278,469,556,333,556,556,500,556,556,278,556,556,222,222,500,222,833,556,556,556,556,333,500,278,556,500,722,500,500,500,334,260,334,584,350,556,350,222,556,333,1000,556,556,333,1000,667,333,1000,350,611,350,350,222,222,333,333,350,556,1000,333,1000,500,333,944,350,500,667,278,333,556,556,556,556,260,556,333,737,370,556,584,333,737,333,400,584,333,333,333,556,537,278,333,333,365,556,834,834,834,611,667,667,667,667,667,667,1000,722,667,667,667,667,278,278,278,278,722,722,778,778,778,778,778,584,778,722,722,722,722,667,667,611,556,556,556,556,556,556,889,500,556,556,556,556,278,278,278,278,556,556,556,556,556,556,556,584,611,556,556,556,556,500,556,500]}`,
+ "timesBI": `{"Tp":"Core","Name":"Times-BoldItalic","Up":-100,"Ut":50,"Cw":[250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,389,555,500,500,833,778,278,333,333,500,570,250,333,250,278,500,500,500,500,500,500,500,500,500,500,333,333,570,570,570,500,832,667,667,667,722,667,667,722,778,389,500,667,611,889,722,722,611,722,667,556,611,722,667,889,667,611,611,333,278,333,570,500,333,500,500,444,500,444,333,500,556,278,278,500,278,778,556,500,500,500,389,389,278,556,444,667,500,444,389,348,220,348,570,350,500,350,333,500,500,1000,500,500,333,1000,556,333,944,350,611,350,350,333,333,500,500,350,500,1000,333,1000,389,333,722,350,389,611,250,389,500,500,500,500,220,500,333,747,266,500,606,333,747,333,400,570,300,300,333,576,500,250,333,300,300,500,750,750,750,500,667,667,667,667,667,667,944,667,667,667,667,667,389,389,389,389,722,722,722,722,722,722,722,570,722,722,722,722,722,611,611,500,500,500,500,500,500,500,722,444,444,444,444,444,278,278,278,278,500,556,500,500,500,500,500,570,500,556,556,556,556,444,500,444]}`,
+ "timesB": `{"Tp":"Core","Name":"Times-Bold","Up":-100,"Ut":50,"Cw":[250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,333,555,500,500,1000,833,278,333,333,500,570,250,333,250,278,500,500,500,500,500,500,500,500,500,500,333,333,570,570,570,500,930,722,667,722,722,667,611,778,778,389,500,778,667,944,722,778,611,778,722,556,667,722,722,1000,722,722,667,333,278,333,581,500,333,500,556,444,556,444,333,500,556,278,333,556,278,833,556,500,556,556,444,389,333,556,500,722,500,500,444,394,220,394,520,350,500,350,333,500,500,1000,500,500,333,1000,556,333,1000,350,667,350,350,333,333,500,500,350,500,1000,333,1000,389,333,722,350,444,722,250,333,500,500,500,500,220,500,333,747,300,500,570,333,747,333,400,570,300,300,333,556,540,250,333,300,330,500,750,750,750,500,722,722,722,722,722,722,1000,722,667,667,667,667,389,389,389,389,722,722,778,778,778,778,778,570,778,722,722,722,722,722,611,556,500,500,500,500,500,500,722,444,444,444,444,444,278,278,278,278,500,556,500,500,500,500,500,570,500,556,556,556,556,500,556,500]}`,
+ "timesI": `{"Tp":"Core","Name":"Times-Italic","Up":-100,"Ut":50,"Cw":[250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,333,420,500,500,833,778,214,333,333,500,675,250,333,250,278,500,500,500,500,500,500,500,500,500,500,333,333,675,675,675,500,920,611,611,667,722,611,611,722,722,333,444,667,556,833,667,722,611,722,611,500,556,722,611,833,611,556,556,389,278,389,422,500,333,500,500,444,500,444,278,500,500,278,278,444,278,722,500,500,500,500,389,389,278,500,444,667,444,444,389,400,275,400,541,350,500,350,333,500,556,889,500,500,333,1000,500,333,944,350,556,350,350,333,333,556,556,350,500,889,333,980,389,333,667,350,389,556,250,389,500,500,500,500,275,500,333,760,276,500,675,333,760,333,400,675,300,300,333,500,523,250,333,300,310,500,750,750,750,500,611,611,611,611,611,611,889,667,611,611,611,611,333,333,333,333,722,667,722,722,722,722,722,675,722,722,722,722,722,556,611,500,500,500,500,500,500,500,667,444,444,444,444,444,278,278,278,278,500,500,500,500,500,500,500,675,500,500,500,500,500,444,500,444]}`,
+ "times": `{"Tp":"Core","Name":"Times-Roman","Up":-100,"Ut":50,"Cw":[250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,333,408,500,500,833,778,180,333,333,500,564,250,333,250,278,500,500,500,500,500,500,500,500,500,500,278,278,564,564,564,444,921,722,667,667,722,611,556,722,722,333,389,722,611,889,722,722,556,722,667,556,611,722,722,944,722,722,611,333,278,333,469,500,333,444,500,444,500,444,333,500,500,278,278,500,278,778,500,500,500,500,333,389,278,500,500,722,500,500,444,480,200,480,541,350,500,350,333,500,444,1000,500,500,333,1000,556,333,889,350,611,350,350,333,333,444,444,350,500,1000,333,980,389,333,722,350,444,722,250,333,500,500,500,500,200,500,333,760,276,500,564,333,760,333,400,564,300,300,333,500,453,250,333,300,310,500,750,750,750,444,722,722,722,722,722,722,889,667,611,611,611,611,333,333,333,333,722,722,722,722,722,722,722,564,722,722,722,722,722,722,556,500,444,444,444,444,444,444,667,444,444,444,444,444,278,278,278,278,500,500,500,500,500,500,500,564,500,500,500,500,500,500,500,500]}`,
+ "zapfdingbats": `{"Tp":"Core","Name":"ZapfDingbats","Up":-100,"Ut":50,"Cw":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,278,974,961,974,980,719,789,790,791,690,960,939,549,855,911,933,911,945,974,755,846,762,761,571,677,763,760,759,754,494,552,537,577,692,786,788,788,790,793,794,816,823,789,841,823,833,816,831,923,744,723,749,790,792,695,776,768,792,759,707,708,682,701,826,815,789,789,707,687,696,689,786,787,713,791,785,791,873,761,762,762,759,759,892,892,788,784,438,138,277,415,392,392,668,668,0,390,390,317,317,276,276,509,509,410,410,234,234,334,334,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,732,544,544,910,667,760,760,776,595,694,626,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,894,838,1016,458,748,924,748,918,927,928,928,834,873,828,924,924,917,930,931,463,883,836,836,867,867,696,696,874,0,874,760,946,771,865,771,888,967,888,831,873,927,970,918,0]}`,
+}
+
+func (f *Fpdf) coreFontReader(familyStr, styleStr string) (r *strings.Reader) {
+ key := familyStr + styleStr
+ str, ok := embeddedFontList[key]
+ if ok {
+ r = strings.NewReader(str)
+ } else {
+ f.SetErrorf("could not locate \"%s\" among embedded core font definition files", key)
+ }
+ return
+}
+
+var embeddedMapList = map[string]string{
+ "cp1250": `
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+20AC Euro
+!82 U+201A quotesinglbase
+!84 U+201E quotedblbase
+!85 U+2026 ellipsis
+!86 U+2020 dagger
+!87 U+2021 daggerdbl
+!89 U+2030 perthousand
+!8A U+0160 Scaron
+!8B U+2039 guilsinglleft
+!8C U+015A Sacute
+!8D U+0164 Tcaron
+!8E U+017D Zcaron
+!8F U+0179 Zacute
+!91 U+2018 quoteleft
+!92 U+2019 quoteright
+!93 U+201C quotedblleft
+!94 U+201D quotedblright
+!95 U+2022 bullet
+!96 U+2013 endash
+!97 U+2014 emdash
+!99 U+2122 trademark
+!9A U+0161 scaron
+!9B U+203A guilsinglright
+!9C U+015B sacute
+!9D U+0165 tcaron
+!9E U+017E zcaron
+!9F U+017A zacute
+!A0 U+00A0 space
+!A1 U+02C7 caron
+!A2 U+02D8 breve
+!A3 U+0141 Lslash
+!A4 U+00A4 currency
+!A5 U+0104 Aogonek
+!A6 U+00A6 brokenbar
+!A7 U+00A7 section
+!A8 U+00A8 dieresis
+!A9 U+00A9 copyright
+!AA U+015E Scedilla
+!AB U+00AB guillemotleft
+!AC U+00AC logicalnot
+!AD U+00AD hyphen
+!AE U+00AE registered
+!AF U+017B Zdotaccent
+!B0 U+00B0 degree
+!B1 U+00B1 plusminus
+!B2 U+02DB ogonek
+!B3 U+0142 lslash
+!B4 U+00B4 acute
+!B5 U+00B5 mu
+!B6 U+00B6 paragraph
+!B7 U+00B7 periodcentered
+!B8 U+00B8 cedilla
+!B9 U+0105 aogonek
+!BA U+015F scedilla
+!BB U+00BB guillemotright
+!BC U+013D Lcaron
+!BD U+02DD hungarumlaut
+!BE U+013E lcaron
+!BF U+017C zdotaccent
+!C0 U+0154 Racute
+!C1 U+00C1 Aacute
+!C2 U+00C2 Acircumflex
+!C3 U+0102 Abreve
+!C4 U+00C4 Adieresis
+!C5 U+0139 Lacute
+!C6 U+0106 Cacute
+!C7 U+00C7 Ccedilla
+!C8 U+010C Ccaron
+!C9 U+00C9 Eacute
+!CA U+0118 Eogonek
+!CB U+00CB Edieresis
+!CC U+011A Ecaron
+!CD U+00CD Iacute
+!CE U+00CE Icircumflex
+!CF U+010E Dcaron
+!D0 U+0110 Dcroat
+!D1 U+0143 Nacute
+!D2 U+0147 Ncaron
+!D3 U+00D3 Oacute
+!D4 U+00D4 Ocircumflex
+!D5 U+0150 Ohungarumlaut
+!D6 U+00D6 Odieresis
+!D7 U+00D7 multiply
+!D8 U+0158 Rcaron
+!D9 U+016E Uring
+!DA U+00DA Uacute
+!DB U+0170 Uhungarumlaut
+!DC U+00DC Udieresis
+!DD U+00DD Yacute
+!DE U+0162 Tcommaaccent
+!DF U+00DF germandbls
+!E0 U+0155 racute
+!E1 U+00E1 aacute
+!E2 U+00E2 acircumflex
+!E3 U+0103 abreve
+!E4 U+00E4 adieresis
+!E5 U+013A lacute
+!E6 U+0107 cacute
+!E7 U+00E7 ccedilla
+!E8 U+010D ccaron
+!E9 U+00E9 eacute
+!EA U+0119 eogonek
+!EB U+00EB edieresis
+!EC U+011B ecaron
+!ED U+00ED iacute
+!EE U+00EE icircumflex
+!EF U+010F dcaron
+!F0 U+0111 dcroat
+!F1 U+0144 nacute
+!F2 U+0148 ncaron
+!F3 U+00F3 oacute
+!F4 U+00F4 ocircumflex
+!F5 U+0151 ohungarumlaut
+!F6 U+00F6 odieresis
+!F7 U+00F7 divide
+!F8 U+0159 rcaron
+!F9 U+016F uring
+!FA U+00FA uacute
+!FB U+0171 uhungarumlaut
+!FC U+00FC udieresis
+!FD U+00FD yacute
+!FE U+0163 tcommaaccent
+!FF U+02D9 dotaccent
+ `,
+ "cp1252": `
+!00 U+0000 .notdef
+!01 U+0001 .notdef
+!02 U+0002 .notdef
+!03 U+0003 .notdef
+!04 U+0004 .notdef
+!05 U+0005 .notdef
+!06 U+0006 .notdef
+!07 U+0007 .notdef
+!08 U+0008 .notdef
+!09 U+0009 .notdef
+!0A U+000A .notdef
+!0B U+000B .notdef
+!0C U+000C .notdef
+!0D U+000D .notdef
+!0E U+000E .notdef
+!0F U+000F .notdef
+!10 U+0010 .notdef
+!11 U+0011 .notdef
+!12 U+0012 .notdef
+!13 U+0013 .notdef
+!14 U+0014 .notdef
+!15 U+0015 .notdef
+!16 U+0016 .notdef
+!17 U+0017 .notdef
+!18 U+0018 .notdef
+!19 U+0019 .notdef
+!1A U+001A .notdef
+!1B U+001B .notdef
+!1C U+001C .notdef
+!1D U+001D .notdef
+!1E U+001E .notdef
+!1F U+001F .notdef
+!20 U+0020 space
+!21 U+0021 exclam
+!22 U+0022 quotedbl
+!23 U+0023 numbersign
+!24 U+0024 dollar
+!25 U+0025 percent
+!26 U+0026 ampersand
+!27 U+0027 quotesingle
+!28 U+0028 parenleft
+!29 U+0029 parenright
+!2A U+002A asterisk
+!2B U+002B plus
+!2C U+002C comma
+!2D U+002D hyphen
+!2E U+002E period
+!2F U+002F slash
+!30 U+0030 zero
+!31 U+0031 one
+!32 U+0032 two
+!33 U+0033 three
+!34 U+0034 four
+!35 U+0035 five
+!36 U+0036 six
+!37 U+0037 seven
+!38 U+0038 eight
+!39 U+0039 nine
+!3A U+003A colon
+!3B U+003B semicolon
+!3C U+003C less
+!3D U+003D equal
+!3E U+003E greater
+!3F U+003F question
+!40 U+0040 at
+!41 U+0041 A
+!42 U+0042 B
+!43 U+0043 C
+!44 U+0044 D
+!45 U+0045 E
+!46 U+0046 F
+!47 U+0047 G
+!48 U+0048 H
+!49 U+0049 I
+!4A U+004A J
+!4B U+004B K
+!4C U+004C L
+!4D U+004D M
+!4E U+004E N
+!4F U+004F O
+!50 U+0050 P
+!51 U+0051 Q
+!52 U+0052 R
+!53 U+0053 S
+!54 U+0054 T
+!55 U+0055 U
+!56 U+0056 V
+!57 U+0057 W
+!58 U+0058 X
+!59 U+0059 Y
+!5A U+005A Z
+!5B U+005B bracketleft
+!5C U+005C backslash
+!5D U+005D bracketright
+!5E U+005E asciicircum
+!5F U+005F underscore
+!60 U+0060 grave
+!61 U+0061 a
+!62 U+0062 b
+!63 U+0063 c
+!64 U+0064 d
+!65 U+0065 e
+!66 U+0066 f
+!67 U+0067 g
+!68 U+0068 h
+!69 U+0069 i
+!6A U+006A j
+!6B U+006B k
+!6C U+006C l
+!6D U+006D m
+!6E U+006E n
+!6F U+006F o
+!70 U+0070 p
+!71 U+0071 q
+!72 U+0072 r
+!73 U+0073 s
+!74 U+0074 t
+!75 U+0075 u
+!76 U+0076 v
+!77 U+0077 w
+!78 U+0078 x
+!79 U+0079 y
+!7A U+007A z
+!7B U+007B braceleft
+!7C U+007C bar
+!7D U+007D braceright
+!7E U+007E asciitilde
+!7F U+007F .notdef
+!80 U+20AC Euro
+!82 U+201A quotesinglbase
+!83 U+0192 florin
+!84 U+201E quotedblbase
+!85 U+2026 ellipsis
+!86 U+2020 dagger
+!87 U+2021 daggerdbl
+!88 U+02C6 circumflex
+!89 U+2030 perthousand
+!8A U+0160 Scaron
+!8B U+2039 guilsinglleft
+!8C U+0152 OE
+!8E U+017D Zcaron
+!91 U+2018 quoteleft
+!92 U+2019 quoteright
+!93 U+201C quotedblleft
+!94 U+201D quotedblright
+!95 U+2022 bullet
+!96 U+2013 endash
+!97 U+2014 emdash
+!98 U+02DC tilde
+!99 U+2122 trademark
+!9A U+0161 scaron
+!9B U+203A guilsinglright
+!9C U+0153 oe
+!9E U+017E zcaron
+!9F U+0178 Ydieresis
+!A0 U+00A0 space
+!A1 U+00A1 exclamdown
+!A2 U+00A2 cent
+!A3 U+00A3 sterling
+!A4 U+00A4 currency
+!A5 U+00A5 yen
+!A6 U+00A6 brokenbar
+!A7 U+00A7 section
+!A8 U+00A8 dieresis
+!A9 U+00A9 copyright
+!AA U+00AA ordfeminine
+!AB U+00AB guillemotleft
+!AC U+00AC logicalnot
+!AD U+00AD hyphen
+!AE U+00AE registered
+!AF U+00AF macron
+!B0 U+00B0 degree
+!B1 U+00B1 plusminus
+!B2 U+00B2 twosuperior
+!B3 U+00B3 threesuperior
+!B4 U+00B4 acute
+!B5 U+00B5 mu
+!B6 U+00B6 paragraph
+!B7 U+00B7 periodcentered
+!B8 U+00B8 cedilla
+!B9 U+00B9 onesuperior
+!BA U+00BA ordmasculine
+!BB U+00BB guillemotright
+!BC U+00BC onequarter
+!BD U+00BD onehalf
+!BE U+00BE threequarters
+!BF U+00BF questiondown
+!C0 U+00C0 Agrave
+!C1 U+00C1 Aacute
+!C2 U+00C2 Acircumflex
+!C3 U+00C3 Atilde
+!C4 U+00C4 Adieresis
+!C5 U+00C5 Aring
+!C6 U+00C6 AE
+!C7 U+00C7 Ccedilla
+!C8 U+00C8 Egrave
+!C9 U+00C9 Eacute
+!CA U+00CA Ecircumflex
+!CB U+00CB Edieresis
+!CC U+00CC Igrave
+!CD U+00CD Iacute
+!CE U+00CE Icircumflex
+!CF U+00CF Idieresis
+!D0 U+00D0 Eth
+!D1 U+00D1 Ntilde
+!D2 U+00D2 Ograve
+!D3 U+00D3 Oacute
+!D4 U+00D4 Ocircumflex
+!D5 U+00D5 Otilde
+!D6 U+00D6 Odieresis
+!D7 U+00D7 multiply
+!D8 U+00D8 Oslash
+!D9 U+00D9 Ugrave
+!DA U+00DA Uacute
+!DB U+00DB Ucircumflex
+!DC U+00DC Udieresis
+!DD U+00DD Yacute
+!DE U+00DE Thorn
+!DF U+00DF germandbls
+!E0 U+00E0 agrave
+!E1 U+00E1 aacute
+!E2 U+00E2 acircumflex
+!E3 U+00E3 atilde
+!E4 U+00E4 adieresis
+!E5 U+00E5 aring
+!E6 U+00E6 ae
+!E7 U+00E7 ccedilla
+!E8 U+00E8 egrave
+!E9 U+00E9 eacute
+!EA U+00EA ecircumflex
+!EB U+00EB edieresis
+!EC U+00EC igrave
+!ED U+00ED iacute
+!EE U+00EE icircumflex
+!EF U+00EF idieresis
+!F0 U+00F0 eth
+!F1 U+00F1 ntilde
+!F2 U+00F2 ograve
+!F3 U+00F3 oacute
+!F4 U+00F4 ocircumflex
+!F5 U+00F5 otilde
+!F6 U+00F6 odieresis
+!F7 U+00F7 divide
+!F8 U+00F8 oslash
+!F9 U+00F9 ugrave
+!FA U+00FA uacute
+!FB U+00FB ucircumflex
+!FC U+00FC udieresis
+!FD U+00FD yacute
+!FE U+00FE thorn
+!FF U+00FF ydieresis
+ `,
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/font.go b/vendor/github.com/jung-kurt/gofpdf/font.go
new file mode 100644
index 0000000..35f59f1
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/font.go
@@ -0,0 +1,456 @@
+/*
+ * Copyright (c) 2013 Kurt Jung (Gmail: kurt.w.jung)
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package gofpdf
+
+// Utility to generate font definition files
+
+// Version: 1.2
+// Date: 2011-06-18
+// Author: Olivier PLATHEY
+// Port to Go: Kurt Jung, 2013-07-15
+
+import (
+ "bufio"
+ "compress/zlib"
+ "encoding/binary"
+ "encoding/json"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strconv"
+ "strings"
+)
+
+func baseNoExt(fileStr string) string {
+ str := filepath.Base(fileStr)
+ extLen := len(filepath.Ext(str))
+ if extLen > 0 {
+ str = str[:len(str)-extLen]
+ }
+ return str
+}
+
+func loadMap(encodingFileStr string) (encList encListType, err error) {
+ // printf("Encoding file string [%s]\n", encodingFileStr)
+ var f *os.File
+ // f, err = os.Open(encodingFilepath(encodingFileStr))
+ f, err = os.Open(encodingFileStr)
+ if err == nil {
+ defer f.Close()
+ for j := range encList {
+ encList[j].uv = -1
+ encList[j].name = ".notdef"
+ }
+ scanner := bufio.NewScanner(f)
+ var enc encType
+ var pos int
+ for scanner.Scan() {
+ // "!3F U+003F question"
+ _, err = fmt.Sscanf(scanner.Text(), "!%x U+%x %s", &pos, &enc.uv, &enc.name)
+ if err == nil {
+ if pos < 256 {
+ encList[pos] = enc
+ } else {
+ err = fmt.Errorf("map position 0x%2X exceeds 0xFF", pos)
+ return
+ }
+ } else {
+ return
+ }
+ }
+ if err = scanner.Err(); err != nil {
+ return
+ }
+ }
+ return
+}
+
+// Return informations from a TrueType font
+func getInfoFromTrueType(fileStr string, msgWriter io.Writer, embed bool, encList encListType) (info fontInfoType, err error) {
+ var ttf TtfType
+ ttf, err = TtfParse(fileStr)
+ if err != nil {
+ return
+ }
+ if embed {
+ if !ttf.Embeddable {
+ err = fmt.Errorf("font license does not allow embedding")
+ return
+ }
+ info.Data, err = ioutil.ReadFile(fileStr)
+ if err != nil {
+ return
+ }
+ info.OriginalSize = len(info.Data)
+ }
+ k := 1000.0 / float64(ttf.UnitsPerEm)
+ info.FontName = ttf.PostScriptName
+ info.Bold = ttf.Bold
+ info.Desc.ItalicAngle = int(ttf.ItalicAngle)
+ info.IsFixedPitch = ttf.IsFixedPitch
+ info.Desc.Ascent = round(k * float64(ttf.TypoAscender))
+ info.Desc.Descent = round(k * float64(ttf.TypoDescender))
+ info.UnderlineThickness = round(k * float64(ttf.UnderlineThickness))
+ info.UnderlinePosition = round(k * float64(ttf.UnderlinePosition))
+ info.Desc.FontBBox = fontBoxType{
+ round(k * float64(ttf.Xmin)),
+ round(k * float64(ttf.Ymin)),
+ round(k * float64(ttf.Xmax)),
+ round(k * float64(ttf.Ymax)),
+ }
+ // printf("FontBBox\n")
+ // dump(info.Desc.FontBBox)
+ info.Desc.CapHeight = round(k * float64(ttf.CapHeight))
+ info.Desc.MissingWidth = round(k * float64(ttf.Widths[0]))
+ var wd int
+ for j := 0; j < len(info.Widths); j++ {
+ wd = info.Desc.MissingWidth
+ if encList[j].name != ".notdef" {
+ uv := encList[j].uv
+ pos, ok := ttf.Chars[uint16(uv)]
+ if ok {
+ wd = round(k * float64(ttf.Widths[pos]))
+ } else {
+ fmt.Fprintf(msgWriter, "Character %s is missing\n", encList[j].name)
+ }
+ }
+ info.Widths[j] = wd
+ }
+ // printf("getInfoFromTrueType/FontBBox\n")
+ // dump(info.Desc.FontBBox)
+ return
+}
+
+type segmentType struct {
+ marker uint8
+ tp uint8
+ size uint32
+ data []byte
+}
+
+func segmentRead(f *os.File) (s segmentType, err error) {
+ if err = binary.Read(f, binary.LittleEndian, &s.marker); err != nil {
+ return
+ }
+ if s.marker != 128 {
+ err = fmt.Errorf("font file is not a valid binary Type1")
+ return
+ }
+ if err = binary.Read(f, binary.LittleEndian, &s.tp); err != nil {
+ return
+ }
+ if err = binary.Read(f, binary.LittleEndian, &s.size); err != nil {
+ return
+ }
+ s.data = make([]byte, s.size)
+ _, err = f.Read(s.data)
+ return
+}
+
+// -rw-r--r-- 1 root root 9532 2010-04-22 11:27 /usr/share/fonts/type1/mathml/Symbol.afm
+// -rw-r--r-- 1 root root 37744 2010-04-22 11:27 /usr/share/fonts/type1/mathml/Symbol.pfb
+
+// Return informations from a Type1 font
+func getInfoFromType1(fileStr string, msgWriter io.Writer, embed bool, encList encListType) (info fontInfoType, err error) {
+ if embed {
+ var f *os.File
+ f, err = os.Open(fileStr)
+ if err != nil {
+ return
+ }
+ defer f.Close()
+ // Read first segment
+ var s1, s2 segmentType
+ s1, err = segmentRead(f)
+ if err != nil {
+ return
+ }
+ s2, err = segmentRead(f)
+ if err != nil {
+ return
+ }
+ info.Data = s1.data
+ info.Data = append(info.Data, s2.data...)
+ info.Size1 = s1.size
+ info.Size2 = s2.size
+ }
+ afmFileStr := fileStr[0:len(fileStr)-3] + "afm"
+ size, ok := fileSize(afmFileStr)
+ if !ok {
+ err = fmt.Errorf("font file (ATM) %s not found", afmFileStr)
+ return
+ } else if size == 0 {
+ err = fmt.Errorf("font file (AFM) %s empty or not readable", afmFileStr)
+ return
+ }
+ var f *os.File
+ f, err = os.Open(afmFileStr)
+ if err != nil {
+ return
+ }
+ defer f.Close()
+ scanner := bufio.NewScanner(f)
+ var fields []string
+ var wd int
+ var wt, name string
+ wdMap := make(map[string]int)
+ for scanner.Scan() {
+ fields = strings.Fields(strings.TrimSpace(scanner.Text()))
+ // Comment Generated by FontForge 20080203
+ // FontName Symbol
+ // C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+ if len(fields) >= 2 {
+ switch fields[0] {
+ case "C":
+ if wd, err = strconv.Atoi(fields[4]); err == nil {
+ name = fields[7]
+ wdMap[name] = wd
+ }
+ case "FontName":
+ info.FontName = fields[1]
+ case "Weight":
+ wt = strings.ToLower(fields[1])
+ case "ItalicAngle":
+ info.Desc.ItalicAngle, err = strconv.Atoi(fields[1])
+ case "Ascender":
+ info.Desc.Ascent, err = strconv.Atoi(fields[1])
+ case "Descender":
+ info.Desc.Descent, err = strconv.Atoi(fields[1])
+ case "UnderlineThickness":
+ info.UnderlineThickness, err = strconv.Atoi(fields[1])
+ case "UnderlinePosition":
+ info.UnderlinePosition, err = strconv.Atoi(fields[1])
+ case "IsFixedPitch":
+ info.IsFixedPitch = fields[1] == "true"
+ case "FontBBox":
+ if info.Desc.FontBBox.Xmin, err = strconv.Atoi(fields[1]); err == nil {
+ if info.Desc.FontBBox.Ymin, err = strconv.Atoi(fields[2]); err == nil {
+ if info.Desc.FontBBox.Xmax, err = strconv.Atoi(fields[3]); err == nil {
+ info.Desc.FontBBox.Ymax, err = strconv.Atoi(fields[4])
+ }
+ }
+ }
+ case "CapHeight":
+ info.Desc.CapHeight, err = strconv.Atoi(fields[1])
+ case "StdVW":
+ info.Desc.StemV, err = strconv.Atoi(fields[1])
+ }
+ }
+ if err != nil {
+ return
+ }
+ }
+ if err = scanner.Err(); err != nil {
+ return
+ }
+ if info.FontName == "" {
+ err = fmt.Errorf("the field FontName missing in AFM file %s", afmFileStr)
+ return
+ }
+ info.Bold = wt == "bold" || wt == "black"
+ var missingWd int
+ missingWd, ok = wdMap[".notdef"]
+ if ok {
+ info.Desc.MissingWidth = missingWd
+ }
+ for j := 0; j < len(info.Widths); j++ {
+ info.Widths[j] = info.Desc.MissingWidth
+ }
+ for j := 0; j < len(info.Widths); j++ {
+ name = encList[j].name
+ if name != ".notdef" {
+ wd, ok = wdMap[name]
+ if ok {
+ info.Widths[j] = wd
+ } else {
+ fmt.Fprintf(msgWriter, "Character %s is missing\n", name)
+ }
+ }
+ }
+ // printf("getInfoFromType1/FontBBox\n")
+ // dump(info.Desc.FontBBox)
+ return
+}
+
+func makeFontDescriptor(info *fontInfoType) {
+ if info.Desc.CapHeight == 0 {
+ info.Desc.CapHeight = info.Desc.Ascent
+ }
+ info.Desc.Flags = 1 << 5
+ if info.IsFixedPitch {
+ info.Desc.Flags |= 1
+ }
+ if info.Desc.ItalicAngle != 0 {
+ info.Desc.Flags |= 1 << 6
+ }
+ if info.Desc.StemV == 0 {
+ if info.Bold {
+ info.Desc.StemV = 120
+ } else {
+ info.Desc.StemV = 70
+ }
+ }
+ // printf("makeFontDescriptor/FontBBox\n")
+ // dump(info.Desc.FontBBox)
+}
+
+// Build differences from reference encoding
+func makeFontEncoding(encList encListType, refEncFileStr string) (diffStr string, err error) {
+ var refList encListType
+ if refList, err = loadMap(refEncFileStr); err != nil {
+ return
+ }
+ var buf fmtBuffer
+ last := 0
+ for j := 32; j < 256; j++ {
+ if encList[j].name != refList[j].name {
+ if j != last+1 {
+ buf.printf("%d ", j)
+ }
+ last = j
+ buf.printf("/%s ", encList[j].name)
+ }
+ }
+ diffStr = strings.TrimSpace(buf.String())
+ return
+}
+
+func makeDefinitionFile(fileStr, tpStr, encodingFileStr string, embed bool, encList encListType, info fontInfoType) (err error) {
+ var def fontDefType
+ def.Tp = tpStr
+ def.Name = info.FontName
+ makeFontDescriptor(&info)
+ def.Desc = info.Desc
+ // printf("makeDefinitionFile/FontBBox\n")
+ // dump(def.Desc.FontBBox)
+ def.Up = info.UnderlinePosition
+ def.Ut = info.UnderlineThickness
+ def.Cw = info.Widths
+ def.Enc = baseNoExt(encodingFileStr)
+ // fmt.Printf("encodingFileStr [%s], def.Enc [%s]\n", encodingFileStr, def.Enc)
+ // fmt.Printf("reference [%s]\n", filepath.Join(filepath.Dir(encodingFileStr), "cp1252.map"))
+ def.Diff, err = makeFontEncoding(encList, filepath.Join(filepath.Dir(encodingFileStr), "cp1252.map"))
+ if err != nil {
+ return
+ }
+ def.File = info.File
+ def.Size1 = int(info.Size1)
+ def.Size2 = int(info.Size2)
+ def.OriginalSize = info.OriginalSize
+ // printf("Font definition file [%s]\n", fileStr)
+ var buf []byte
+ buf, err = json.Marshal(def)
+ if err != nil {
+ return
+ }
+ var f *os.File
+ f, err = os.Create(fileStr)
+ if err != nil {
+ return
+ }
+ defer f.Close()
+ f.Write(buf)
+ return
+}
+
+// MakeFont generates a font definition file in JSON format. A definition file
+// of this type is required to use non-core fonts in the PDF documents that
+// gofpdf generates. See the makefont utility in the gofpdf package for a
+// command line interface to this function.
+//
+// fontFileStr is the name of the TrueType file (extension .ttf), OpenType file
+// (extension .otf) or binary Type1 file (extension .pfb) from which to
+// generate a definition file. If an OpenType file is specified, it must be one
+// that is based on TrueType outlines, not PostScript outlines; this cannot be
+// determined from the file extension alone. If a Type1 file is specified, a
+// metric file with the same pathname except with the extension .afm must be
+// present.
+//
+// encodingFileStr is the name of the encoding file that corresponds to the
+// font.
+//
+// dstDirStr is the name of the directory in which to save the definition file
+// and, if embed is true, the compressed font file.
+//
+// msgWriter is the writer that is called to display messages throughout the
+// process. Use nil to turn off messages.
+//
+// embed is true if the font is to be embedded in the PDF files.
+func MakeFont(fontFileStr, encodingFileStr, dstDirStr string, msgWriter io.Writer, embed bool) (err error) {
+ if msgWriter == nil {
+ msgWriter = ioutil.Discard
+ }
+ if !fileExist(fontFileStr) {
+ err = fmt.Errorf("font file not found: %s", fontFileStr)
+ return
+ }
+ extStr := strings.ToLower(fontFileStr[len(fontFileStr)-3:])
+ // printf("Font file extension [%s]\n", extStr)
+ var tpStr string
+ if extStr == "ttf" || extStr == "otf" {
+ tpStr = "TrueType"
+ } else if extStr == "pfb" {
+ tpStr = "Type1"
+ } else {
+ err = fmt.Errorf("unrecognized font file extension: %s", extStr)
+ return
+ }
+ var encList encListType
+ var info fontInfoType
+ encList, err = loadMap(encodingFileStr)
+ if err != nil {
+ return
+ }
+ // printf("Encoding table\n")
+ // dump(encList)
+ if tpStr == "TrueType" {
+ info, err = getInfoFromTrueType(fontFileStr, msgWriter, embed, encList)
+ if err != nil {
+ return
+ }
+ } else {
+ info, err = getInfoFromType1(fontFileStr, msgWriter, embed, encList)
+ if err != nil {
+ return
+ }
+ }
+ baseStr := baseNoExt(fontFileStr)
+ // fmt.Printf("Base [%s]\n", baseStr)
+ if embed {
+ var f *os.File
+ info.File = baseStr + ".z"
+ zFileStr := filepath.Join(dstDirStr, info.File)
+ f, err = os.Create(zFileStr)
+ if err != nil {
+ return
+ }
+ defer f.Close()
+ cmp := zlib.NewWriter(f)
+ cmp.Write(info.Data)
+ cmp.Close()
+ fmt.Fprintf(msgWriter, "Font file compressed: %s\n", zFileStr)
+ }
+ defFileStr := filepath.Join(dstDirStr, baseStr+".json")
+ err = makeDefinitionFile(defFileStr, tpStr, encodingFileStr, embed, encList, info)
+ if err != nil {
+ return
+ }
+ fmt.Fprintf(msgWriter, "Font definition file successfully generated: %s\n", defFileStr)
+ return
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/fpdf.go b/vendor/github.com/jung-kurt/gofpdf/fpdf.go
new file mode 100644
index 0000000..66cff72
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/fpdf.go
@@ -0,0 +1,3856 @@
+/*
+ * Copyright (c) 2013-2014 Kurt Jung (Gmail: kurt.w.jung)
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package gofpdf
+
+// Version: 1.7
+// Date: 2011-06-18
+// Author: Olivier PLATHEY
+// Port to Go: Kurt Jung, 2013-07-15
+
+import (
+ "bytes"
+ "encoding/binary"
+ "encoding/json"
+ "fmt"
+ "image"
+ "image/color"
+ "image/gif"
+ "image/jpeg"
+ "image/png"
+ "io"
+ "io/ioutil"
+ "math"
+ "os"
+ "path"
+ "sort"
+ "strconv"
+ "strings"
+ "time"
+)
+
+var gl struct {
+ catalogSort bool
+ noCompress bool // Initial zero value indicates compression
+ creationDate time.Time
+}
+
+type fmtBuffer struct {
+ bytes.Buffer
+}
+
+func (b *fmtBuffer) printf(fmtStr string, args ...interface{}) {
+ b.Buffer.WriteString(fmt.Sprintf(fmtStr, args...))
+}
+
+func fpdfNew(orientationStr, unitStr, sizeStr, fontDirStr string, size SizeType) (f *Fpdf) {
+ f = new(Fpdf)
+ if orientationStr == "" {
+ orientationStr = "P"
+ }
+ if unitStr == "" {
+ unitStr = "mm"
+ }
+ if sizeStr == "" {
+ sizeStr = "A4"
+ }
+ if fontDirStr == "" {
+ fontDirStr = "."
+ }
+ f.page = 0
+ f.n = 2
+ f.pages = make([]*bytes.Buffer, 0, 8)
+ f.pages = append(f.pages, bytes.NewBufferString("")) // pages[0] is unused (1-based)
+ f.pageSizes = make(map[int]SizeType)
+ f.state = 0
+ f.fonts = make(map[string]fontDefType)
+ f.fontFiles = make(map[string]fontFileType)
+ f.diffs = make([]string, 0, 8)
+ f.templates = make(map[int64]Template)
+ f.templateObjects = make(map[int64]int)
+ f.images = make(map[string]*ImageInfoType)
+ f.pageLinks = make([][]linkType, 0, 8)
+ f.pageLinks = append(f.pageLinks, make([]linkType, 0, 0)) // pageLinks[0] is unused (1-based)
+ f.links = make([]intLinkType, 0, 8)
+ f.links = append(f.links, intLinkType{}) // links[0] is unused (1-based)
+ f.inHeader = false
+ f.inFooter = false
+ f.lasth = 0
+ f.fontFamily = ""
+ f.fontStyle = ""
+ f.SetFontSize(12)
+ f.underline = false
+ f.SetDrawColor(0, 0, 0)
+ f.SetFillColor(0, 0, 0)
+ f.SetTextColor(0, 0, 0)
+ f.colorFlag = false
+ f.ws = 0
+ f.fontpath = fontDirStr
+ // Core fonts
+ f.coreFonts = map[string]bool{
+ "courier": true,
+ "helvetica": true,
+ "times": true,
+ "symbol": true,
+ "zapfdingbats": true,
+ }
+ // Scale factor
+ switch unitStr {
+ case "pt", "point":
+ f.k = 1.0
+ case "mm":
+ f.k = 72.0 / 25.4
+ case "cm":
+ f.k = 72.0 / 2.54
+ case "in", "inch":
+ f.k = 72.0
+ default:
+ f.err = fmt.Errorf("incorrect unit %s", unitStr)
+ return
+ }
+ f.unitStr = unitStr
+ // Page sizes
+ f.stdPageSizes = make(map[string]SizeType)
+ f.stdPageSizes["a3"] = SizeType{841.89, 1190.55}
+ f.stdPageSizes["a4"] = SizeType{595.28, 841.89}
+ f.stdPageSizes["a5"] = SizeType{420.94, 595.28}
+ f.stdPageSizes["letter"] = SizeType{612, 792}
+ f.stdPageSizes["legal"] = SizeType{612, 1008}
+ if size.Wd > 0 && size.Ht > 0 {
+ f.defPageSize = size
+ } else {
+ f.defPageSize = f.getpagesizestr(sizeStr)
+ if f.err != nil {
+ return
+ }
+ }
+ f.curPageSize = f.defPageSize
+ // Page orientation
+ orientationStr = strings.ToLower(orientationStr)
+ switch orientationStr {
+ case "p", "portrait":
+ f.defOrientation = "P"
+ f.w = f.defPageSize.Wd
+ f.h = f.defPageSize.Ht
+ // dbg("Assign h: %8.2f", f.h)
+ case "l", "landscape":
+ f.defOrientation = "L"
+ f.w = f.defPageSize.Ht
+ f.h = f.defPageSize.Wd
+ default:
+ f.err = fmt.Errorf("incorrect orientation: %s", orientationStr)
+ return
+ }
+ f.curOrientation = f.defOrientation
+ f.wPt = f.w * f.k
+ f.hPt = f.h * f.k
+ // Page margins (1 cm)
+ margin := 28.35 / f.k
+ f.SetMargins(margin, margin, margin)
+ // Interior cell margin (1 mm)
+ f.cMargin = margin / 10
+ // Line width (0.2 mm)
+ f.lineWidth = 0.567 / f.k
+ // Automatic page break
+ f.SetAutoPageBreak(true, 2*margin)
+ // Default display mode
+ f.SetDisplayMode("default", "default")
+ if f.err != nil {
+ return
+ }
+ f.acceptPageBreak = func() bool {
+ return f.autoPageBreak
+ }
+ // Enable compression
+ f.SetCompression(!gl.noCompress)
+ f.blendList = make([]blendModeType, 0, 8)
+ f.blendList = append(f.blendList, blendModeType{}) // blendList[0] is unused (1-based)
+ f.blendMap = make(map[string]int)
+ f.blendMode = "Normal"
+ f.alpha = 1
+ f.gradientList = make([]gradientType, 0, 8)
+ f.gradientList = append(f.gradientList, gradientType{}) // gradientList[0] is unused
+ // Set default PDF version number
+ f.pdfVersion = "1.3"
+ f.layerInit()
+ f.catalogSort = gl.catalogSort
+ f.creationDate = gl.creationDate
+ return
+}
+
+// NewCustom returns a pointer to a new Fpdf instance. Its methods are
+// subsequently called to produce a single PDF document. NewCustom() is an
+// alternative to New() that provides additional customization. The PageSize()
+// example demonstrates this method.
+func NewCustom(init *InitType) (f *Fpdf) {
+ return fpdfNew(init.OrientationStr, init.UnitStr, init.SizeStr, init.FontDirStr, init.Size)
+}
+
+// New returns a pointer to a new Fpdf instance. Its methods are subsequently
+// called to produce a single PDF document.
+//
+// orientationStr specifies the default page orientation. For portrait mode,
+// specify "P" or "Portrait". For landscape mode, specify "L" or "Landscape".
+// An empty string will be replaced with "P".
+//
+// unitStr specifies the unit of length used in size parameters for elements
+// other than fonts, which are always measured in points. Specify "pt" for
+// point, "mm" for millimeter, "cm" for centimeter, or "in" for inch. An empty
+// string will be replaced with "mm".
+//
+// sizeStr specifies the page size. Acceptable values are "A3", "A4", "A5",
+// "Letter", or "Legal". An empty string will be replaced with "A4".
+//
+// fontDirStr specifies the file system location in which font resources will
+// be found. An empty string is replaced with ".". This argument only needs to
+// reference an actual directory if a font other than one of the core
+// fonts is used. The core fonts are "courier", "helvetica" (also called
+// "arial"), "times", and "zapfdingbats" (also called "symbol").
+func New(orientationStr, unitStr, sizeStr, fontDirStr string) (f *Fpdf) {
+ return fpdfNew(orientationStr, unitStr, sizeStr, fontDirStr, SizeType{0, 0})
+}
+
+// Ok returns true if no processing errors have occurred.
+func (f *Fpdf) Ok() bool {
+ return f.err == nil
+}
+
+// Err returns true if a processing error has occurred.
+func (f *Fpdf) Err() bool {
+ return f.err != nil
+}
+
+// ClearError unsets the internal Fpdf error. This method should be used with
+// care, as an internal error condition usually indicates an unrecoverable
+// problem with the generation of a document. It is intended to deal with cases
+// in which an error is used to select an alternate form of the document.
+func (f *Fpdf) ClearError() {
+ f.err = nil
+}
+
+// SetErrorf sets the internal Fpdf error with formatted text to halt PDF
+// generation; this may facilitate error handling by application. If an error
+// condition is already set, this call is ignored.
+//
+// See the documentation for printing in the standard fmt package for details
+// about fmtStr and args.
+func (f *Fpdf) SetErrorf(fmtStr string, args ...interface{}) {
+ if f.err == nil {
+ f.err = fmt.Errorf(fmtStr, args...)
+ }
+}
+
+// String satisfies the fmt.Stringer interface and summarizes the Fpdf
+// instance.
+func (f *Fpdf) String() string {
+ return "Fpdf " + cnFpdfVersion
+}
+
+// SetError sets an error to halt PDF generation. This may facilitate error
+// handling by application. See also Ok(), Err() and Error().
+func (f *Fpdf) SetError(err error) {
+ if f.err == nil && err != nil {
+ f.err = err
+ }
+}
+
+// Error returns the internal Fpdf error; this will be nil if no error has occurred.
+func (f *Fpdf) Error() error {
+ return f.err
+}
+
+// GetPageSize returns the current page's width and height. This is the paper's
+// size. To compute the size of the area being used, subtract the margins (see
+// GetMargins()).
+func (f *Fpdf) GetPageSize() (width, height float64) {
+ width = f.w
+ height = f.h
+ return
+}
+
+// GetMargins returns the left, top, right, and bottom margins. The first three
+// are set with the SetMargins() method. The bottom margin is set with the
+// SetAutoPageBreak() method.
+func (f *Fpdf) GetMargins() (left, top, right, bottom float64) {
+ left = f.lMargin
+ top = f.tMargin
+ right = f.rMargin
+ bottom = f.bMargin
+ return
+}
+
+// SetMargins defines the left, top and right margins. By default, they equal 1
+// cm. Call this method to change them. If the value of the right margin is
+// less than zero, it is set to the same as the left margin.
+func (f *Fpdf) SetMargins(left, top, right float64) {
+ f.lMargin = left
+ f.tMargin = top
+ if right < 0 {
+ right = left
+ }
+ f.rMargin = right
+}
+
+// SetLeftMargin defines the left margin. The method can be called before
+// creating the first page. If the current abscissa gets out of page, it is
+// brought back to the margin.
+func (f *Fpdf) SetLeftMargin(margin float64) {
+ f.lMargin = margin
+ if f.page > 0 && f.x < margin {
+ f.x = margin
+ }
+}
+
+// GetCellMargin returns the cell margin. This is the amount of space before
+// and after the text within a cell that's left blank, and is in units passed
+// to New(). It defaults to 1mm.
+func (f *Fpdf) GetCellMargin() float64 {
+ return f.cMargin
+}
+
+// SetCellMargin sets the cell margin. This is the amount of space before and
+// after the text within a cell that's left blank, and is in units passed to
+// New().
+func (f *Fpdf) SetCellMargin(margin float64) {
+ f.cMargin = margin
+}
+
+// SetFontLocation sets the location in the file system of the font and font
+// definition files.
+func (f *Fpdf) SetFontLocation(fontDirStr string) {
+ f.fontpath = fontDirStr
+}
+
+// SetFontLoader sets a loader used to read font files (.json and .z) from an
+// arbitrary source. If a font loader has been specified, it is used to load
+// the named font resources when AddFont() is called. If this operation fails,
+// an attempt is made to load the resources from the configured font directory
+// (see SetFontLocation()).
+func (f *Fpdf) SetFontLoader(loader FontLoader) {
+ f.fontLoader = loader
+}
+
+// SetHeaderFunc sets the function that lets the application render the page
+// header. The specified function is automatically called by AddPage() and
+// should not be called directly by the application. The implementation in Fpdf
+// is empty, so you have to provide an appropriate function if you want page
+// headers. fnc will typically be a closure that has access to the Fpdf
+// instance and other document generation variables.
+//
+// This method is demonstrated in the example for AddPage().
+func (f *Fpdf) SetHeaderFunc(fnc func()) {
+ f.headerFnc = fnc
+}
+
+// SetFooterFunc sets the function that lets the application render the page
+// footer. The specified function is automatically called by AddPage() and
+// Close() and should not be called directly by the application. The
+// implementation in Fpdf is empty, so you have to provide an appropriate
+// function if you want page footers. fnc will typically be a closure that has
+// access to the Fpdf instance and other document generation variables.
+//
+// This method is demonstrated in the example for AddPage().
+func (f *Fpdf) SetFooterFunc(fnc func()) {
+ f.footerFnc = fnc
+}
+
+// SetTopMargin defines the top margin. The method can be called before
+// creating the first page.
+func (f *Fpdf) SetTopMargin(margin float64) {
+ f.tMargin = margin
+}
+
+// SetRightMargin defines the right margin. The method can be called before
+// creating the first page.
+func (f *Fpdf) SetRightMargin(margin float64) {
+ f.rMargin = margin
+}
+
+// SetAutoPageBreak enables or disables the automatic page breaking mode. When
+// enabling, the second parameter is the distance from the bottom of the page
+// that defines the triggering limit. By default, the mode is on and the margin
+// is 2 cm.
+func (f *Fpdf) SetAutoPageBreak(auto bool, margin float64) {
+ f.autoPageBreak = auto
+ f.bMargin = margin
+ f.pageBreakTrigger = f.h - margin
+}
+
+// SetDisplayMode sets advisory display directives for the document viewer.
+// Pages can be displayed entirely on screen, occupy the full width of the
+// window, use real size, be scaled by a specific zooming factor or use viewer
+// default (configured in the Preferences menu of Adobe Reader). The page
+// layout can be specified so that pages are displayed individually or in
+// pairs.
+//
+// zoomStr can be "fullpage" to display the entire page on screen, "fullwidth"
+// to use maximum width of window, "real" to use real size (equivalent to 100%
+// zoom) or "default" to use viewer default mode.
+//
+// layoutStr can be "single" (or "SinglePage") to display one page at once,
+// "continuous" (or "OneColumn") to display pages continuously, "two" (or
+// "TwoColumnLeft") to display two pages on two columns with odd-numbered pages
+// on the left, or "TwoColumnRight" to display two pages on two columns with
+// odd-numbered pages on the right, or "TwoPageLeft" to display pages two at a
+// time with odd-numbered pages on the left, or "TwoPageRight" to display pages
+// two at a time with odd-numbered pages on the right, or "default" to use
+// viewer default mode.
+func (f *Fpdf) SetDisplayMode(zoomStr, layoutStr string) {
+ if f.err != nil {
+ return
+ }
+ if layoutStr == "" {
+ layoutStr = "default"
+ }
+ switch zoomStr {
+ case "fullpage", "fullwidth", "real", "default":
+ f.zoomMode = zoomStr
+ default:
+ f.err = fmt.Errorf("incorrect zoom display mode: %s", zoomStr)
+ return
+ }
+ switch layoutStr {
+ case "single", "continuous", "two", "default", "SinglePage", "OneColumn",
+ "TwoColumnLeft", "TwoColumnRight", "TwoPageLeft", "TwoPageRight":
+ f.layoutMode = layoutStr
+ default:
+ f.err = fmt.Errorf("incorrect layout display mode: %s", layoutStr)
+ return
+ }
+}
+
+// SetDefaultCompression controls the default setting of the internal
+// compression flag. See SetCompression() for more details. Compression is on
+// by default.
+func SetDefaultCompression(compress bool) {
+ gl.noCompress = !compress
+}
+
+// SetCompression activates or deactivates page compression with zlib. When
+// activated, the internal representation of each page is compressed, which
+// leads to a compression ratio of about 2 for the resulting document.
+// Compression is on by default.
+func (f *Fpdf) SetCompression(compress bool) {
+ f.compress = compress
+}
+
+// SetTitle defines the title of the document. isUTF8 indicates if the string
+// is encoded in ISO-8859-1 (false) or UTF-8 (true).
+func (f *Fpdf) SetTitle(titleStr string, isUTF8 bool) {
+ if isUTF8 {
+ titleStr = utf8toutf16(titleStr)
+ }
+ f.title = titleStr
+}
+
+// SetSubject defines the subject of the document. isUTF8 indicates if the
+// string is encoded in ISO-8859-1 (false) or UTF-8 (true).
+func (f *Fpdf) SetSubject(subjectStr string, isUTF8 bool) {
+ if isUTF8 {
+ subjectStr = utf8toutf16(subjectStr)
+ }
+ f.subject = subjectStr
+}
+
+// SetAuthor defines the author of the document. isUTF8 indicates if the string
+// is encoded in ISO-8859-1 (false) or UTF-8 (true).
+func (f *Fpdf) SetAuthor(authorStr string, isUTF8 bool) {
+ if isUTF8 {
+ authorStr = utf8toutf16(authorStr)
+ }
+ f.author = authorStr
+}
+
+// SetKeywords defines the keywords of the document. keywordStr is a
+// space-delimited string, for example "invoice August". isUTF8 indicates if
+// the string is encoded
+func (f *Fpdf) SetKeywords(keywordsStr string, isUTF8 bool) {
+ if isUTF8 {
+ keywordsStr = utf8toutf16(keywordsStr)
+ }
+ f.keywords = keywordsStr
+}
+
+// SetCreator defines the creator of the document. isUTF8 indicates if the
+// string is encoded in ISO-8859-1 (false) or UTF-8 (true).
+func (f *Fpdf) SetCreator(creatorStr string, isUTF8 bool) {
+ if isUTF8 {
+ creatorStr = utf8toutf16(creatorStr)
+ }
+ f.creator = creatorStr
+}
+
+// AliasNbPages defines an alias for the total number of pages. It will be
+// substituted as the document is closed. An empty string is replaced with the
+// string "{nb}".
+//
+// See the example for AddPage() for a demonstration of this method.
+func (f *Fpdf) AliasNbPages(aliasStr string) {
+ if aliasStr == "" {
+ aliasStr = "{nb}"
+ }
+ f.aliasNbPagesStr = aliasStr
+}
+
+// Begin document
+func (f *Fpdf) open() {
+ f.state = 1
+}
+
+// Close terminates the PDF document. It is not necessary to call this method
+// explicitly because Output(), OutputAndClose() and OutputFileAndClose() do it
+// automatically. If the document contains no page, AddPage() is called to
+// prevent the generation of an invalid document.
+func (f *Fpdf) Close() {
+ if f.err == nil {
+ if f.clipNest > 0 {
+ f.err = fmt.Errorf("clip procedure must be explicitly ended")
+ } else if f.transformNest > 0 {
+ f.err = fmt.Errorf("transformation procedure must be explicitly ended")
+ }
+ }
+ if f.err != nil {
+ return
+ }
+ if f.state == 3 {
+ return
+ }
+ if f.page == 0 {
+ f.AddPage()
+ if f.err != nil {
+ return
+ }
+ }
+ // Page footer
+ if f.footerFnc != nil {
+ f.inFooter = true
+ f.footerFnc()
+ f.inFooter = false
+ }
+ // Close page
+ f.endpage()
+ // Close document
+ f.enddoc()
+ return
+}
+
+// PageSize returns the width and height of the specified page in the units
+// established in New(). These return values are followed by the unit of
+// measure itself. If pageNum is zero or otherwise out of bounds, it returns
+// the default page size, that is, the size of the page that would be added by
+// AddPage().
+func (f *Fpdf) PageSize(pageNum int) (wd, ht float64, unitStr string) {
+ sz, ok := f.pageSizes[pageNum]
+ if ok {
+ sz.Wd, sz.Ht = sz.Wd/f.k, sz.Ht/f.k
+ } else {
+ sz = f.defPageSize // user units
+ }
+ return sz.Wd, sz.Ht, f.unitStr
+}
+
+// AddPageFormat adds a new page with non-default orientation or size. See
+// AddPage() for more details.
+//
+// See New() for a description of orientationStr.
+//
+// size specifies the size of the new page in the units established in New().
+//
+// The PageSize() example demonstrates this method.
+func (f *Fpdf) AddPageFormat(orientationStr string, size SizeType) {
+ if f.err != nil {
+ return
+ }
+ if f.state == 0 {
+ f.open()
+ }
+ familyStr := f.fontFamily
+ style := f.fontStyle
+ if f.underline {
+ style += "U"
+ }
+ fontsize := f.fontSizePt
+ lw := f.lineWidth
+ dc := f.color.draw
+ fc := f.color.fill
+ tc := f.color.text
+ cf := f.colorFlag
+ if f.page > 0 {
+ // Page footer
+ if f.footerFnc != nil {
+ f.inFooter = true
+ f.footerFnc()
+ f.inFooter = false
+ }
+ // Close page
+ f.endpage()
+ }
+ // Start new page
+ f.beginpage(orientationStr, size)
+ // Set line cap style to current value
+ // f.out("2 J")
+ f.outf("%d J", f.capStyle)
+ // Set line join style to current value
+ f.outf("%d j", f.joinStyle)
+ // Set line width
+ f.lineWidth = lw
+ f.outf("%.2f w", lw*f.k)
+ // Set dash pattern
+ if len(f.dashArray) > 0 {
+ f.outputDashPattern()
+ }
+ // Set font
+ if familyStr != "" {
+ f.SetFont(familyStr, style, fontsize)
+ if f.err != nil {
+ return
+ }
+ }
+ // Set colors
+ f.color.draw = dc
+ if dc.str != "0 G" {
+ f.out(dc.str)
+ }
+ f.color.fill = fc
+ if fc.str != "0 g" {
+ f.out(fc.str)
+ }
+ f.color.text = tc
+ f.colorFlag = cf
+ // Page header
+ if f.headerFnc != nil {
+ f.inHeader = true
+ f.headerFnc()
+ f.inHeader = false
+ }
+ // Restore line width
+ if f.lineWidth != lw {
+ f.lineWidth = lw
+ f.outf("%.2f w", lw*f.k)
+ }
+ // Restore font
+ if familyStr != "" {
+ f.SetFont(familyStr, style, fontsize)
+ if f.err != nil {
+ return
+ }
+ }
+ // Restore colors
+ if f.color.draw.str != dc.str {
+ f.color.draw = dc
+ f.out(dc.str)
+ }
+ if f.color.fill.str != fc.str {
+ f.color.fill = fc
+ f.out(fc.str)
+ }
+ f.color.text = tc
+ f.colorFlag = cf
+ return
+}
+
+// AddPage adds a new page to the document. If a page is already present, the
+// Footer() method is called first to output the footer. Then the page is
+// added, the current position set to the top-left corner according to the left
+// and top margins, and Header() is called to display the header.
+//
+// The font which was set before calling is automatically restored. There is no
+// need to call SetFont() again if you want to continue with the same font. The
+// same is true for colors and line width.
+//
+// The origin of the coordinate system is at the top-left corner and increasing
+// ordinates go downwards.
+//
+// See AddPageFormat() for a version of this method that allows the page size
+// and orientation to be different than the default.
+func (f *Fpdf) AddPage() {
+ if f.err != nil {
+ return
+ }
+ // dbg("AddPage")
+ f.AddPageFormat(f.defOrientation, f.defPageSize)
+ return
+}
+
+// PageNo returns the current page number.
+//
+// See the example for AddPage() for a demonstration of this method.
+func (f *Fpdf) PageNo() int {
+ return f.page
+}
+
+type clrType struct {
+ r, g, b float64
+ ir, ig, ib int
+ gray bool
+ str string
+}
+
+func colorComp(v int) (int, float64) {
+ if v < 0 {
+ v = 0
+ } else if v > 255 {
+ v = 255
+ }
+ return v, float64(v) / 255.0
+}
+
+func colorValue(r, g, b int, grayStr, fullStr string) (clr clrType) {
+ clr.ir, clr.r = colorComp(r)
+ clr.ig, clr.g = colorComp(g)
+ clr.ib, clr.b = colorComp(b)
+ clr.gray = clr.ir == clr.ig && clr.r == clr.b
+ if len(grayStr) > 0 {
+ if clr.gray {
+ clr.str = sprintf("%.3f %s", clr.r, grayStr)
+ } else {
+ clr.str = sprintf("%.3f %.3f %.3f %s", clr.r, clr.g, clr.b, fullStr)
+ }
+ } else {
+ clr.str = sprintf("%.3f %.3f %.3f", clr.r, clr.g, clr.b)
+ }
+ return
+}
+
+// SetDrawColor defines the color used for all drawing operations (lines,
+// rectangles and cell borders). It is expressed in RGB components (0 - 255).
+// The method can be called before the first page is created. The value is
+// retained from page to page.
+func (f *Fpdf) SetDrawColor(r, g, b int) {
+ f.color.draw = colorValue(r, g, b, "G", "RG")
+ if f.page > 0 {
+ f.out(f.color.draw.str)
+ }
+}
+
+// GetDrawColor returns the current draw color as RGB components (0 - 255).
+func (f *Fpdf) GetDrawColor() (int, int, int) {
+ return f.color.draw.ir, f.color.draw.ig, f.color.draw.ib
+}
+
+// SetFillColor defines the color used for all filling operations (filled
+// rectangles and cell backgrounds). It is expressed in RGB components (0
+// -255). The method can be called before the first page is created and the
+// value is retained from page to page.
+func (f *Fpdf) SetFillColor(r, g, b int) {
+ f.color.fill = colorValue(r, g, b, "g", "rg")
+ f.colorFlag = f.color.fill.str != f.color.text.str
+ if f.page > 0 {
+ f.out(f.color.fill.str)
+ }
+}
+
+// GetFillColor returns the current fill color as RGB components (0 - 255).
+func (f *Fpdf) GetFillColor() (int, int, int) {
+ return f.color.fill.ir, f.color.fill.ig, f.color.fill.ib
+}
+
+// SetTextColor defines the color used for text. It is expressed in RGB
+// components (0 - 255). The method can be called before the first page is
+// created. The value is retained from page to page.
+func (f *Fpdf) SetTextColor(r, g, b int) {
+ f.color.text = colorValue(r, g, b, "g", "rg")
+ f.colorFlag = f.color.fill.str != f.color.text.str
+}
+
+// GetTextColor returns the current text color as RGB components (0 - 255).
+func (f *Fpdf) GetTextColor() (int, int, int) {
+ return f.color.text.ir, f.color.text.ig, f.color.text.ib
+}
+
+// GetStringWidth returns the length of a string in user units. A font must be
+// currently selected.
+func (f *Fpdf) GetStringWidth(s string) float64 {
+ if f.err != nil {
+ return 0
+ }
+ w := 0
+ for _, ch := range []byte(s) {
+ if ch == 0 {
+ break
+ }
+ w += f.currentFont.Cw[ch]
+ }
+ return float64(w) * f.fontSize / 1000
+}
+
+// SetLineWidth defines the line width. By default, the value equals 0.2 mm.
+// The method can be called before the first page is created. The value is
+// retained from page to page.
+func (f *Fpdf) SetLineWidth(width float64) {
+ f.lineWidth = width
+ if f.page > 0 {
+ f.outf("%.2f w", width*f.k)
+ }
+}
+
+// GetLineWidth returns the current line thickness.
+func (f *Fpdf) GetLineWidth() float64 {
+ return f.lineWidth
+}
+
+// SetLineCapStyle defines the line cap style. styleStr should be "butt",
+// "round" or "square". A square style projects from the end of the line. The
+// method can be called before the first page is created. The value is
+// retained from page to page.
+func (f *Fpdf) SetLineCapStyle(styleStr string) {
+ var capStyle int
+ switch styleStr {
+ case "round":
+ capStyle = 1
+ case "square":
+ capStyle = 2
+ default:
+ capStyle = 0
+ }
+ if capStyle != f.capStyle {
+ f.capStyle = capStyle
+ if f.page > 0 {
+ f.outf("%d J", f.capStyle)
+ }
+ }
+}
+
+// SetLineJoinStyle defines the line cap style. styleStr should be "miter",
+// "round" or "bevel". The method can be called before the first page
+// is created. The value is retained from page to page.
+func (f *Fpdf) SetLineJoinStyle(styleStr string) {
+ var joinStyle int
+ switch styleStr {
+ case "round":
+ joinStyle = 1
+ case "bevel":
+ joinStyle = 2
+ default:
+ joinStyle = 0
+ }
+ if joinStyle != f.joinStyle {
+ f.joinStyle = joinStyle
+ if f.page > 0 {
+ f.outf("%d j", f.joinStyle)
+ }
+ }
+}
+
+// SetDashPattern sets the dash pattern that is used to draw lines. The
+// dashArray elements are numbers that specify the lengths, in units
+// established in New(), of alternating dashes and gaps. The dash phase
+// specifies the distance into the dash pattern at which to start the dash. The
+// dash pattern is retained from page to page. Call this method with an empty
+// array to restore solid line drawing.
+//
+// The Beziergon() example demonstrates this method.
+func (f *Fpdf) SetDashPattern(dashArray []float64, dashPhase float64) {
+ scaled := make([]float64, len(dashArray))
+ for i, value := range dashArray {
+ scaled[i] = value * f.k
+ }
+ dashPhase *= f.k
+ if !slicesEqual(scaled, f.dashArray) || dashPhase != f.dashPhase {
+ f.dashArray = scaled
+ f.dashPhase = dashPhase
+ if f.page > 0 {
+ f.outputDashPattern()
+ }
+ }
+}
+
+func (f *Fpdf) outputDashPattern() {
+ var buf bytes.Buffer
+ buf.WriteByte('[')
+ for i, value := range f.dashArray {
+ if i > 0 {
+ buf.WriteByte(' ')
+ }
+ buf.WriteString(strconv.FormatFloat(value, 'f', 2, 64))
+ }
+ buf.WriteString("] ")
+ buf.WriteString(strconv.FormatFloat(f.dashPhase, 'f', 2, 64))
+ buf.WriteString(" d")
+ f.outbuf(&buf)
+}
+
+// Line draws a line between points (x1, y1) and (x2, y2) using the current
+// draw color, line width and cap style.
+func (f *Fpdf) Line(x1, y1, x2, y2 float64) {
+ f.outf("%.2f %.2f m %.2f %.2f l S", x1*f.k, (f.h-y1)*f.k, x2*f.k, (f.h-y2)*f.k)
+}
+
+// fillDrawOp corrects path painting operators
+func fillDrawOp(styleStr string) (opStr string) {
+ switch strings.ToUpper(styleStr) {
+ case "", "D":
+ // Stroke the path.
+ opStr = "S"
+ case "F":
+ // fill the path, using the nonzero winding number rule
+ opStr = "f"
+ case "F*":
+ // fill the path, using the even-odd rule
+ opStr = "f*"
+ case "FD", "DF":
+ // fill and then stroke the path, using the nonzero winding number rule
+ opStr = "B"
+ case "FD*", "DF*":
+ // fill and then stroke the path, using the even-odd rule
+ opStr = "B*"
+ default:
+ opStr = styleStr
+ }
+ return
+}
+
+// Rect outputs a rectangle of width w and height h with the upper left corner
+// positioned at point (x, y).
+//
+// It can be drawn (border only), filled (with no border) or both. styleStr can
+// be "F" for filled, "D" for outlined only, or "DF" or "FD" for outlined and
+// filled. An empty string will be replaced with "D". Drawing uses the current
+// draw color and line width centered on the rectangle's perimeter. Filling
+// uses the current fill color.
+func (f *Fpdf) Rect(x, y, w, h float64, styleStr string) {
+ f.outf("%.2f %.2f %.2f %.2f re %s", x*f.k, (f.h-y)*f.k, w*f.k, -h*f.k, fillDrawOp(styleStr))
+}
+
+// Circle draws a circle centered on point (x, y) with radius r.
+//
+// styleStr can be "F" for filled, "D" for outlined only, or "DF" or "FD" for
+// outlined and filled. An empty string will be replaced with "D". Drawing uses
+// the current draw color and line width centered on the circle's perimeter.
+// Filling uses the current fill color.
+func (f *Fpdf) Circle(x, y, r float64, styleStr string) {
+ f.Ellipse(x, y, r, r, 0, styleStr)
+}
+
+// Ellipse draws an ellipse centered at point (x, y). rx and ry specify its
+// horizontal and vertical radii.
+//
+// degRotate specifies the counter-clockwise angle in degrees that the ellipse
+// will be rotated.
+//
+// styleStr can be "F" for filled, "D" for outlined only, or "DF" or "FD" for
+// outlined and filled. An empty string will be replaced with "D". Drawing uses
+// the current draw color and line width centered on the ellipse's perimeter.
+// Filling uses the current fill color.
+//
+// The Circle() example demonstrates this method.
+func (f *Fpdf) Ellipse(x, y, rx, ry, degRotate float64, styleStr string) {
+ f.arc(x, y, rx, ry, degRotate, 0, 360, styleStr, false)
+}
+
+// Polygon draws a closed figure defined by a series of vertices specified by
+// points. The x and y fields of the points use the units established in New().
+// The last point in the slice will be implicitly joined to the first to close
+// the polygon.
+//
+// styleStr can be "F" for filled, "D" for outlined only, or "DF" or "FD" for
+// outlined and filled. An empty string will be replaced with "D". Drawing uses
+// the current draw color and line width centered on the ellipse's perimeter.
+// Filling uses the current fill color.
+func (f *Fpdf) Polygon(points []PointType, styleStr string) {
+ if len(points) > 2 {
+ for j, pt := range points {
+ if j == 0 {
+ f.point(pt.X, pt.Y)
+ } else {
+ f.outf("%.5f %.5f l ", pt.X*f.k, (f.h-pt.Y)*f.k)
+ }
+ }
+ f.outf("%.5f %.5f l ", points[0].X*f.k, (f.h-points[0].Y)*f.k)
+ f.DrawPath(styleStr)
+ }
+}
+
+// Beziergon draws a closed figure defined by a series of cubic Bézier curve
+// segments. The first point in the slice defines the starting point of the
+// figure. Each three following points p1, p2, p3 represent a curve segment to
+// the point p3 using p1 and p2 as the Bézier control points.
+//
+// The x and y fields of the points use the units established in New().
+//
+// styleStr can be "F" for filled, "D" for outlined only, or "DF" or "FD" for
+// outlined and filled. An empty string will be replaced with "D". Drawing uses
+// the current draw color and line width centered on the ellipse's perimeter.
+// Filling uses the current fill color.
+func (f *Fpdf) Beziergon(points []PointType, styleStr string) {
+
+ // Thanks, Robert Lillack, for contributing this function.
+
+ if len(points) < 4 {
+ return
+ }
+ f.point(points[0].XY())
+
+ points = points[1:]
+ for len(points) >= 3 {
+ cx0, cy0 := points[0].XY()
+ cx1, cy1 := points[1].XY()
+ x1, y1 := points[2].XY()
+ f.curve(cx0, cy0, cx1, cy1, x1, y1)
+ points = points[3:]
+ }
+
+ f.DrawPath(styleStr)
+}
+
+// Outputs current point
+func (f *Fpdf) point(x, y float64) {
+ f.outf("%.2f %.2f m", x*f.k, (f.h-y)*f.k)
+}
+
+// Outputs a single cubic Bézier curve segment from current point
+func (f *Fpdf) curve(cx0, cy0, cx1, cy1, x, y float64) {
+ // Thanks, Robert Lillack, for straightening this out
+ f.outf("%.5f %.5f %.5f %.5f %.5f %.5f c", cx0*f.k, (f.h-cy0)*f.k, cx1*f.k,
+ (f.h-cy1)*f.k, x*f.k, (f.h-y)*f.k)
+}
+
+// Curve draws a single-segment quadratic Bézier curve. The curve starts at
+// the point (x0, y0) and ends at the point (x1, y1). The control point (cx,
+// cy) specifies the curvature. At the start point, the curve is tangent to the
+// straight line between the start point and the control point. At the end
+// point, the curve is tangent to the straight line between the end point and
+// the control point.
+//
+// styleStr can be "F" for filled, "D" for outlined only, or "DF" or "FD" for
+// outlined and filled. An empty string will be replaced with "D". Drawing uses
+// the current draw color, line width, and cap style centered on the curve's
+// path. Filling uses the current fill color.
+//
+// The Circle() example demonstrates this method.
+func (f *Fpdf) Curve(x0, y0, cx, cy, x1, y1 float64, styleStr string) {
+ f.point(x0, y0)
+ f.outf("%.5f %.5f %.5f %.5f v %s", cx*f.k, (f.h-cy)*f.k, x1*f.k, (f.h-y1)*f.k,
+ fillDrawOp(styleStr))
+}
+
+// CurveCubic draws a single-segment cubic Bézier curve. This routine performs
+// the same function as CurveBezierCubic() but has a nonstandard argument order.
+// It is retained to preserve backward compatibility.
+func (f *Fpdf) CurveCubic(x0, y0, cx0, cy0, x1, y1, cx1, cy1 float64, styleStr string) {
+ // f.point(x0, y0)
+ // f.outf("%.5f %.5f %.5f %.5f %.5f %.5f c %s", cx0*f.k, (f.h-cy0)*f.k,
+ // cx1*f.k, (f.h-cy1)*f.k, x1*f.k, (f.h-y1)*f.k, fillDrawOp(styleStr))
+ f.CurveBezierCubic(x0, y0, cx0, cy0, cx1, cy1, x1, y1, styleStr)
+}
+
+// CurveBezierCubic draws a single-segment cubic Bézier curve. The curve starts at
+// the point (x0, y0) and ends at the point (x1, y1). The control points (cx0,
+// cy0) and (cx1, cy1) specify the curvature. At the start point, the curve is
+// tangent to the straight line between the start point and the control point
+// (cx0, cy0). At the end point, the curve is tangent to the straight line
+// between the end point and the control point (cx1, cy1).
+//
+// styleStr can be "F" for filled, "D" for outlined only, or "DF" or "FD" for
+// outlined and filled. An empty string will be replaced with "D". Drawing uses
+// the current draw color, line width, and cap style centered on the curve's
+// path. Filling uses the current fill color.
+//
+// This routine performs the same function as CurveCubic() but uses standard
+// argument order.
+//
+// The Circle() example demonstrates this method.
+func (f *Fpdf) CurveBezierCubic(x0, y0, cx0, cy0, cx1, cy1, x1, y1 float64, styleStr string) {
+ f.point(x0, y0)
+ f.outf("%.5f %.5f %.5f %.5f %.5f %.5f c %s", cx0*f.k, (f.h-cy0)*f.k,
+ cx1*f.k, (f.h-cy1)*f.k, x1*f.k, (f.h-y1)*f.k, fillDrawOp(styleStr))
+}
+
+// Arc draws an elliptical arc centered at point (x, y). rx and ry specify its
+// horizontal and vertical radii.
+//
+// degRotate specifies the angle that the arc will be rotated. degStart and
+// degEnd specify the starting and ending angle of the arc. All angles are
+// specified in degrees and measured counter-clockwise from the 3 o'clock
+// position.
+//
+// styleStr can be "F" for filled, "D" for outlined only, or "DF" or "FD" for
+// outlined and filled. An empty string will be replaced with "D". Drawing uses
+// the current draw color, line width, and cap style centered on the arc's
+// path. Filling uses the current fill color.
+//
+// The Circle() example demonstrates this method.
+func (f *Fpdf) Arc(x, y, rx, ry, degRotate, degStart, degEnd float64, styleStr string) {
+ f.arc(x, y, rx, ry, degRotate, degStart, degEnd, styleStr, false)
+}
+
+// GetAlpha returns the alpha blending channel, which consists of the
+// alpha transparency value and the blend mode. See SetAlpha for more
+// details.
+func (f *Fpdf) GetAlpha() (alpha float64, blendModeStr string) {
+ return f.alpha, f.blendMode
+}
+
+// SetAlpha sets the alpha blending channel. The blending effect applies to
+// text, drawings and images.
+//
+// alpha must be a value between 0.0 (fully transparent) to 1.0 (fully opaque).
+// Values outside of this range result in an error.
+//
+// blendModeStr must be one of "Normal", "Multiply", "Screen", "Overlay",
+// "Darken", "Lighten", "ColorDodge", "ColorBurn","HardLight", "SoftLight",
+// "Difference", "Exclusion", "Hue", "Saturation", "Color", or "Luminosity". An
+// empty string is replaced with "Normal".
+//
+// To reset normal rendering after applying a blending mode, call this method
+// with alpha set to 1.0 and blendModeStr set to "Normal".
+func (f *Fpdf) SetAlpha(alpha float64, blendModeStr string) {
+ if f.err != nil || (alpha == f.alpha && blendModeStr == f.blendMode) {
+ return
+ }
+ var bl blendModeType
+ switch blendModeStr {
+ case "Normal", "Multiply", "Screen", "Overlay",
+ "Darken", "Lighten", "ColorDodge", "ColorBurn", "HardLight", "SoftLight",
+ "Difference", "Exclusion", "Hue", "Saturation", "Color", "Luminosity":
+ bl.modeStr = blendModeStr
+ case "":
+ bl.modeStr = "Normal"
+ default:
+ f.err = fmt.Errorf("unrecognized blend mode \"%s\"", blendModeStr)
+ return
+ }
+ if alpha < 0.0 || alpha > 1.0 {
+ f.err = fmt.Errorf("alpha value (0.0 - 1.0) is out of range: %.3f", alpha)
+ return
+ }
+ f.alpha = alpha
+ f.blendMode = blendModeStr
+ alphaStr := sprintf("%.3f", alpha)
+ keyStr := sprintf("%s %s", alphaStr, blendModeStr)
+ pos, ok := f.blendMap[keyStr]
+ if !ok {
+ pos = len(f.blendList) // at least 1
+ f.blendList = append(f.blendList, blendModeType{alphaStr, alphaStr, blendModeStr, 0})
+ f.blendMap[keyStr] = pos
+ }
+ f.outf("/GS%d gs", pos)
+}
+
+func (f *Fpdf) gradientClipStart(x, y, w, h float64) {
+ // Save current graphic state and set clipping area
+ f.outf("q %.2f %.2f %.2f %.2f re W n", x*f.k, (f.h-y)*f.k, w*f.k, -h*f.k)
+ // Set up transformation matrix for gradient
+ f.outf("%.5f 0 0 %.5f %.5f %.5f cm", w*f.k, h*f.k, x*f.k, (f.h-(y+h))*f.k)
+}
+
+func (f *Fpdf) gradientClipEnd() {
+ // Restore previous graphic state
+ f.out("Q")
+}
+
+func (f *Fpdf) gradient(tp int, r1, g1, b1 int, r2, g2, b2 int, x1, y1 float64, x2, y2 float64, r float64) {
+ pos := len(f.gradientList)
+ clr1 := colorValue(r1, g1, b1, "", "")
+ clr2 := colorValue(r2, g2, b2, "", "")
+ f.gradientList = append(f.gradientList, gradientType{tp, clr1.str, clr2.str,
+ x1, y1, x2, y2, r, 0})
+ f.outf("/Sh%d sh", pos)
+}
+
+// LinearGradient draws a rectangular area with a blending of one color to
+// another. The rectangle is of width w and height h. Its upper left corner is
+// positioned at point (x, y).
+//
+// Each color is specified with three component values, one each for red, green
+// and blue. The values range from 0 to 255. The first color is specified by
+// (r1, g1, b1) and the second color by (r2, g2, b2).
+//
+// The blending is controlled with a gradient vector that uses normalized
+// coordinates in which the lower left corner is position (0, 0) and the upper
+// right corner is (1, 1). The vector's origin and destination are specified by
+// the points (x1, y1) and (x2, y2). In a linear gradient, blending occurs
+// perpendicularly to the vector. The vector does not necessarily need to be
+// anchored on the rectangle edge. Color 1 is used up to the origin of the
+// vector and color 2 is used beyond the vector's end point. Between the points
+// the colors are gradually blended.
+func (f *Fpdf) LinearGradient(x, y, w, h float64, r1, g1, b1 int, r2, g2, b2 int, x1, y1, x2, y2 float64) {
+ f.gradientClipStart(x, y, w, h)
+ f.gradient(2, r1, g1, b1, r2, g2, b2, x1, y1, x2, y2, 0)
+ f.gradientClipEnd()
+}
+
+// RadialGradient draws a rectangular area with a blending of one color to
+// another. The rectangle is of width w and height h. Its upper left corner is
+// positioned at point (x, y).
+//
+// Each color is specified with three component values, one each for red, green
+// and blue. The values range from 0 to 255. The first color is specified by
+// (r1, g1, b1) and the second color by (r2, g2, b2).
+//
+// The blending is controlled with a point and a circle, both specified with
+// normalized coordinates in which the lower left corner of the rendered
+// rectangle is position (0, 0) and the upper right corner is (1, 1). Color 1
+// begins at the origin point specified by (x1, y1). Color 2 begins at the
+// circle specified by the center point (x2, y2) and radius r. Colors are
+// gradually blended from the origin to the circle. The origin and the circle's
+// center do not necessarily have to coincide, but the origin must be within
+// the circle to avoid rendering problems.
+//
+// The LinearGradient() example demonstrates this method.
+func (f *Fpdf) RadialGradient(x, y, w, h float64, r1, g1, b1 int, r2, g2, b2 int, x1, y1, x2, y2, r float64) {
+ f.gradientClipStart(x, y, w, h)
+ f.gradient(3, r1, g1, b1, r2, g2, b2, x1, y1, x2, y2, r)
+ f.gradientClipEnd()
+}
+
+// ClipRect begins a rectangular clipping operation. The rectangle is of width
+// w and height h. Its upper left corner is positioned at point (x, y). outline
+// is true to draw a border with the current draw color and line width centered
+// on the rectangle's perimeter. Only the outer half of the border will be
+// shown. After calling this method, all rendering operations (for example,
+// Image(), LinearGradient(), etc) will be clipped by the specified rectangle.
+// Call ClipEnd() to restore unclipped operations.
+//
+// This ClipText() example demonstrates this method.
+func (f *Fpdf) ClipRect(x, y, w, h float64, outline bool) {
+ f.clipNest++
+ f.outf("q %.2f %.2f %.2f %.2f re W %s", x*f.k, (f.h-y)*f.k, w*f.k, -h*f.k, strIf(outline, "S", "n"))
+}
+
+// ClipText begins a clipping operation in which rendering is confined to the
+// character string specified by txtStr. The origin (x, y) is on the left of
+// the first character at the baseline. The current font is used. outline is
+// true to draw a border with the current draw color and line width centered on
+// the perimeters of the text characters. Only the outer half of the border
+// will be shown. After calling this method, all rendering operations (for
+// example, Image(), LinearGradient(), etc) will be clipped. Call ClipEnd() to
+// restore unclipped operations.
+func (f *Fpdf) ClipText(x, y float64, txtStr string, outline bool) {
+ f.clipNest++
+ f.outf("q BT %.5f %.5f Td %d Tr (%s) Tj ET", x*f.k, (f.h-y)*f.k, intIf(outline, 5, 7), f.escape(txtStr))
+}
+
+func (f *Fpdf) clipArc(x1, y1, x2, y2, x3, y3 float64) {
+ h := f.h
+ f.outf("%.5f %.5f %.5f %.5f %.5f %.5f c ", x1*f.k, (h-y1)*f.k,
+ x2*f.k, (h-y2)*f.k, x3*f.k, (h-y3)*f.k)
+}
+
+// ClipRoundedRect begins a rectangular clipping operation. The rectangle is of
+// width w and height h. Its upper left corner is positioned at point (x, y).
+// The rounded corners of the rectangle are specified by radius r. outline is
+// true to draw a border with the current draw color and line width centered on
+// the rectangle's perimeter. Only the outer half of the border will be shown.
+// After calling this method, all rendering operations (for example, Image(),
+// LinearGradient(), etc) will be clipped by the specified rectangle. Call
+// ClipEnd() to restore unclipped operations.
+//
+// This ClipText() example demonstrates this method.
+func (f *Fpdf) ClipRoundedRect(x, y, w, h, r float64, outline bool) {
+ f.clipNest++
+ k := f.k
+ hp := f.h
+ myArc := (4.0 / 3.0) * (math.Sqrt2 - 1.0)
+ f.outf("q %.5f %.5f m", (x+r)*k, (hp-y)*k)
+ xc := x + w - r
+ yc := y + r
+ f.outf("%.5f %.5f l", xc*k, (hp-y)*k)
+ f.clipArc(xc+r*myArc, yc-r, xc+r, yc-r*myArc, xc+r, yc)
+ xc = x + w - r
+ yc = y + h - r
+ f.outf("%.5f %.5f l", (x+w)*k, (hp-yc)*k)
+ f.clipArc(xc+r, yc+r*myArc, xc+r*myArc, yc+r, xc, yc+r)
+ xc = x + r
+ yc = y + h - r
+ f.outf("%.5f %.5f l", xc*k, (hp-(y+h))*k)
+ f.clipArc(xc-r*myArc, yc+r, xc-r, yc+r*myArc, xc-r, yc)
+ xc = x + r
+ yc = y + r
+ f.outf("%.5f %.5f l", x*k, (hp-yc)*k)
+ f.clipArc(xc-r, yc-r*myArc, xc-r*myArc, yc-r, xc, yc-r)
+ f.outf(" W %s", strIf(outline, "S", "n"))
+}
+
+// ClipEllipse begins an elliptical clipping operation. The ellipse is centered
+// at (x, y). Its horizontal and vertical radii are specified by rx and ry.
+// outline is true to draw a border with the current draw color and line width
+// centered on the ellipse's perimeter. Only the outer half of the border will
+// be shown. After calling this method, all rendering operations (for example,
+// Image(), LinearGradient(), etc) will be clipped by the specified ellipse.
+// Call ClipEnd() to restore unclipped operations.
+//
+// This ClipText() example demonstrates this method.
+func (f *Fpdf) ClipEllipse(x, y, rx, ry float64, outline bool) {
+ f.clipNest++
+ lx := (4.0 / 3.0) * rx * (math.Sqrt2 - 1)
+ ly := (4.0 / 3.0) * ry * (math.Sqrt2 - 1)
+ k := f.k
+ h := f.h
+ f.outf("q %.5f %.5f m %.5f %.5f %.5f %.5f %.5f %.5f c",
+ (x+rx)*k, (h-y)*k,
+ (x+rx)*k, (h-(y-ly))*k,
+ (x+lx)*k, (h-(y-ry))*k,
+ x*k, (h-(y-ry))*k)
+ f.outf("%.5f %.5f %.5f %.5f %.5f %.5f c",
+ (x-lx)*k, (h-(y-ry))*k,
+ (x-rx)*k, (h-(y-ly))*k,
+ (x-rx)*k, (h-y)*k)
+ f.outf("%.5f %.5f %.5f %.5f %.5f %.5f c",
+ (x-rx)*k, (h-(y+ly))*k,
+ (x-lx)*k, (h-(y+ry))*k,
+ x*k, (h-(y+ry))*k)
+ f.outf("%.5f %.5f %.5f %.5f %.5f %.5f c W %s",
+ (x+lx)*k, (h-(y+ry))*k,
+ (x+rx)*k, (h-(y+ly))*k,
+ (x+rx)*k, (h-y)*k,
+ strIf(outline, "S", "n"))
+}
+
+// ClipCircle begins a circular clipping operation. The circle is centered at
+// (x, y) and has radius r. outline is true to draw a border with the current
+// draw color and line width centered on the circle's perimeter. Only the outer
+// half of the border will be shown. After calling this method, all rendering
+// operations (for example, Image(), LinearGradient(), etc) will be clipped by
+// the specified circle. Call ClipEnd() to restore unclipped operations.
+//
+// The ClipText() example demonstrates this method.
+func (f *Fpdf) ClipCircle(x, y, r float64, outline bool) {
+ f.ClipEllipse(x, y, r, r, outline)
+}
+
+// ClipPolygon begins a clipping operation within a polygon. The figure is
+// defined by a series of vertices specified by points. The x and y fields of
+// the points use the units established in New(). The last point in the slice
+// will be implicitly joined to the first to close the polygon. outline is true
+// to draw a border with the current draw color and line width centered on the
+// polygon's perimeter. Only the outer half of the border will be shown. After
+// calling this method, all rendering operations (for example, Image(),
+// LinearGradient(), etc) will be clipped by the specified polygon. Call
+// ClipEnd() to restore unclipped operations.
+//
+// The ClipText() example demonstrates this method.
+func (f *Fpdf) ClipPolygon(points []PointType, outline bool) {
+ f.clipNest++
+ var s fmtBuffer
+ h := f.h
+ k := f.k
+ s.printf("q ")
+ for j, pt := range points {
+ s.printf("%.5f %.5f %s ", pt.X*k, (h-pt.Y)*k, strIf(j == 0, "m", "l"))
+ }
+ s.printf("h W %s", strIf(outline, "S", "n"))
+ f.out(s.String())
+}
+
+// ClipEnd ends a clipping operation that was started with a call to
+// ClipRect(), ClipRoundedRect(), ClipText(), ClipEllipse(), ClipCircle() or
+// ClipPolygon(). Clipping operations can be nested. The document cannot be
+// successfully output while a clipping operation is active.
+//
+// The ClipText() example demonstrates this method.
+func (f *Fpdf) ClipEnd() {
+ if f.err == nil {
+ if f.clipNest > 0 {
+ f.clipNest--
+ f.out("Q")
+ } else {
+ f.err = fmt.Errorf("error attempting to end clip operation out of sequence")
+ }
+ }
+}
+
+// AddFont imports a TrueType, OpenType or Type1 font and makes it available.
+// It is necessary to generate a font definition file first with the makefont
+// utility. It is not necessary to call this function for the core PDF fonts
+// (courier, helvetica, times, zapfdingbats).
+//
+// The JSON definition file (and the font file itself when embedding) must be
+// present in the font directory. If it is not found, the error "Could not
+// include font definition file" is set.
+//
+// family specifies the font family. The name can be chosen arbitrarily. If it
+// is a standard family name, it will override the corresponding font. This
+// string is used to subsequently set the font with the SetFont method.
+//
+// style specifies the font style. Acceptable values are (case insensitive) the
+// empty string for regular style, "B" for bold, "I" for italic, or "BI" or
+// "IB" for bold and italic combined.
+//
+// fileStr specifies the base name with ".json" extension of the font
+// definition file to be added. The file will be loaded from the font directory
+// specified in the call to New() or SetFontLocation().
+func (f *Fpdf) AddFont(familyStr, styleStr, fileStr string) {
+ if fileStr == "" {
+ fileStr = strings.Replace(familyStr, " ", "", -1) + strings.ToLower(styleStr) + ".json"
+ }
+
+ if f.fontLoader != nil {
+ reader, err := f.fontLoader.Open(fileStr)
+ if err == nil {
+ f.AddFontFromReader(familyStr, styleStr, reader)
+ if closer, ok := reader.(io.Closer); ok {
+ closer.Close()
+ }
+ return
+ }
+ }
+
+ fileStr = path.Join(f.fontpath, fileStr)
+ file, err := os.Open(fileStr)
+ if err != nil {
+ f.err = err
+ return
+ }
+ defer file.Close()
+
+ f.AddFontFromReader(familyStr, styleStr, file)
+}
+
+// AddFontFromBytes imports a TrueType, OpenType or Type1 font from static
+// bytes within the executable and makes it available for use in the generated
+// document.
+//
+// family specifies the font family. The name can be chosen arbitrarily. If it
+// is a standard family name, it will override the corresponding font. This
+// string is used to subsequently set the font with the SetFont method.
+//
+// style specifies the font style. Acceptable values are (case insensitive) the
+// empty string for regular style, "B" for bold, "I" for italic, or "BI" or
+// "IB" for bold and italic combined.
+//
+// jsonFileBytes contain all bytes of JSON file.
+//
+// zFileBytes contain all bytes of Z file.
+func (f *Fpdf) AddFontFromBytes(familyStr string, styleStr string, jsonFileBytes []byte, zFileBytes []byte) {
+ if f.err != nil {
+ return
+ }
+
+ // load font key
+ var ok bool
+ fontkey := getFontKey(familyStr, styleStr)
+ _, ok = f.fonts[fontkey]
+
+ if ok {
+ return
+ }
+
+ // load font definitions
+ var info fontDefType
+ err := json.Unmarshal(jsonFileBytes, &info)
+
+ if err != nil {
+ f.err = err
+ }
+
+ if f.err != nil {
+ return
+ }
+
+ // search existing encodings
+ info.I = len(f.fonts)
+
+ if len(info.Diff) > 0 {
+ n := -1
+
+ for j, str := range f.diffs {
+ if str == info.Diff {
+ n = j + 1
+ break
+ }
+ }
+
+ if n < 0 {
+ f.diffs = append(f.diffs, info.Diff)
+ n = len(f.diffs)
+ }
+
+ info.DiffN = n
+ }
+
+ // embed font
+ if len(info.File) > 0 {
+ if info.Tp == "TrueType" {
+ f.fontFiles[info.File] = fontFileType{
+ length1: int64(info.OriginalSize),
+ embedded: true,
+ content: zFileBytes,
+ }
+ } else {
+ f.fontFiles[info.File] = fontFileType{
+ length1: int64(info.Size1),
+ length2: int64(info.Size2),
+ embedded: true,
+ content: zFileBytes,
+ }
+ }
+ }
+
+ f.fonts[fontkey] = info
+}
+
+// getFontKey is used by AddFontFromReader and GetFontDesc
+func getFontKey(familyStr, styleStr string) string {
+ familyStr = strings.ToLower(familyStr)
+ styleStr = strings.ToUpper(styleStr)
+ if styleStr == "IB" {
+ styleStr = "BI"
+ }
+ return familyStr + styleStr
+}
+
+// AddFontFromReader imports a TrueType, OpenType or Type1 font and makes it
+// available using a reader that satisifies the io.Reader interface. See
+// AddFont for details about familyStr and styleStr.
+func (f *Fpdf) AddFontFromReader(familyStr, styleStr string, r io.Reader) {
+ if f.err != nil {
+ return
+ }
+ // dbg("Adding family [%s], style [%s]", familyStr, styleStr)
+ var ok bool
+ fontkey := getFontKey(familyStr, styleStr)
+ _, ok = f.fonts[fontkey]
+ if ok {
+ return
+ }
+ var info fontDefType
+ info = f.loadfont(r)
+ if f.err != nil {
+ return
+ }
+ info.I = len(f.fonts)
+ if len(info.Diff) > 0 {
+ // Search existing encodings
+ n := -1
+ for j, str := range f.diffs {
+ if str == info.Diff {
+ n = j + 1
+ break
+ }
+ }
+ if n < 0 {
+ f.diffs = append(f.diffs, info.Diff)
+ n = len(f.diffs)
+ }
+ info.DiffN = n
+ }
+ // dbg("font [%s], type [%s]", info.File, info.Tp)
+ if len(info.File) > 0 {
+ // Embedded font
+ if info.Tp == "TrueType" {
+ f.fontFiles[info.File] = fontFileType{length1: int64(info.OriginalSize)}
+ } else {
+ f.fontFiles[info.File] = fontFileType{length1: int64(info.Size1), length2: int64(info.Size2)}
+ }
+ }
+ f.fonts[fontkey] = info
+ return
+}
+
+// GetFontDesc returns the font descriptor, which can be used for
+// example to find the baseline of a font. If familyStr is empty
+// current font descriptor will be returned.
+// See FontDescType for documentation about the font descriptor.
+// See AddFont for details about familyStr and styleStr.
+func (f *Fpdf) GetFontDesc(familyStr, styleStr string) FontDescType {
+ if familyStr == "" {
+ return f.currentFont.Desc
+ }
+ return f.fonts[getFontKey(familyStr, styleStr)].Desc
+}
+
+// SetFont sets the font used to print character strings. It is mandatory to
+// call this method at least once before printing text or the resulting
+// document will not be valid.
+//
+// The font can be either a standard one or a font added via the AddFont()
+// method or AddFontFromReader() method. Standard fonts use the Windows
+// encoding cp1252 (Western Europe).
+//
+// The method can be called before the first page is created and the font is
+// kept from page to page. If you just wish to change the current font size, it
+// is simpler to call SetFontSize().
+//
+// Note: the font definition file must be accessible. An error is set if the
+// file cannot be read.
+//
+// familyStr specifies the font family. It can be either a name defined by
+// AddFont(), AddFontFromReader() or one of the standard families (case
+// insensitive): "Courier" for fixed-width, "Helvetica" or "Arial" for sans
+// serif, "Times" for serif, "Symbol" or "ZapfDingbats" for symbolic.
+//
+// styleStr can be "B" (bold), "I" (italic), "U" (underscore) or any
+// combination. The default value (specified with an empty string) is regular.
+// Bold and italic styles do not apply to Symbol and ZapfDingbats.
+//
+// size is the font size measured in points. The default value is the current
+// size. If no size has been specified since the beginning of the document, the
+// value taken is 12.
+func (f *Fpdf) SetFont(familyStr, styleStr string, size float64) {
+ // dbg("SetFont x %.2f, lMargin %.2f", f.x, f.lMargin)
+
+ if f.err != nil {
+ return
+ }
+ // dbg("SetFont")
+ var ok bool
+ if familyStr == "" {
+ familyStr = f.fontFamily
+ } else {
+ familyStr = strings.ToLower(familyStr)
+ }
+ styleStr = strings.ToUpper(styleStr)
+ f.underline = strings.Contains(styleStr, "U")
+ if f.underline {
+ styleStr = strings.Replace(styleStr, "U", "", -1)
+ }
+ if styleStr == "IB" {
+ styleStr = "BI"
+ }
+ if size == 0.0 {
+ size = f.fontSizePt
+ }
+ // Test if font is already selected
+ if f.fontFamily == familyStr && f.fontStyle == styleStr && f.fontSizePt == size {
+ return
+ }
+ // Test if font is already loaded
+ fontkey := familyStr + styleStr
+ _, ok = f.fonts[fontkey]
+ if !ok {
+ // Test if one of the core fonts
+ if familyStr == "arial" {
+ familyStr = "helvetica"
+ }
+ _, ok = f.coreFonts[familyStr]
+ if ok {
+ if familyStr == "symbol" {
+ familyStr = "zapfdingbats"
+ }
+ if familyStr == "zapfdingbats" {
+ styleStr = ""
+ }
+ fontkey = familyStr + styleStr
+ _, ok = f.fonts[fontkey]
+ if !ok {
+ rdr := f.coreFontReader(familyStr, styleStr)
+ if f.err == nil {
+ f.AddFontFromReader(familyStr, styleStr, rdr)
+ }
+ if f.err != nil {
+ return
+ }
+ }
+ } else {
+ f.err = fmt.Errorf("undefined font: %s %s", familyStr, styleStr)
+ return
+ }
+ }
+ // Select it
+ f.fontFamily = familyStr
+ f.fontStyle = styleStr
+ f.fontSizePt = size
+ f.fontSize = size / f.k
+ f.currentFont = f.fonts[fontkey]
+ if f.page > 0 {
+ f.outf("BT /F%d %.2f Tf ET", f.currentFont.I, f.fontSizePt)
+ }
+ return
+}
+
+// SetFontSize defines the size of the current font. Size is specified in
+// points (1/ 72 inch). See also SetFontUnitSize().
+func (f *Fpdf) SetFontSize(size float64) {
+ if f.fontSizePt == size {
+ return
+ }
+ f.fontSizePt = size
+ f.fontSize = size / f.k
+ if f.page > 0 {
+ f.outf("BT /F%d %.2f Tf ET", f.currentFont.I, f.fontSizePt)
+ }
+}
+
+// SetFontUnitSize defines the size of the current font. Size is specified in
+// the unit of measure specified in New(). See also SetFontSize().
+func (f *Fpdf) SetFontUnitSize(size float64) {
+ if f.fontSize == size {
+ return
+ }
+ f.fontSizePt = size * f.k
+ f.fontSize = size
+ if f.page > 0 {
+ f.outf("BT /F%d %.2f Tf ET", f.currentFont.I, f.fontSizePt)
+ }
+}
+
+// GetFontSize returns the size of the current font in points followed by the
+// size in the unit of measure specified in New(). The second value can be used
+// as a line height value in drawing operations.
+func (f *Fpdf) GetFontSize() (ptSize, unitSize float64) {
+ return f.fontSizePt, f.fontSize
+}
+
+// AddLink creates a new internal link and returns its identifier. An internal
+// link is a clickable area which directs to another place within the document.
+// The identifier can then be passed to Cell(), Write(), Image() or Link(). The
+// destination is defined with SetLink().
+func (f *Fpdf) AddLink() int {
+ f.links = append(f.links, intLinkType{})
+ return len(f.links) - 1
+}
+
+// SetLink defines the page and position a link points to. See AddLink().
+func (f *Fpdf) SetLink(link int, y float64, page int) {
+ if y == -1 {
+ y = f.y
+ }
+ if page == -1 {
+ page = f.page
+ }
+ f.links[link] = intLinkType{page, y}
+}
+
+// Add a new clickable link on current page
+func (f *Fpdf) newLink(x, y, w, h float64, link int, linkStr string) {
+ // linkList, ok := f.pageLinks[f.page]
+ // if !ok {
+ // linkList = make([]linkType, 0, 8)
+ // f.pageLinks[f.page] = linkList
+ // }
+ f.pageLinks[f.page] = append(f.pageLinks[f.page],
+ linkType{x * f.k, f.hPt - y*f.k, w * f.k, h * f.k, link, linkStr})
+}
+
+// Link puts a link on a rectangular area of the page. Text or image links are
+// generally put via Cell(), Write() or Image(), but this method can be useful
+// for instance to define a clickable area inside an image. link is the value
+// returned by AddLink().
+func (f *Fpdf) Link(x, y, w, h float64, link int) {
+ f.newLink(x, y, w, h, link, "")
+}
+
+// LinkString puts a link on a rectangular area of the page. Text or image
+// links are generally put via Cell(), Write() or Image(), but this method can
+// be useful for instance to define a clickable area inside an image. linkStr
+// is the target URL.
+func (f *Fpdf) LinkString(x, y, w, h float64, linkStr string) {
+ f.newLink(x, y, w, h, 0, linkStr)
+}
+
+// Bookmark sets a bookmark that will be displayed in a sidebar outline. txtStr
+// is the title of the bookmark. level specifies the level of the bookmark in
+// the outline; 0 is the top level, 1 is just below, and so on. y specifies the
+// vertical position of the bookmark destination in the current page; -1
+// indicates the current position.
+func (f *Fpdf) Bookmark(txtStr string, level int, y float64) {
+ if y == -1 {
+ y = f.y
+ }
+ f.outlines = append(f.outlines, outlineType{text: txtStr, level: level, y: y, p: f.PageNo(), prev: -1, last: -1, next: -1, first: -1})
+}
+
+// Text prints a character string. The origin (x, y) is on the left of the
+// first character at the baseline. This method permits a string to be placed
+// precisely on the page, but it is usually easier to use Cell(), MultiCell()
+// or Write() which are the standard methods to print text.
+func (f *Fpdf) Text(x, y float64, txtStr string) {
+ s := sprintf("BT %.2f %.2f Td (%s) Tj ET", x*f.k, (f.h-y)*f.k, f.escape(txtStr))
+ if f.underline && txtStr != "" {
+ s += " " + f.dounderline(x, y, txtStr)
+ }
+ if f.colorFlag {
+ s = sprintf("q %s %s Q", f.color.text.str, s)
+ }
+ f.out(s)
+}
+
+// SetAcceptPageBreakFunc allows the application to control where page breaks
+// occur.
+//
+// fnc is an application function (typically a closure) that is called by the
+// library whenever a page break condition is met. The break is issued if true
+// is returned. The default implementation returns a value according to the
+// mode selected by SetAutoPageBreak. The function provided should not be
+// called by the application.
+//
+// See the example for SetLeftMargin() to see how this function can be used to
+// manage multiple columns.
+func (f *Fpdf) SetAcceptPageBreakFunc(fnc func() bool) {
+ f.acceptPageBreak = fnc
+}
+
+// CellFormat prints a rectangular cell with optional borders, background color
+// and character string. The upper-left corner of the cell corresponds to the
+// current position. The text can be aligned or centered. After the call, the
+// current position moves to the right or to the next line. It is possible to
+// put a link on the text.
+//
+// If automatic page breaking is enabled and the cell goes beyond the limit, a
+// page break is done before outputting.
+//
+// w and h specify the width and height of the cell. If w is 0, the cell
+// extends up to the right margin. Specifying 0 for h will result in no output,
+// but the current position will be advanced by w.
+//
+// txtStr specifies the text to display.
+//
+// borderStr specifies how the cell border will be drawn. An empty string
+// indicates no border, "1" indicates a full border, and one or more of "L",
+// "T", "R" and "B" indicate the left, top, right and bottom sides of the
+// border.
+//
+// ln indicates where the current position should go after the call. Possible
+// values are 0 (to the right), 1 (to the beginning of the next line), and 2
+// (below). Putting 1 is equivalent to putting 0 and calling Ln() just after.
+//
+// alignStr specifies how the text is to be positioned within the cell.
+// Horizontal alignment is controlled by including "L", "C" or "R" (left,
+// center, right) in alignStr. Vertical alignment is controlled by including
+// "T", "M", "B" or "A" (top, middle, bottom, baseline) in alignStr. The default
+// alignment is left middle.
+//
+// fill is true to paint the cell background or false to leave it transparent.
+//
+// link is the identifier returned by AddLink() or 0 for no internal link.
+//
+// linkStr is a target URL or empty for no external link. A non--zero value for
+// link takes precedence over linkStr.
+func (f *Fpdf) CellFormat(w, h float64, txtStr string, borderStr string, ln int, alignStr string, fill bool, link int, linkStr string) {
+ // dbg("CellFormat. h = %.2f, borderStr = %s", h, borderStr)
+ if f.err != nil {
+ return
+ }
+ borderStr = strings.ToUpper(borderStr)
+ k := f.k
+ if f.y+h > f.pageBreakTrigger && !f.inHeader && !f.inFooter && f.acceptPageBreak() {
+ // Automatic page break
+ x := f.x
+ ws := f.ws
+ // dbg("auto page break, x %.2f, ws %.2f", x, ws)
+ if ws > 0 {
+ f.ws = 0
+ f.out("0 Tw")
+ }
+ f.AddPageFormat(f.curOrientation, f.curPageSize)
+ if f.err != nil {
+ return
+ }
+ f.x = x
+ if ws > 0 {
+ f.ws = ws
+ f.outf("%.3f Tw", ws*k)
+ }
+ }
+ if w == 0 {
+ w = f.w - f.rMargin - f.x
+ }
+ var s fmtBuffer
+ if fill || borderStr == "1" {
+ var op string
+ if fill {
+ if borderStr == "1" {
+ op = "B"
+ // dbg("border is '1', fill")
+ } else {
+ op = "f"
+ // dbg("border is empty, fill")
+ }
+ } else {
+ // dbg("border is '1', no fill")
+ op = "S"
+ }
+ /// dbg("(CellFormat) f.x %.2f f.k %.2f", f.x, f.k)
+ s.printf("%.2f %.2f %.2f %.2f re %s ", f.x*k, (f.h-f.y)*k, w*k, -h*k, op)
+ }
+ if len(borderStr) > 0 && borderStr != "1" {
+ // fmt.Printf("border is '%s', no fill\n", borderStr)
+ x := f.x
+ y := f.y
+ left := x * k
+ top := (f.h - y) * k
+ right := (x + w) * k
+ bottom := (f.h - (y + h)) * k
+ if strings.Contains(borderStr, "L") {
+ s.printf("%.2f %.2f m %.2f %.2f l S ", left, top, left, bottom)
+ }
+ if strings.Contains(borderStr, "T") {
+ s.printf("%.2f %.2f m %.2f %.2f l S ", left, top, right, top)
+ }
+ if strings.Contains(borderStr, "R") {
+ s.printf("%.2f %.2f m %.2f %.2f l S ", right, top, right, bottom)
+ }
+ if strings.Contains(borderStr, "B") {
+ s.printf("%.2f %.2f m %.2f %.2f l S ", left, bottom, right, bottom)
+ }
+ }
+ if len(txtStr) > 0 {
+ var dx, dy float64
+ // Horizontal alignment
+ if strings.Index(alignStr, "R") != -1 {
+ dx = w - f.cMargin - f.GetStringWidth(txtStr)
+ } else if strings.Index(alignStr, "C") != -1 {
+ dx = (w - f.GetStringWidth(txtStr)) / 2
+ } else {
+ dx = f.cMargin
+ }
+ // Vertical alignment
+ if strings.Index(alignStr, "T") != -1 {
+ dy = (f.fontSize - h) / 2.0
+ } else if strings.Index(alignStr, "B") != -1 {
+ dy = (h - f.fontSize) / 2.0
+ } else if strings.Index(alignStr, "A") != -1 {
+ var descent float64
+ d := f.currentFont.Desc
+ if d.Descent == 0 {
+ // not defined (standard font?), use average of 19%
+ descent = -0.19 * f.fontSize
+ } else {
+ descent = float64(d.Descent) * f.fontSize / float64(d.Ascent-d.Descent)
+ }
+ dy = (h-f.fontSize)/2.0 - descent
+ } else {
+ dy = 0
+ }
+ if f.colorFlag {
+ s.printf("q %s ", f.color.text.str)
+ }
+ txt2 := strings.Replace(txtStr, "\\", "\\\\", -1)
+ txt2 = strings.Replace(txt2, "(", "\\(", -1)
+ txt2 = strings.Replace(txt2, ")", "\\)", -1)
+ // if strings.Contains(txt2, "end of excerpt") {
+ // dbg("f.h %.2f, f.y %.2f, h %.2f, f.fontSize %.2f, k %.2f", f.h, f.y, h, f.fontSize, k)
+ // }
+ s.printf("BT %.2f %.2f Td (%s) Tj ET", (f.x+dx)*k, (f.h-(f.y+dy+.5*h+.3*f.fontSize))*k, txt2)
+ //BT %.2F %.2F Td (%s) Tj ET',($this->x+$dx)*$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k,$txt2);
+ if f.underline {
+ s.printf(" %s", f.dounderline(f.x+dx, f.y+dy+.5*h+.3*f.fontSize, txtStr))
+ }
+ if f.colorFlag {
+ s.printf(" Q")
+ }
+ if link > 0 || len(linkStr) > 0 {
+ f.newLink(f.x+dx, f.y+dy+.5*h-.5*f.fontSize, f.GetStringWidth(txtStr), f.fontSize, link, linkStr)
+ }
+ }
+ str := s.String()
+ if len(str) > 0 {
+ f.out(str)
+ }
+ f.lasth = h
+ if ln > 0 {
+ // Go to next line
+ f.y += h
+ if ln == 1 {
+ f.x = f.lMargin
+ }
+ } else {
+ f.x += w
+ }
+ return
+}
+
+// Cell is a simpler version of CellFormat with no fill, border, links or
+// special alignment.
+func (f *Fpdf) Cell(w, h float64, txtStr string) {
+ f.CellFormat(w, h, txtStr, "", 0, "L", false, 0, "")
+}
+
+// Cellf is a simpler printf-style version of CellFormat with no fill, border,
+// links or special alignment. See documentation for the fmt package for
+// details on fmtStr and args.
+func (f *Fpdf) Cellf(w, h float64, fmtStr string, args ...interface{}) {
+ f.CellFormat(w, h, sprintf(fmtStr, args...), "", 0, "L", false, 0, "")
+}
+
+// SplitLines splits text into several lines using the current font. Each line
+// has its length limited to a maximum width given by w. This function can be
+// used to determine the total height of wrapped text for vertical placement
+// purposes.
+//
+// You can use MultiCell if you want to print a text on several lines in a
+// simple way.
+func (f *Fpdf) SplitLines(txt []byte, w float64) [][]byte {
+ // Function contributed by Bruno Michel
+ lines := [][]byte{}
+ cw := &f.currentFont.Cw
+ wmax := int(math.Ceil((w - 2*f.cMargin) * 1000 / f.fontSize))
+ s := bytes.Replace(txt, []byte("\r"), []byte{}, -1)
+ nb := len(s)
+ for nb > 0 && s[nb-1] == '\n' {
+ nb--
+ }
+ s = s[0:nb]
+ sep := -1
+ i := 0
+ j := 0
+ l := 0
+ for i < nb {
+ c := s[i]
+ l += cw[c]
+ if c == ' ' || c == '\t' || c == '\n' {
+ sep = i
+ }
+ if c == '\n' || l > wmax {
+ if sep == -1 {
+ if i == j {
+ i++
+ }
+ sep = i
+ } else {
+ i = sep + 1
+ }
+ lines = append(lines, s[j:sep])
+ sep = -1
+ j = i
+ l = 0
+ } else {
+ i++
+ }
+ }
+ if i != j {
+ lines = append(lines, s[j:i])
+ }
+ return lines
+}
+
+// MultiCell supports printing text with line breaks. They can be automatic (as
+// soon as the text reaches the right border of the cell) or explicit (via the
+// \n character). As many cells as necessary are output, one below the other.
+//
+// Text can be aligned, centered or justified. The cell block can be framed and
+// the background painted. See CellFormat() for more details.
+//
+// w is the width of the cells. A value of zero indicates cells that reach to
+// the right margin.
+//
+// h indicates the line height of each cell in the unit of measure specified in New().
+func (f *Fpdf) MultiCell(w, h float64, txtStr, borderStr, alignStr string, fill bool) {
+ // dbg("MultiCell")
+ if alignStr == "" {
+ alignStr = "J"
+ }
+ cw := &f.currentFont.Cw
+ if w == 0 {
+ w = f.w - f.rMargin - f.x
+ }
+ wmax := (w - 2*f.cMargin) * 1000 / f.fontSize
+ s := strings.Replace(txtStr, "\r", "", -1)
+ nb := len(s)
+ // if nb > 0 && s[nb-1:nb] == "\n" {
+ if nb > 0 && []byte(s)[nb-1] == '\n' {
+ nb--
+ s = s[0:nb]
+ }
+ // dbg("[%s]\n", s)
+ var b, b2 string
+ b = "0"
+ if len(borderStr) > 0 {
+ if borderStr == "1" {
+ borderStr = "LTRB"
+ b = "LRT"
+ b2 = "LR"
+ } else {
+ b2 = ""
+ if strings.Contains(borderStr, "L") {
+ b2 += "L"
+ }
+ if strings.Contains(borderStr, "R") {
+ b2 += "R"
+ }
+ if strings.Contains(borderStr, "T") {
+ b = b2 + "T"
+ } else {
+ b = b2
+ }
+ }
+ }
+ sep := -1
+ i := 0
+ j := 0
+ l := 0.0
+ ls := 0.0
+ ns := 0
+ nl := 1
+ for i < nb {
+ // Get next character
+ c := []byte(s)[i]
+ if c == '\n' {
+ // Explicit line break
+ if f.ws > 0 {
+ f.ws = 0
+ f.out("0 Tw")
+ }
+ f.CellFormat(w, h, s[j:i], b, 2, alignStr, fill, 0, "")
+ i++
+ sep = -1
+ j = i
+ l = 0
+ ns = 0
+ nl++
+ if len(borderStr) > 0 && nl == 2 {
+ b = b2
+ }
+ continue
+ }
+ if c == ' ' {
+ sep = i
+ ls = l
+ ns++
+ }
+ l += float64(cw[c])
+ if l > wmax {
+ // Automatic line break
+ if sep == -1 {
+ if i == j {
+ i++
+ }
+ if f.ws > 0 {
+ f.ws = 0
+ f.out("0 Tw")
+ }
+ f.CellFormat(w, h, s[j:i], b, 2, alignStr, fill, 0, "")
+ } else {
+ if alignStr == "J" {
+ if ns > 1 {
+ f.ws = (wmax - ls) / 1000 * f.fontSize / float64(ns-1)
+ } else {
+ f.ws = 0
+ }
+ f.outf("%.3f Tw", f.ws*f.k)
+ }
+ f.CellFormat(w, h, s[j:sep], b, 2, alignStr, fill, 0, "")
+ i = sep + 1
+ }
+ sep = -1
+ j = i
+ l = 0
+ ns = 0
+ nl++
+ if len(borderStr) > 0 && nl == 2 {
+ b = b2
+ }
+ } else {
+ i++
+ }
+ }
+ // Last chunk
+ if f.ws > 0 {
+ f.ws = 0
+ f.out("0 Tw")
+ }
+ if len(borderStr) > 0 && strings.Contains(borderStr, "B") {
+ b += "B"
+ }
+ f.CellFormat(w, h, s[j:i], b, 2, alignStr, fill, 0, "")
+ f.x = f.lMargin
+}
+
+// Output text in flowing mode
+func (f *Fpdf) write(h float64, txtStr string, link int, linkStr string) {
+ // dbg("Write")
+ cw := &f.currentFont.Cw
+ w := f.w - f.rMargin - f.x
+ wmax := (w - 2*f.cMargin) * 1000 / f.fontSize
+ s := strings.Replace(txtStr, "\r", "", -1)
+ nb := len(s)
+ sep := -1
+ i := 0
+ j := 0
+ l := 0.0
+ nl := 1
+ for i < nb {
+ // Get next character
+ c := []byte(s)[i]
+ if c == '\n' {
+ // Explicit line break
+ f.CellFormat(w, h, s[j:i], "", 2, "", false, link, linkStr)
+ i++
+ sep = -1
+ j = i
+ l = 0.0
+ if nl == 1 {
+ f.x = f.lMargin
+ w = f.w - f.rMargin - f.x
+ wmax = (w - 2*f.cMargin) * 1000 / f.fontSize
+ }
+ nl++
+ continue
+ }
+ if c == ' ' {
+ sep = i
+ }
+ l += float64(cw[c])
+ if l > wmax {
+ // Automatic line break
+ if sep == -1 {
+ if f.x > f.lMargin {
+ // Move to next line
+ f.x = f.lMargin
+ f.y += h
+ w = f.w - f.rMargin - f.x
+ wmax = (w - 2*f.cMargin) * 1000 / f.fontSize
+ i++
+ nl++
+ continue
+ }
+ if i == j {
+ i++
+ }
+ f.CellFormat(w, h, s[j:i], "", 2, "", false, link, linkStr)
+ } else {
+ f.CellFormat(w, h, s[j:sep], "", 2, "", false, link, linkStr)
+ i = sep + 1
+ }
+ sep = -1
+ j = i
+ l = 0.0
+ if nl == 1 {
+ f.x = f.lMargin
+ w = f.w - f.rMargin - f.x
+ wmax = (w - 2*f.cMargin) * 1000 / f.fontSize
+ }
+ nl++
+ } else {
+ i++
+ }
+ }
+ // Last chunk
+ if i != j {
+ f.CellFormat(l/1000*f.fontSize, h, s[j:], "", 0, "", false, link, linkStr)
+ }
+}
+
+// Write prints text from the current position. When the right margin is
+// reached (or the \n character is met) a line break occurs and text continues
+// from the left margin. Upon method exit, the current position is left just at
+// the end of the text.
+//
+// It is possible to put a link on the text.
+//
+// h indicates the line height in the unit of measure specified in New().
+func (f *Fpdf) Write(h float64, txtStr string) {
+ f.write(h, txtStr, 0, "")
+}
+
+// Writef is like Write but uses printf-style formatting. See the documentation
+// for package fmt for more details on fmtStr and args.
+func (f *Fpdf) Writef(h float64, fmtStr string, args ...interface{}) {
+ f.write(h, sprintf(fmtStr, args...), 0, "")
+}
+
+// WriteLinkString writes text that when clicked launches an external URL. See
+// Write() for argument details.
+func (f *Fpdf) WriteLinkString(h float64, displayStr, targetStr string) {
+ f.write(h, displayStr, 0, targetStr)
+}
+
+// WriteLinkID writes text that when clicked jumps to another location in the
+// PDF. linkID is an identifier returned by AddLink(). See Write() for argument
+// details.
+func (f *Fpdf) WriteLinkID(h float64, displayStr string, linkID int) {
+ f.write(h, displayStr, linkID, "")
+}
+
+// WriteAligned is an implementation of Write that makes it possible to align
+// text.
+//
+// width indicates the width of the box the text will be drawn in. This is in
+// the unit of measure specified in New(). If it is set to 0, the bounding box
+//of the page will be taken (pageWidth - leftMargin - rightMargin).
+//
+// lineHeight indicates the line height in the unit of measure specified in
+// New().
+//
+// alignStr sees to horizontal alignment of the given textStr. The options are
+// "L", "C" and "R" (Left, Center, Right). The default is "L".
+func (f *Fpdf) WriteAligned(width, lineHeight float64, textStr, alignStr string) {
+ lMargin, _, rMargin, _ := f.GetMargins()
+
+ if width == 0 {
+ pageWidth, _ := f.GetPageSize()
+ width = pageWidth - (lMargin + rMargin)
+ }
+
+ lines := f.SplitLines([]byte(textStr), width)
+
+ for _, lineBt := range lines {
+ lineStr := string(lineBt[:])
+ lineWidth := f.GetStringWidth(lineStr)
+
+ switch alignStr {
+ case "C":
+ f.SetLeftMargin(lMargin + ((width - lineWidth) / 2))
+ f.Write(lineHeight, lineStr)
+ f.SetLeftMargin(lMargin)
+ case "R":
+ f.SetLeftMargin(lMargin + (width - lineWidth) - rMargin)
+ f.Write(lineHeight, lineStr)
+ f.SetLeftMargin(lMargin)
+ default:
+ f.Write(lineHeight, lineStr)
+ }
+ }
+}
+
+// Ln performs a line break. The current abscissa goes back to the left margin
+// and the ordinate increases by the amount passed in parameter. A negative
+// value of h indicates the height of the last printed cell.
+//
+// This method is demonstrated in the example for MultiCell.
+func (f *Fpdf) Ln(h float64) {
+ f.x = f.lMargin
+ if h < 0 {
+ f.y += f.lasth
+ } else {
+ f.y += h
+ }
+}
+
+// ImageTypeFromMime returns the image type used in various image-related
+// functions (for example, Image()) that is associated with the specified MIME
+// type. For example, "jpg" is returned if mimeStr is "image/jpeg". An error is
+// set if the specified MIME type is not supported.
+func (f *Fpdf) ImageTypeFromMime(mimeStr string) (tp string) {
+ switch mimeStr {
+ case "image/png":
+ tp = "png"
+ case "image/jpg":
+ tp = "jpg"
+ case "image/jpeg":
+ tp = "jpg"
+ case "image/gif":
+ tp = "gif"
+ default:
+ f.SetErrorf("unsupported image type: %s", mimeStr)
+ }
+ return
+}
+
+func (f *Fpdf) imageOut(info *ImageInfoType, x, y, w, h float64, flow bool, link int, linkStr string) {
+ // Automatic width and height calculation if needed
+ if w == 0 && h == 0 {
+ // Put image at 96 dpi
+ w = -96
+ h = -96
+ }
+ if w == -1 {
+ // Set image width to whatever value for dpi we read
+ // from the image or that was set manually
+ w = -info.dpi
+ }
+ if h == -1 {
+ // Set image height to whatever value for dpi we read
+ // from the image or that was set manually
+ h = -info.dpi
+ }
+ if w < 0 {
+ w = -info.w * 72.0 / w / f.k
+ }
+ if h < 0 {
+ h = -info.h * 72.0 / h / f.k
+ }
+ if w == 0 {
+ w = h * info.w / info.h
+ }
+ if h == 0 {
+ h = w * info.h / info.w
+ }
+ // Flowing mode
+ if flow {
+ if f.y+h > f.pageBreakTrigger && !f.inHeader && !f.inFooter && f.acceptPageBreak() {
+ // Automatic page break
+ x2 := f.x
+ f.AddPageFormat(f.curOrientation, f.curPageSize)
+ if f.err != nil {
+ return
+ }
+ f.x = x2
+ }
+ y = f.y
+ f.y += h
+ }
+ if x < 0 {
+ x = f.x
+ }
+ // dbg("h %.2f", h)
+ // q 85.04 0 0 NaN 28.35 NaN cm /I2 Do Q
+ f.outf("q %.5f 0 0 %.5f %.5f %.5f cm /I%d Do Q", w*f.k, h*f.k, x*f.k, (f.h-(y+h))*f.k, info.i)
+ if link > 0 || len(linkStr) > 0 {
+ f.newLink(x, y, w, h, link, linkStr)
+ }
+}
+
+// Image puts a JPEG, PNG or GIF image in the current page.
+//
+// Deprecated in favor of ImageOptions -- see that function for
+// details on the behavior of arguments
+func (f *Fpdf) Image(imageNameStr string, x, y, w, h float64, flow bool, tp string, link int, linkStr string) {
+ options := ImageOptions{
+ ReadDpi: false,
+ ImageType: tp,
+ }
+ f.ImageOptions(imageNameStr, x, y, w, h, flow, options, link, linkStr)
+}
+
+// ImageOptions puts a JPEG, PNG or GIF image in the current page. The size it
+// will take on the page can be specified in different ways. If both w and h
+// are 0, the image is rendered at 96 dpi. If either w or h is zero, it will be
+// calculated from the other dimension so that the aspect ratio is maintained.
+// If w and/or h are -1, the dpi for that dimension will be read from the
+// ImageInfoType object. PNG files can contain dpi information, and if present,
+// this information will be populated in the ImageInfoType object and used in
+// Width, Height, and Extent calculations. Otherwise, the SetDpi function can
+// be used to change the dpi from the default of 72.
+//
+// If w and h are any other negative value, their absolute values
+// indicate their dpi extents.
+//
+// Supported JPEG formats are 24 bit, 32 bit and gray scale. Supported PNG
+// formats are 24 bit, indexed color, and 8 bit indexed gray scale. If a GIF
+// image is animated, only the first frame is rendered. Transparency is
+// supported. It is possible to put a link on the image.
+//
+// imageNameStr may be the name of an image as registered with a call to either
+// RegisterImageReader() or RegisterImage(). In the first case, the image is
+// loaded using an io.Reader. This is generally useful when the image is
+// obtained from some other means than as a disk-based file. In the second
+// case, the image is loaded as a file. Alternatively, imageNameStr may
+// directly specify a sufficiently qualified filename.
+//
+// However the image is loaded, if it is used more than once only one copy is
+// embedded in the file.
+//
+// If x is negative, the current abscissa is used.
+//
+// If flow is true, the current y value is advanced after placing the image and
+// a page break may be made if necessary.
+//
+// If link refers to an internal page anchor (that is, it is non-zero; see
+// AddLink()), the image will be a clickable internal link. Otherwise, if
+// linkStr specifies a URL, the image will be a clickable external link.
+func (f *Fpdf) ImageOptions(imageNameStr string, x, y, w, h float64, flow bool, options ImageOptions, link int, linkStr string) {
+ if f.err != nil {
+ return
+ }
+ info := f.RegisterImageOptions(imageNameStr, options)
+ if f.err != nil {
+ return
+ }
+ f.imageOut(info, x, y, w, h, flow, link, linkStr)
+ return
+}
+
+// RegisterImageReader registers an image, reading it from Reader r, adding it
+// to the PDF file but not adding it to the page.
+//
+// This function is now deprecated in favor of RegisterImageOptionsReader
+func (f *Fpdf) RegisterImageReader(imgName, tp string, r io.Reader) (info *ImageInfoType) {
+ options := ImageOptions{
+ ReadDpi: false,
+ ImageType: tp,
+ }
+ return f.RegisterImageOptionsReader(imgName, options, r)
+}
+
+// ImageOptions provides a place to hang any options we want to use while
+// parsing an image.
+//
+// ImageType's possible values are (case insensitive):
+// "JPG", "JPEG", "PNG" and "GIF". If empty, the type is inferred from
+// the file extension.
+//
+// ReadDpi defines whether to attempt to automatically read the image
+// dpi information from the image file. Normally, this should be set
+// to true (understanding that not all images will have this info
+// available). However, for backwards compatibility with previous
+// versions of the API, it defaults to false.
+type ImageOptions struct {
+ ImageType string
+ ReadDpi bool
+}
+
+// RegisterImageOptionsReader registers an image, reading it from Reader r, adding it
+// to the PDF file but not adding it to the page. Use Image() with the same
+// name to add the image to the page. Note that tp should be specified in this
+// case.
+//
+// See Image() for restrictions on the image and the options parameters.
+func (f *Fpdf) RegisterImageOptionsReader(imgName string, options ImageOptions, r io.Reader) (info *ImageInfoType) {
+ // Thanks, Ivan Daniluk, for generalizing this code to use the Reader interface.
+ if f.err != nil {
+ return
+ }
+ info, ok := f.images[imgName]
+ if ok {
+ return
+ }
+
+ // First use of this image, get info
+ if options.ImageType == "" {
+ f.err = fmt.Errorf("image type should be specified if reading from custom reader")
+ return
+ }
+ options.ImageType = strings.ToLower(options.ImageType)
+ if options.ImageType == "jpeg" {
+ options.ImageType = "jpg"
+ }
+ switch options.ImageType {
+ case "jpg":
+ info = f.parsejpg(r)
+ case "png":
+ info = f.parsepng(r, options.ReadDpi)
+ case "gif":
+ info = f.parsegif(r)
+ default:
+ f.err = fmt.Errorf("unsupported image type: %s", options.ImageType)
+ }
+ if f.err != nil {
+ return
+ }
+ info.i = len(f.images) + 1
+ f.images[imgName] = info
+
+ return
+}
+
+// RegisterImage registers an image, adding it to the PDF file but not adding
+// it to the page. Use Image() with the same filename to add the image to the
+// page. Note that Image() calls this function, so this function is only
+// necessary if you need information about the image before placing it.
+//
+// This function is now deprecated in favor of RegisterImageOptions.
+// See Image() for restrictions on the image and the "tp" parameters.
+func (f *Fpdf) RegisterImage(fileStr, tp string) (info *ImageInfoType) {
+ options := ImageOptions{
+ ReadDpi: false,
+ ImageType: tp,
+ }
+ return f.RegisterImageOptions(fileStr, options)
+}
+
+// RegisterImageOptions registers an image, adding it to the PDF file but not
+// adding it to the page. Use Image() with the same filename to add the image
+// to the page. Note that Image() calls this function, so this function is only
+// necessary if you need information about the image before placing it. See
+// Image() for restrictions on the image and the "tp" parameters.
+func (f *Fpdf) RegisterImageOptions(fileStr string, options ImageOptions) (info *ImageInfoType) {
+ info, ok := f.images[fileStr]
+ if ok {
+ return
+ }
+
+ file, err := os.Open(fileStr)
+ if err != nil {
+ f.err = err
+ return
+ }
+ defer file.Close()
+
+ // First use of this image, get info
+ if options.ImageType == "" {
+ pos := strings.LastIndex(fileStr, ".")
+ if pos < 0 {
+ f.err = fmt.Errorf("image file has no extension and no type was specified: %s", fileStr)
+ return
+ }
+ options.ImageType = fileStr[pos+1:]
+ }
+
+ return f.RegisterImageOptionsReader(fileStr, options, file)
+}
+
+// GetImageInfo returns information about the registered image specified by
+// imageStr. If the image has not been registered, nil is returned. The
+// internal error is not modified by this method.
+func (f *Fpdf) GetImageInfo(imageStr string) (info *ImageInfoType) {
+ return f.images[imageStr]
+}
+
+// GetConversionRatio returns the conversion ratio based on the unit given when
+// creating the PDF.
+func (f *Fpdf) GetConversionRatio() float64 {
+ return f.k
+}
+
+// GetXY returns the abscissa and ordinate of the current position.
+//
+// Note: the value returned for the abscissa will be affected by the current
+// cell margin. To account for this, you may need to either add the value
+// returned by GetCellMargin() to it or call SetCellMargin(0) to remove the
+// cell margin.
+func (f *Fpdf) GetXY() (float64, float64) {
+ return f.x, f.y
+}
+
+// GetX returns the abscissa of the current position.
+//
+// Note: the value returned will be affected by the current cell margin. To
+// account for this, you may need to either add the value returned by
+// GetCellMargin() to it or call SetCellMargin(0) to remove the cell margin.
+func (f *Fpdf) GetX() float64 {
+ return f.x
+}
+
+// SetX defines the abscissa of the current position. If the passed value is
+// negative, it is relative to the right of the page.
+func (f *Fpdf) SetX(x float64) {
+ if x >= 0 {
+ f.x = x
+ } else {
+ f.x = f.w + x
+ }
+}
+
+// GetY returns the ordinate of the current position.
+func (f *Fpdf) GetY() float64 {
+ return f.y
+}
+
+// SetY moves the current abscissa back to the left margin and sets the
+// ordinate. If the passed value is negative, it is relative to the bottom of
+// the page.
+func (f *Fpdf) SetY(y float64) {
+ // dbg("SetY x %.2f, lMargin %.2f", f.x, f.lMargin)
+ f.x = f.lMargin
+ if y >= 0 {
+ f.y = y
+ } else {
+ f.y = f.h + y
+ }
+}
+
+// SetXY defines the abscissa and ordinate of the current position. If the
+// passed values are negative, they are relative respectively to the right and
+// bottom of the page.
+func (f *Fpdf) SetXY(x, y float64) {
+ f.SetY(y)
+ f.SetX(x)
+}
+
+// SetProtection applies certain constraints on the finished PDF document.
+//
+// actionFlag is a bitflag that controls various document operations.
+// CnProtectPrint allows the document to be printed. CnProtectModify allows a
+// document to be modified by a PDF editor. CnProtectCopy allows text and
+// images to be copied into the system clipboard. CnProtectAnnotForms allows
+// annotations and forms to be added by a PDF editor. These values can be
+// combined by or-ing them together, for example,
+// CnProtectCopy|CnProtectModify. This flag is advisory; not all PDF readers
+// implement the constraints that this argument attempts to control.
+//
+// userPassStr specifies the password that will need to be provided to view the
+// contents of the PDF. The permissions specified by actionFlag will apply.
+//
+// ownerPassStr specifies the password that will need to be provided to gain
+// full access to the document regardless of the actionFlag value. An empty
+// string for this argument will be replaced with a random value, effectively
+// prohibiting full access to the document.
+func (f *Fpdf) SetProtection(actionFlag byte, userPassStr, ownerPassStr string) {
+ if f.err != nil {
+ return
+ }
+ f.protect.setProtection(actionFlag, userPassStr, ownerPassStr)
+}
+
+// OutputAndClose sends the PDF document to the writer specified by w. This
+// method will close both f and w, even if an error is detected and no document
+// is produced.
+func (f *Fpdf) OutputAndClose(w io.WriteCloser) error {
+ f.Output(w)
+ w.Close()
+ return f.err
+}
+
+// OutputFileAndClose creates or truncates the file specified by fileStr and
+// writes the PDF document to it. This method will close f and the newly
+// written file, even if an error is detected and no document is produced.
+//
+// Most examples demonstrate the use of this method.
+func (f *Fpdf) OutputFileAndClose(fileStr string) error {
+ if f.err == nil {
+ pdfFile, err := os.Create(fileStr)
+ if err == nil {
+ f.Output(pdfFile)
+ pdfFile.Close()
+ } else {
+ f.err = err
+ }
+ }
+ return f.err
+}
+
+// Output sends the PDF document to the writer specified by w. No output will
+// take place if an error has occurred in the document generation process. w
+// remains open after this function returns. After returning, f is in a closed
+// state and its methods should not be called.
+func (f *Fpdf) Output(w io.Writer) error {
+ if f.err != nil {
+ return f.err
+ }
+ // dbg("Output")
+ if f.state < 3 {
+ f.Close()
+ }
+ _, err := f.buffer.WriteTo(w)
+ if err != nil {
+ f.err = err
+ }
+ return f.err
+}
+
+func (f *Fpdf) getpagesizestr(sizeStr string) (size SizeType) {
+ if f.err != nil {
+ return
+ }
+ sizeStr = strings.ToLower(sizeStr)
+ // dbg("Size [%s]", sizeStr)
+ var ok bool
+ size, ok = f.stdPageSizes[sizeStr]
+ if ok {
+ // dbg("found %s", sizeStr)
+ size.Wd /= f.k
+ size.Ht /= f.k
+
+ } else {
+ f.err = fmt.Errorf("unknown page size %s", sizeStr)
+ }
+ return
+}
+
+func (f *Fpdf) _getpagesize(size SizeType) SizeType {
+ if size.Wd > size.Ht {
+ size.Wd, size.Ht = size.Ht, size.Wd
+ }
+ return size
+}
+
+func (f *Fpdf) beginpage(orientationStr string, size SizeType) {
+ if f.err != nil {
+ return
+ }
+ f.page++
+ f.pages = append(f.pages, bytes.NewBufferString(""))
+ f.pageLinks = append(f.pageLinks, make([]linkType, 0, 0))
+ f.state = 2
+ f.x = f.lMargin
+ f.y = f.tMargin
+ f.fontFamily = ""
+ // Check page size and orientation
+ if orientationStr == "" {
+ orientationStr = f.defOrientation
+ } else {
+ orientationStr = strings.ToUpper(orientationStr[0:1])
+ }
+ if orientationStr != f.curOrientation || size.Wd != f.curPageSize.Wd || size.Ht != f.curPageSize.Ht {
+ // New size or orientation
+ if orientationStr == "P" {
+ f.w = size.Wd
+ f.h = size.Ht
+ } else {
+ f.w = size.Ht
+ f.h = size.Wd
+ }
+ f.wPt = f.w * f.k
+ f.hPt = f.h * f.k
+ f.pageBreakTrigger = f.h - f.bMargin
+ f.curOrientation = orientationStr
+ f.curPageSize = size
+ }
+ if orientationStr != f.defOrientation || size.Wd != f.defPageSize.Wd || size.Ht != f.defPageSize.Ht {
+ f.pageSizes[f.page] = SizeType{f.wPt, f.hPt}
+ }
+ return
+}
+
+func (f *Fpdf) endpage() {
+ f.EndLayer()
+ f.state = 1
+}
+
+// Load a font definition file from the given Reader
+func (f *Fpdf) loadfont(r io.Reader) (def fontDefType) {
+ if f.err != nil {
+ return
+ }
+ // dbg("Loading font [%s]", fontStr)
+ var buf bytes.Buffer
+ _, err := buf.ReadFrom(r)
+ if err != nil {
+ f.err = err
+ return
+ }
+ err = json.Unmarshal(buf.Bytes(), &def)
+ if err != nil {
+ f.err = err
+ }
+ // dump(def)
+ return
+}
+
+// Escape special characters in strings
+func (f *Fpdf) escape(s string) string {
+ s = strings.Replace(s, "\\", "\\\\", -1)
+ s = strings.Replace(s, "(", "\\(", -1)
+ s = strings.Replace(s, ")", "\\)", -1)
+ s = strings.Replace(s, "\r", "\\r", -1)
+ return s
+}
+
+// Format a text string
+func (f *Fpdf) textstring(s string) string {
+ if f.protect.encrypted {
+ b := []byte(s)
+ f.protect.rc4(uint32(f.n), &b)
+ s = string(b)
+ }
+ return "(" + f.escape(s) + ")"
+}
+
+func blankCount(str string) (count int) {
+ l := len(str)
+ for j := 0; j < l; j++ {
+ if byte(' ') == str[j] {
+ count++
+ }
+ }
+ return
+}
+
+// Underline text
+func (f *Fpdf) dounderline(x, y float64, txt string) string {
+ up := float64(f.currentFont.Up)
+ ut := float64(f.currentFont.Ut)
+ w := f.GetStringWidth(txt) + f.ws*float64(blankCount(txt))
+ return sprintf("%.2f %.2f %.2f %.2f re f", x*f.k,
+ (f.h-(y-up/1000*f.fontSize))*f.k, w*f.k, -ut/1000*f.fontSizePt)
+}
+
+func bufEqual(buf []byte, str string) bool {
+ return string(buf[0:len(str)]) == str
+}
+
+func be16(buf []byte) int {
+ return 256*int(buf[0]) + int(buf[1])
+}
+
+func (f *Fpdf) newImageInfo() *ImageInfoType {
+ // default dpi to 72 unless told otherwise
+ return &ImageInfoType{scale: f.k, dpi: 72}
+}
+
+// Extract info from io.Reader with JPEG data
+// Thank you, Bruno Michel, for providing this code.
+func (f *Fpdf) parsejpg(r io.Reader) (info *ImageInfoType) {
+ info = f.newImageInfo()
+ var (
+ data bytes.Buffer
+ err error
+ )
+ _, err = data.ReadFrom(r)
+ if err != nil {
+ f.err = err
+ return
+ }
+ info.data = data.Bytes()
+
+ config, err := jpeg.DecodeConfig(bytes.NewReader(info.data))
+ if err != nil {
+ f.err = err
+ return
+ }
+ info.w = float64(config.Width)
+ info.h = float64(config.Height)
+ info.f = "DCTDecode"
+ info.bpc = 8
+ switch config.ColorModel {
+ case color.GrayModel:
+ info.cs = "DeviceGray"
+ case color.YCbCrModel:
+ info.cs = "DeviceRGB"
+ case color.CMYKModel:
+ info.cs = "DeviceCMYK"
+ default:
+ f.err = fmt.Errorf("image JPEG buffer has unsupported color space (%v)", config.ColorModel)
+ return
+ }
+ return
+}
+
+// Extract info from a PNG data
+func (f *Fpdf) parsepng(r io.Reader, readdpi bool) (info *ImageInfoType) {
+ buf, err := bufferFromReader(r)
+ if err != nil {
+ f.err = err
+ return
+ }
+ return f.parsepngstream(buf, readdpi)
+}
+
+func (f *Fpdf) readBeInt32(buf *bytes.Buffer) (val int32) {
+ err := binary.Read(buf, binary.BigEndian, &val)
+ if err != nil {
+ f.err = err
+ }
+ return
+}
+
+func (f *Fpdf) readByte(buf *bytes.Buffer) (val byte) {
+ err := binary.Read(buf, binary.BigEndian, &val)
+ if err != nil {
+ f.err = err
+ }
+ return
+}
+
+// Extract info from a GIF data (via PNG conversion)
+func (f *Fpdf) parsegif(r io.Reader) (info *ImageInfoType) {
+ data, err := bufferFromReader(r)
+ if err != nil {
+ f.err = err
+ return
+ }
+ var img image.Image
+ img, err = gif.Decode(data)
+ if err != nil {
+ f.err = err
+ return
+ }
+ pngBuf := new(bytes.Buffer)
+ err = png.Encode(pngBuf, img)
+ if err != nil {
+ f.err = err
+ return
+ }
+ return f.parsepngstream(pngBuf, false)
+}
+
+// Begin a new object
+func (f *Fpdf) newobj() {
+ // dbg("newobj")
+ f.n++
+ for j := len(f.offsets); j <= f.n; j++ {
+ f.offsets = append(f.offsets, 0)
+ }
+ f.offsets[f.n] = f.buffer.Len()
+ f.outf("%d 0 obj", f.n)
+}
+
+func (f *Fpdf) putstream(b []byte) {
+ // dbg("putstream")
+ if f.protect.encrypted {
+ f.protect.rc4(uint32(f.n), &b)
+ }
+ f.out("stream")
+ f.out(string(b))
+ f.out("endstream")
+}
+
+// Add a line to the document
+func (f *Fpdf) out(s string) {
+ if f.state == 2 {
+ f.pages[f.page].WriteString(s)
+ f.pages[f.page].WriteString("\n")
+ } else {
+ f.buffer.WriteString(s)
+ f.buffer.WriteString("\n")
+ }
+}
+
+// Add a buffered line to the document
+func (f *Fpdf) outbuf(b *bytes.Buffer) {
+ if f.state == 2 {
+ f.pages[f.page].ReadFrom(b)
+ f.pages[f.page].WriteString("\n")
+ } else {
+ f.buffer.ReadFrom(b)
+ f.buffer.WriteString("\n")
+ }
+}
+
+// RawWriteStr writes a string directly to the PDF generation buffer. This is a
+// low-level function that is not required for normal PDF construction. An
+// understanding of the PDF specification is needed to use this method
+// correctly.
+func (f *Fpdf) RawWriteStr(str string) {
+ f.out(str)
+}
+
+// RawWriteBuf writes the contents of the specified buffer directly to the PDF
+// generation buffer. This is a low-level function that is not required for
+// normal PDF construction. An understanding of the PDF specification is needed
+// to use this method correctly.
+func (f *Fpdf) RawWriteBuf(buf *bytes.Buffer) {
+ f.outbuf(buf)
+}
+
+// Add a formatted line to the document
+func (f *Fpdf) outf(fmtStr string, args ...interface{}) {
+ f.out(sprintf(fmtStr, args...))
+}
+
+// SetDefaultCatalogSort sets the default value of the catalog sort flag that
+// will be used when initializing a new Fpdf instance. See SetCatalogSort() for
+// more details.
+func SetDefaultCatalogSort(flag bool) {
+ gl.catalogSort = flag
+}
+
+// SetCatalogSort sets a flag that will be used, if true, to consistently order
+// the document's internal resource catalogs. This method is typically only
+// used for test purposes to facilitate PDF comparison.
+func (f *Fpdf) SetCatalogSort(flag bool) {
+ f.catalogSort = flag
+}
+
+// SetDefaultCreationDate sets the default value of the document creation date
+// that will be used when initializing a new Fpdf instance. See
+// SetCreationDate() for more details.
+func SetDefaultCreationDate(tm time.Time) {
+ gl.creationDate = tm
+}
+
+// SetCreationDate fixes the document's internal CreationDate value. By
+// default, the time when the document is generated is used for this value.
+// This method is typically only used for testing purposes to facilitate PDF
+// comparsion. Specify a zero-value time to revert to the default behavior.
+func (f *Fpdf) SetCreationDate(tm time.Time) {
+ f.creationDate = tm
+}
+
+func (f *Fpdf) putpages() {
+ var wPt, hPt float64
+ var pageSize SizeType
+ // var linkList []linkType
+ var ok bool
+ nb := f.page
+ if len(f.aliasNbPagesStr) > 0 {
+ // Replace number of pages
+ nbStr := sprintf("%d", nb)
+ for n := 1; n <= nb; n++ {
+ s := f.pages[n].String()
+ if strings.Contains(s, f.aliasNbPagesStr) {
+ s = strings.Replace(s, f.aliasNbPagesStr, nbStr, -1)
+ f.pages[n].Truncate(0)
+ f.pages[n].WriteString(s)
+ }
+ }
+ }
+ if f.defOrientation == "P" {
+ wPt = f.defPageSize.Wd * f.k
+ hPt = f.defPageSize.Ht * f.k
+ } else {
+ wPt = f.defPageSize.Ht * f.k
+ hPt = f.defPageSize.Wd * f.k
+ }
+ for n := 1; n <= nb; n++ {
+ // Page
+ f.newobj()
+ f.out("<</Type /Page")
+ f.out("/Parent 1 0 R")
+ pageSize, ok = f.pageSizes[n]
+ if ok {
+ f.outf("/MediaBox [0 0 %.2f %.2f]", pageSize.Wd, pageSize.Ht)
+ }
+ f.out("/Resources 2 0 R")
+ // Links
+ if len(f.pageLinks[n]) > 0 {
+ var annots fmtBuffer
+ annots.printf("/Annots [")
+ for _, pl := range f.pageLinks[n] {
+ annots.printf("<</Type /Annot /Subtype /Link /Rect [%.2f %.2f %.2f %.2f] /Border [0 0 0] ",
+ pl.x, pl.y, pl.x+pl.wd, pl.y-pl.ht)
+ if pl.link == 0 {
+ annots.printf("/A <</S /URI /URI %s>>>>", f.textstring(pl.linkStr))
+ } else {
+ l := f.links[pl.link]
+ var sz SizeType
+ var h float64
+ sz, ok = f.pageSizes[l.page]
+ if ok {
+ h = sz.Ht
+ } else {
+ h = hPt
+ }
+ // dbg("h [%.2f], l.y [%.2f] f.k [%.2f]\n", h, l.y, f.k)
+ annots.printf("/Dest [%d 0 R /XYZ 0 %.2f null]>>", 1+2*l.page, h-l.y*f.k)
+ }
+ }
+ annots.printf("]")
+ f.out(annots.String())
+ }
+ if f.pdfVersion > "1.3" {
+ f.out("/Group <</Type /Group /S /Transparency /CS /DeviceRGB>>")
+ }
+ f.outf("/Contents %d 0 R>>", f.n+1)
+ f.out("endobj")
+ // Page content
+ f.newobj()
+ if f.compress {
+ data := sliceCompress(f.pages[n].Bytes())
+ f.outf("<</Filter /FlateDecode /Length %d>>", len(data))
+ f.putstream(data)
+ } else {
+ f.outf("<</Length %d>>", f.pages[n].Len())
+ f.putstream(f.pages[n].Bytes())
+ }
+ f.out("endobj")
+ }
+ // Pages root
+ f.offsets[1] = f.buffer.Len()
+ f.out("1 0 obj")
+ f.out("<</Type /Pages")
+ var kids fmtBuffer
+ kids.printf("/Kids [")
+ for i := 0; i < nb; i++ {
+ kids.printf("%d 0 R ", 3+2*i)
+ }
+ kids.printf("]")
+ f.out(kids.String())
+ f.outf("/Count %d", nb)
+ f.outf("/MediaBox [0 0 %.2f %.2f]", wPt, hPt)
+ f.out(">>")
+ f.out("endobj")
+}
+
+func (f *Fpdf) putfonts() {
+ if f.err != nil {
+ return
+ }
+ nf := f.n
+ for _, diff := range f.diffs {
+ // Encodings
+ f.newobj()
+ f.outf("<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [%s]>>", diff)
+ f.out("endobj")
+ }
+ {
+ var fileList []string
+ var info fontFileType
+ var file string
+ for file = range f.fontFiles {
+ fileList = append(fileList, file)
+ }
+ if f.catalogSort {
+ sort.Strings(fileList)
+ }
+ for _, file = range fileList {
+ info = f.fontFiles[file]
+ // Font file embedding
+ f.newobj()
+ info.n = f.n
+ f.fontFiles[file] = info
+
+ var font []byte
+
+ if info.embedded {
+ font = info.content
+ } else {
+ var err error
+ font, err = f.loadFontFile(file)
+ if err != nil {
+ f.err = err
+ return
+ }
+ }
+
+ // dbg("font file [%s], ext [%s]", file, file[len(file)-2:])
+ compressed := file[len(file)-2:] == ".z"
+ if !compressed && info.length2 > 0 {
+ buf := font[6:info.length1]
+ buf = append(buf, font[6+info.length1+6:info.length2]...)
+ font = buf
+ }
+ f.outf("<</Length %d", len(font))
+ if compressed {
+ f.out("/Filter /FlateDecode")
+ }
+ f.outf("/Length1 %d", info.length1)
+ if info.length2 > 0 {
+ f.outf("/Length2 %d /Length3 0", info.length2)
+ }
+ f.out(">>")
+ f.putstream(font)
+ f.out("endobj")
+ }
+ }
+ {
+ var keyList []string
+ var font fontDefType
+ var key string
+ for key = range f.fonts {
+ keyList = append(keyList, key)
+ }
+ if f.catalogSort {
+ sort.Strings(keyList)
+ }
+ for _, key = range keyList {
+ font = f.fonts[key]
+ // Font objects
+ font.N = f.n + 1
+ f.fonts[key] = font
+ tp := font.Tp
+ name := font.Name
+ if tp == "Core" {
+ // Core font
+ f.newobj()
+ f.out("<</Type /Font")
+ f.outf("/BaseFont /%s", name)
+ f.out("/Subtype /Type1")
+ if name != "Symbol" && name != "ZapfDingbats" {
+ f.out("/Encoding /WinAnsiEncoding")
+ }
+ f.out(">>")
+ f.out("endobj")
+ } else if tp == "Type1" || tp == "TrueType" {
+ // Additional Type1 or TrueType/OpenType font
+ f.newobj()
+ f.out("<</Type /Font")
+ f.outf("/BaseFont /%s", name)
+ f.outf("/Subtype /%s", tp)
+ f.out("/FirstChar 32 /LastChar 255")
+ f.outf("/Widths %d 0 R", f.n+1)
+ f.outf("/FontDescriptor %d 0 R", f.n+2)
+ if font.DiffN > 0 {
+ f.outf("/Encoding %d 0 R", nf+font.DiffN)
+ } else {
+ f.out("/Encoding /WinAnsiEncoding")
+ }
+ f.out(">>")
+ f.out("endobj")
+ // Widths
+ f.newobj()
+ var s fmtBuffer
+ s.WriteString("[")
+ for j := 32; j < 256; j++ {
+ s.printf("%d ", font.Cw[j])
+ }
+ s.WriteString("]")
+ f.out(s.String())
+ f.out("endobj")
+ // Descriptor
+ f.newobj()
+ s.Truncate(0)
+ s.printf("<</Type /FontDescriptor /FontName /%s ", name)
+ s.printf("/Ascent %d ", font.Desc.Ascent)
+ s.printf("/Descent %d ", font.Desc.Descent)
+ s.printf("/CapHeight %d ", font.Desc.CapHeight)
+ s.printf("/Flags %d ", font.Desc.Flags)
+ s.printf("/FontBBox [%d %d %d %d] ", font.Desc.FontBBox.Xmin, font.Desc.FontBBox.Ymin,
+ font.Desc.FontBBox.Xmax, font.Desc.FontBBox.Ymax)
+ s.printf("/ItalicAngle %d ", font.Desc.ItalicAngle)
+ s.printf("/StemV %d ", font.Desc.StemV)
+ s.printf("/MissingWidth %d ", font.Desc.MissingWidth)
+ var suffix string
+ if tp != "Type1" {
+ suffix = "2"
+ }
+ s.printf("/FontFile%s %d 0 R>>", suffix, f.fontFiles[font.File].n)
+ f.out(s.String())
+ f.out("endobj")
+ } else {
+ f.err = fmt.Errorf("unsupported font type: %s", tp)
+ return
+ // Allow for additional types
+ // $mtd = 'put'.strtolower($type);
+ // if(!method_exists($this,$mtd))
+ // $this->Error('Unsupported font type: '.$type);
+ // $this->$mtd($font);
+ }
+ }
+ }
+ return
+}
+
+func (f *Fpdf) loadFontFile(name string) ([]byte, error) {
+ if f.fontLoader != nil {
+ reader, err := f.fontLoader.Open(name)
+ if err == nil {
+ data, err := ioutil.ReadAll(reader)
+ if closer, ok := reader.(io.Closer); ok {
+ closer.Close()
+ }
+ return data, err
+ }
+ }
+ return ioutil.ReadFile(path.Join(f.fontpath, name))
+}
+
+func (f *Fpdf) putimages() {
+ var keyList []string
+ var key string
+ for key = range f.images {
+ keyList = append(keyList, key)
+ }
+ if f.catalogSort {
+ sort.Strings(keyList)
+ }
+ for _, key = range keyList {
+ f.putimage(f.images[key])
+ }
+}
+
+func (f *Fpdf) putimage(info *ImageInfoType) {
+ f.newobj()
+ info.n = f.n
+ f.out("<</Type /XObject")
+ f.out("/Subtype /Image")
+ f.outf("/Width %d", int(info.w))
+ f.outf("/Height %d", int(info.h))
+ if info.cs == "Indexed" {
+ f.outf("/ColorSpace [/Indexed /DeviceRGB %d %d 0 R]", len(info.pal)/3-1, f.n+1)
+ } else {
+ f.outf("/ColorSpace /%s", info.cs)
+ if info.cs == "DeviceCMYK" {
+ f.out("/Decode [1 0 1 0 1 0 1 0]")
+ }
+ }
+ f.outf("/BitsPerComponent %d", info.bpc)
+ if len(info.f) > 0 {
+ f.outf("/Filter /%s", info.f)
+ }
+ if len(info.dp) > 0 {
+ f.outf("/DecodeParms <<%s>>", info.dp)
+ }
+ if len(info.trns) > 0 {
+ var trns fmtBuffer
+ for _, v := range info.trns {
+ trns.printf("%d %d ", v, v)
+ }
+ f.outf("/Mask [%s]", trns.String())
+ }
+ if info.smask != nil {
+ f.outf("/SMask %d 0 R", f.n+1)
+ }
+ f.outf("/Length %d>>", len(info.data))
+ f.putstream(info.data)
+ f.out("endobj")
+ // Soft mask
+ if len(info.smask) > 0 {
+ smask := &ImageInfoType{
+ w: info.w,
+ h: info.h,
+ cs: "DeviceGray",
+ bpc: 8,
+ f: info.f,
+ dp: sprintf("/Predictor 15 /Colors 1 /BitsPerComponent 8 /Columns %d", int(info.w)),
+ data: info.smask,
+ scale: f.k,
+ }
+ f.putimage(smask)
+ }
+ // Palette
+ if info.cs == "Indexed" {
+ f.newobj()
+ if f.compress {
+ pal := sliceCompress(info.pal)
+ f.outf("<</Filter /FlateDecode /Length %d>>", len(pal))
+ f.putstream(pal)
+ } else {
+ f.outf("<</Length %d>>", len(info.pal))
+ f.putstream(info.pal)
+ }
+ f.out("endobj")
+ }
+}
+
+func (f *Fpdf) putxobjectdict() {
+ {
+ var image *ImageInfoType
+ var key string
+ var keyList []string
+ for key = range f.images {
+ keyList = append(keyList, key)
+ }
+ if f.catalogSort {
+ sort.Strings(keyList)
+ }
+ for _, key = range keyList {
+ image = f.images[key]
+ f.outf("/I%d %d 0 R", image.i, image.n)
+ }
+ }
+ {
+ var keyList []int64
+ var key int64
+ var tpl Template
+ keyList = templateKeyList(f.templates, f.catalogSort)
+ for _, key = range keyList {
+ tpl = f.templates[key]
+ // for _, tpl := range f.templates {
+ id := tpl.ID()
+ if objID, ok := f.templateObjects[id]; ok {
+ f.outf("/TPL%d %d 0 R", id, objID)
+ }
+ }
+ }
+}
+
+func (f *Fpdf) putresourcedict() {
+ f.out("/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]")
+ f.out("/Font <<")
+ {
+ var keyList []string
+ var font fontDefType
+ var key string
+ for key = range f.fonts {
+ keyList = append(keyList, key)
+ }
+ if f.catalogSort {
+ sort.Strings(keyList)
+ }
+ for _, key = range keyList {
+ font = f.fonts[key]
+ f.outf("/F%d %d 0 R", font.I, font.N)
+ }
+ }
+ f.out(">>")
+ f.out("/XObject <<")
+ f.putxobjectdict()
+ f.out(">>")
+ count := len(f.blendList)
+ if count > 1 {
+ f.out("/ExtGState <<")
+ for j := 1; j < count; j++ {
+ f.outf("/GS%d %d 0 R", j, f.blendList[j].objNum)
+ }
+ f.out(">>")
+ }
+ count = len(f.gradientList)
+ if count > 1 {
+ f.out("/Shading <<")
+ for j := 1; j < count; j++ {
+ f.outf("/Sh%d %d 0 R", j, f.gradientList[j].objNum)
+ }
+ f.out(">>")
+ }
+ // Layers
+ f.layerPutResourceDict()
+}
+
+func (f *Fpdf) putBlendModes() {
+ count := len(f.blendList)
+ for j := 1; j < count; j++ {
+ bl := f.blendList[j]
+ f.newobj()
+ f.blendList[j].objNum = f.n
+ f.outf("<</Type /ExtGState /ca %s /CA %s /BM /%s>>",
+ bl.fillStr, bl.strokeStr, bl.modeStr)
+ f.out("endobj")
+ }
+}
+
+func (f *Fpdf) putGradients() {
+ count := len(f.gradientList)
+ for j := 1; j < count; j++ {
+ var f1 int
+ gr := f.gradientList[j]
+ if gr.tp == 2 || gr.tp == 3 {
+ f.newobj()
+ f.outf("<</FunctionType 2 /Domain [0.0 1.0] /C0 [%s] /C1 [%s] /N 1>>", gr.clr1Str, gr.clr2Str)
+ f.out("endobj")
+ f1 = f.n
+ }
+ f.newobj()
+ f.outf("<</ShadingType %d /ColorSpace /DeviceRGB", gr.tp)
+ if gr.tp == 2 {
+ f.outf("/Coords [%.5f %.5f %.5f %.5f] /Function %d 0 R /Extend [true true]>>",
+ gr.x1, gr.y1, gr.x2, gr.y2, f1)
+ } else if gr.tp == 3 {
+ f.outf("/Coords [%.5f %.5f 0 %.5f %.5f %.5f] /Function %d 0 R /Extend [true true]>>",
+ gr.x1, gr.y1, gr.x2, gr.y2, gr.r, f1)
+ }
+ f.out("endobj")
+ f.gradientList[j].objNum = f.n
+ }
+}
+
+func (f *Fpdf) putresources() {
+ if f.err != nil {
+ return
+ }
+ f.layerPutLayers()
+ f.putBlendModes()
+ f.putGradients()
+ f.putfonts()
+ if f.err != nil {
+ return
+ }
+ f.putimages()
+ f.putTemplates()
+ // Resource dictionary
+ f.offsets[2] = f.buffer.Len()
+ f.out("2 0 obj")
+ f.out("<<")
+ f.putresourcedict()
+ f.out(">>")
+ f.out("endobj")
+ if f.protect.encrypted {
+ f.newobj()
+ f.protect.objNum = f.n
+ f.out("<<")
+ f.out("/Filter /Standard")
+ f.out("/V 1")
+ f.out("/R 2")
+ f.outf("/O (%s)", f.escape(string(f.protect.oValue)))
+ f.outf("/U (%s)", f.escape(string(f.protect.uValue)))
+ f.outf("/P %d", f.protect.pValue)
+ f.out(">>")
+ f.out("endobj")
+ }
+ return
+}
+
+func (f *Fpdf) putinfo() {
+ var tm time.Time
+ f.outf("/Producer %s", f.textstring("FPDF "+cnFpdfVersion))
+ if len(f.title) > 0 {
+ f.outf("/Title %s", f.textstring(f.title))
+ }
+ if len(f.subject) > 0 {
+ f.outf("/Subject %s", f.textstring(f.subject))
+ }
+ if len(f.author) > 0 {
+ f.outf("/Author %s", f.textstring(f.author))
+ }
+ if len(f.keywords) > 0 {
+ f.outf("/Keywords %s", f.textstring(f.keywords))
+ }
+ if len(f.creator) > 0 {
+ f.outf("/Creator %s", f.textstring(f.creator))
+ }
+ if f.creationDate.IsZero() {
+ tm = time.Now()
+ } else {
+ tm = f.creationDate
+ }
+ f.outf("/CreationDate %s", f.textstring("D:"+tm.Format("20060102150405")))
+}
+
+func (f *Fpdf) putcatalog() {
+ f.out("/Type /Catalog")
+ f.out("/Pages 1 0 R")
+ switch f.zoomMode {
+ case "fullpage":
+ f.out("/OpenAction [3 0 R /Fit]")
+ case "fullwidth":
+ f.out("/OpenAction [3 0 R /FitH null]")
+ case "real":
+ f.out("/OpenAction [3 0 R /XYZ null null 1]")
+ }
+ // } else if !is_string($this->zoomMode))
+ // $this->out('/OpenAction [3 0 R /XYZ null null '.sprintf('%.2f',$this->zoomMode/100).']');
+ switch f.layoutMode {
+ case "single", "SinglePage":
+ f.out("/PageLayout /SinglePage")
+ case "continuous", "OneColumn":
+ f.out("/PageLayout /OneColumn")
+ case "two", "TwoColumnLeft":
+ f.out("/PageLayout /TwoColumnLeft")
+ case "TwoColumnRight":
+ f.out("/PageLayout /TwoColumnRight")
+ case "TwoPageLeft", "TwoPageRight":
+ if f.pdfVersion < "1.5" {
+ f.pdfVersion = "1.5"
+ }
+ f.out("/PageLayout /" + f.layoutMode)
+ }
+ // Bookmarks
+ if len(f.outlines) > 0 {
+ f.outf("/Outlines %d 0 R", f.outlineRoot)
+ f.out("/PageMode /UseOutlines")
+ }
+ // Layers
+ f.layerPutCatalog()
+}
+
+func (f *Fpdf) putheader() {
+ if len(f.blendMap) > 0 && f.pdfVersion < "1.4" {
+ f.pdfVersion = "1.4"
+ }
+ f.outf("%%PDF-%s", f.pdfVersion)
+}
+
+func (f *Fpdf) puttrailer() {
+ f.outf("/Size %d", f.n+1)
+ f.outf("/Root %d 0 R", f.n)
+ f.outf("/Info %d 0 R", f.n-1)
+ if f.protect.encrypted {
+ f.outf("/Encrypt %d 0 R", f.protect.objNum)
+ f.out("/ID [()()]")
+ }
+}
+
+func (f *Fpdf) putbookmarks() {
+ nb := len(f.outlines)
+ if nb > 0 {
+ lru := make(map[int]int)
+ level := 0
+ for i, o := range f.outlines {
+ if o.level > 0 {
+ parent := lru[o.level-1]
+ f.outlines[i].parent = parent
+ f.outlines[parent].last = i
+ if o.level > level {
+ f.outlines[parent].first = i
+ }
+ } else {
+ f.outlines[i].parent = nb
+ }
+ if o.level <= level && i > 0 {
+ prev := lru[o.level]
+ f.outlines[prev].next = i
+ f.outlines[i].prev = prev
+ }
+ lru[o.level] = i
+ level = o.level
+ }
+ n := f.n + 1
+ for _, o := range f.outlines {
+ f.newobj()
+ f.outf("<</Title %s", f.textstring(o.text))
+ f.outf("/Parent %d 0 R", n+o.parent)
+ if o.prev != -1 {
+ f.outf("/Prev %d 0 R", n+o.prev)
+ }
+ if o.next != -1 {
+ f.outf("/Next %d 0 R", n+o.next)
+ }
+ if o.first != -1 {
+ f.outf("/First %d 0 R", n+o.first)
+ }
+ if o.last != -1 {
+ f.outf("/Last %d 0 R", n+o.last)
+ }
+ f.outf("/Dest [%d 0 R /XYZ 0 %.2f null]", 1+2*o.p, (f.h-o.y)*f.k)
+ f.out("/Count 0>>")
+ f.out("endobj")
+ }
+ f.newobj()
+ f.outlineRoot = f.n
+ f.outf("<</Type /Outlines /First %d 0 R", n)
+ f.outf("/Last %d 0 R>>", n+lru[0])
+ f.out("endobj")
+ }
+}
+
+func (f *Fpdf) enddoc() {
+ if f.err != nil {
+ return
+ }
+ f.layerEndDoc()
+ f.putheader()
+ f.putpages()
+ f.putresources()
+ if f.err != nil {
+ return
+ }
+ // Bookmarks
+ f.putbookmarks()
+ // Info
+ f.newobj()
+ f.out("<<")
+ f.putinfo()
+ f.out(">>")
+ f.out("endobj")
+ // Catalog
+ f.newobj()
+ f.out("<<")
+ f.putcatalog()
+ f.out(">>")
+ f.out("endobj")
+ // Cross-ref
+ o := f.buffer.Len()
+ f.out("xref")
+ f.outf("0 %d", f.n+1)
+ f.out("0000000000 65535 f ")
+ for j := 1; j <= f.n; j++ {
+ f.outf("%010d 00000 n ", f.offsets[j])
+ }
+ // Trailer
+ f.out("trailer")
+ f.out("<<")
+ f.puttrailer()
+ f.out(">>")
+ f.out("startxref")
+ f.outf("%d", o)
+ f.out("%%EOF")
+ f.state = 3
+ return
+}
+
+// Path Drawing
+
+// MoveTo moves the stylus to (x, y) without drawing the path from the
+// previous point. Paths must start with a MoveTo to set the original
+// stylus location or the result is undefined.
+//
+// Create a "path" by moving a virtual stylus around the page (with
+// MoveTo, LineTo, CurveTo, CurveBezierCubicTo, ArcTo & ClosePath)
+// then draw it or fill it in (with DrawPath). The main advantage of
+// using the path drawing routines rather than multiple Fpdf.Line is
+// that PDF creates nice line joins at the angles, rather than just
+// overlaying the lines.
+func (f *Fpdf) MoveTo(x, y float64) {
+ f.point(x, y)
+ f.x, f.y = x, y
+}
+
+// LineTo creates a line from the current stylus location to (x, y), which
+// becomes the new stylus location. Note that this only creates the line in
+// the path; it does not actually draw the line on the page.
+//
+// The MoveTo() example demonstrates this method.
+func (f *Fpdf) LineTo(x, y float64) {
+ f.outf("%.2f %.2f l", x*f.k, (f.h-y)*f.k)
+ f.x, f.y = x, y
+}
+
+// CurveTo creates a single-segment quadratic Bézier curve. The curve starts at
+// the current stylus location and ends at the point (x, y). The control point
+// (cx, cy) specifies the curvature. At the start point, the curve is tangent
+// to the straight line between the current stylus location and the control
+// point. At the end point, the curve is tangent to the straight line between
+// the end point and the control point.
+//
+// The MoveTo() example demonstrates this method.
+func (f *Fpdf) CurveTo(cx, cy, x, y float64) {
+ f.outf("%.5f %.5f %.5f %.5f v", cx*f.k, (f.h-cy)*f.k, x*f.k, (f.h-y)*f.k)
+ f.x, f.y = x, y
+}
+
+// CurveBezierCubicTo creates a single-segment cubic Bézier curve. The curve
+// starts at the current stylus location and ends at the point (x, y). The
+// control points (cx0, cy0) and (cx1, cy1) specify the curvature. At the
+// current stylus, the curve is tangent to the straight line between the
+// current stylus location and the control point (cx0, cy0). At the end point,
+// the curve is tangent to the straight line between the end point and the
+// control point (cx1, cy1).
+//
+// The MoveTo() example demonstrates this method.
+func (f *Fpdf) CurveBezierCubicTo(cx0, cy0, cx1, cy1, x, y float64) {
+ f.curve(cx0, cy0, cx1, cy1, x, y)
+ f.x, f.y = x, y
+}
+
+// ClosePath creates a line from the current location to the last MoveTo point
+// (if not the same) and mark the path as closed so the first and last lines
+// join nicely.
+//
+// The MoveTo() example demonstrates this method.
+func (f *Fpdf) ClosePath() {
+ f.outf("h")
+}
+
+// DrawPath actually draws the path on the page.
+//
+// styleStr can be "F" for filled, "D" for outlined only, or "DF" or "FD" for
+// outlined and filled. An empty string will be replaced with "D".
+// Path-painting operators as defined in the PDF specification are also
+// allowed: "S" (Stroke the path), "s" (Close and stroke the path),
+// "f" (fill the path, using the nonzero winding number), "f*"
+// (Fill the path, using the even-odd rule), "B" (Fill and then stroke
+// the path, using the nonzero winding number rule), "B*" (Fill and
+// then stroke the path, using the even-odd rule), "b" (Close, fill,
+// and then stroke the path, using the nonzero winding number rule) and
+// "b*" (Close, fill, and then stroke the path, using the even-odd
+// rule).
+// Drawing uses the current draw color, line width, and cap style
+// centered on the
+// path. Filling uses the current fill color.
+//
+// The MoveTo() example demonstrates this method.
+func (f *Fpdf) DrawPath(styleStr string) {
+ f.outf(fillDrawOp(styleStr))
+}
+
+// ArcTo draws an elliptical arc centered at point (x, y). rx and ry specify its
+// horizontal and vertical radii. If the start of the arc is not at
+// the current position, a connecting line will be drawn.
+//
+// degRotate specifies the angle that the arc will be rotated. degStart and
+// degEnd specify the starting and ending angle of the arc. All angles are
+// specified in degrees and measured counter-clockwise from the 3 o'clock
+// position.
+//
+// styleStr can be "F" for filled, "D" for outlined only, or "DF" or "FD" for
+// outlined and filled. An empty string will be replaced with "D". Drawing uses
+// the current draw color, line width, and cap style centered on the arc's
+// path. Filling uses the current fill color.
+//
+// The MoveTo() example demonstrates this method.
+func (f *Fpdf) ArcTo(x, y, rx, ry, degRotate, degStart, degEnd float64) {
+ f.arc(x, y, rx, ry, degRotate, degStart, degEnd, "", true)
+}
+
+func (f *Fpdf) arc(x, y, rx, ry, degRotate, degStart, degEnd float64,
+ styleStr string, path bool) {
+ x *= f.k
+ y = (f.h - y) * f.k
+ rx *= f.k
+ ry *= f.k
+ segments := int(degEnd-degStart) / 60
+ if segments < 2 {
+ segments = 2
+ }
+ angleStart := degStart * math.Pi / 180
+ angleEnd := degEnd * math.Pi / 180
+ angleTotal := angleEnd - angleStart
+ dt := angleTotal / float64(segments)
+ dtm := dt / 3
+ if degRotate != 0 {
+ a := -degRotate * math.Pi / 180
+ f.outf("q %.5f %.5f %.5f %.5f %.5f %.5f cm",
+ math.Cos(a), -1*math.Sin(a),
+ math.Sin(a), math.Cos(a), x, y)
+ x = 0
+ y = 0
+ }
+ t := angleStart
+ a0 := x + rx*math.Cos(t)
+ b0 := y + ry*math.Sin(t)
+ c0 := -rx * math.Sin(t)
+ d0 := ry * math.Cos(t)
+ sx := a0 / f.k // start point of arc
+ sy := f.h - (b0 / f.k)
+ if path {
+ if f.x != sx || f.y != sy {
+ // Draw connecting line to start point
+ f.LineTo(sx, sy)
+ }
+ } else {
+ f.point(sx, sy)
+ }
+ for j := 1; j <= segments; j++ {
+ // Draw this bit of the total curve
+ t = (float64(j) * dt) + angleStart
+ a1 := x + rx*math.Cos(t)
+ b1 := y + ry*math.Sin(t)
+ c1 := -rx * math.Sin(t)
+ d1 := ry * math.Cos(t)
+ f.curve((a0+(c0*dtm))/f.k,
+ f.h-((b0+(d0*dtm))/f.k),
+ (a1-(c1*dtm))/f.k,
+ f.h-((b1-(d1*dtm))/f.k),
+ a1/f.k,
+ f.h-(b1/f.k))
+ a0 = a1
+ b0 = b1
+ c0 = c1
+ d0 = d1
+ if path {
+ f.x = a1 / f.k
+ f.y = f.h - (b1 / f.k)
+ }
+ }
+ if !path {
+ f.out(fillDrawOp(styleStr))
+ }
+ if degRotate != 0 {
+ f.out("Q")
+ }
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/fpdftrans.go b/vendor/github.com/jung-kurt/gofpdf/fpdftrans.go
new file mode 100644
index 0000000..9cda397
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/fpdftrans.go
@@ -0,0 +1,213 @@
+package gofpdf
+
+import (
+ "fmt"
+ "math"
+)
+
+// Routines in this file are translated from the work of Moritz Wagner and
+// Andreas Würmser.
+
+// TransformMatrix is used for generalized transformations of text, drawings
+// and images.
+type TransformMatrix struct {
+ A, B, C, D, E, F float64
+}
+
+// TransformBegin sets up a transformation context for subsequent text,
+// drawings and images. The typical usage is to immediately follow a call to
+// this method with a call to one or more of the transformation methods such as
+// TransformScale(), TransformSkew(), etc. This is followed by text, drawing or
+// image output and finally a call to TransformEnd(). All transformation
+// contexts must be properly ended prior to outputting the document.
+func (f *Fpdf) TransformBegin() {
+ f.transformNest++
+ f.out("q")
+}
+
+// TransformScaleX scales the width of the following text, drawings and images.
+// scaleWd is the percentage scaling factor. (x, y) is center of scaling.
+//
+// The TransformBegin() example demonstrates this method.
+func (f *Fpdf) TransformScaleX(scaleWd, x, y float64) {
+ f.TransformScale(scaleWd, 100, x, y)
+}
+
+// TransformScaleY scales the height of the following text, drawings and
+// images. scaleHt is the percentage scaling factor. (x, y) is center of
+// scaling.
+//
+// The TransformBegin() example demonstrates this method.
+func (f *Fpdf) TransformScaleY(scaleHt, x, y float64) {
+ f.TransformScale(100, scaleHt, x, y)
+}
+
+// TransformScaleXY uniformly scales the width and height of the following
+// text, drawings and images. s is the percentage scaling factor for both width
+// and height. (x, y) is center of scaling.
+//
+// The TransformBegin() example demonstrates this method.
+func (f *Fpdf) TransformScaleXY(s, x, y float64) {
+ f.TransformScale(s, s, x, y)
+}
+
+// TransformScale generally scales the following text, drawings and images.
+// scaleWd and scaleHt are the percentage scaling factors for width and height.
+// (x, y) is center of scaling.
+//
+// The TransformBegin() example demonstrates this method.
+func (f *Fpdf) TransformScale(scaleWd, scaleHt, x, y float64) {
+ if scaleWd == 0 || scaleHt == 0 {
+ f.err = fmt.Errorf("scale factor cannot be zero")
+ return
+ }
+ y = (f.h - y) * f.k
+ x *= f.k
+ scaleWd /= 100
+ scaleHt /= 100
+ f.Transform(TransformMatrix{scaleWd, 0, 0,
+ scaleHt, x * (1 - scaleWd), y * (1 - scaleHt)})
+}
+
+// TransformMirrorHorizontal horizontally mirrors the following text, drawings
+// and images. x is the axis of reflection.
+//
+// The TransformBegin() example demonstrates this method.
+func (f *Fpdf) TransformMirrorHorizontal(x float64) {
+ f.TransformScale(-100, 100, x, f.y)
+}
+
+// TransformMirrorVertical vertically mirrors the following text, drawings and
+// images. y is the axis of reflection.
+//
+// The TransformBegin() example demonstrates this method.
+func (f *Fpdf) TransformMirrorVertical(y float64) {
+ f.TransformScale(100, -100, f.x, y)
+}
+
+// TransformMirrorPoint symmetrically mirrors the following text, drawings and
+// images on the point specified by (x, y).
+//
+// The TransformBegin() example demonstrates this method.
+func (f *Fpdf) TransformMirrorPoint(x, y float64) {
+ f.TransformScale(-100, -100, x, y)
+}
+
+// TransformMirrorLine symmetrically mirrors the following text, drawings and
+// images on the line defined by angle and the point (x, y). angles is
+// specified in degrees and measured counter-clockwise from the 3 o'clock
+// position.
+//
+// The TransformBegin() example demonstrates this method.
+func (f *Fpdf) TransformMirrorLine(angle, x, y float64) {
+ f.TransformScale(-100, 100, x, y)
+ f.TransformRotate(-2*(angle-90), x, y)
+}
+
+// TransformTranslateX moves the following text, drawings and images
+// horizontally by the amount specified by tx.
+//
+// The TransformBegin() example demonstrates this method.
+func (f *Fpdf) TransformTranslateX(tx float64) {
+ f.TransformTranslate(tx, 0)
+}
+
+// TransformTranslateY moves the following text, drawings and images vertically
+// by the amount specified by ty.
+//
+// The TransformBegin() example demonstrates this method.
+func (f *Fpdf) TransformTranslateY(ty float64) {
+ f.TransformTranslate(0, ty)
+}
+
+// TransformTranslate moves the following text, drawings and images
+// horizontally and vertically by the amounts specified by tx and ty.
+//
+// The TransformBegin() example demonstrates this method.
+func (f *Fpdf) TransformTranslate(tx, ty float64) {
+ f.Transform(TransformMatrix{1, 0, 0, 1, tx * f.k, -ty * f.k})
+}
+
+// TransformRotate rotates the following text, drawings and images around the
+// center point (x, y). angle is specified in degrees and measured
+// counter-clockwise from the 3 o'clock position.
+//
+// The TransformBegin() example demonstrates this method.
+func (f *Fpdf) TransformRotate(angle, x, y float64) {
+ y = (f.h - y) * f.k
+ x *= f.k
+ angle = angle * math.Pi / 180
+ var tm TransformMatrix
+ tm.A = math.Cos(angle)
+ tm.B = math.Sin(angle)
+ tm.C = -tm.B
+ tm.D = tm.A
+ tm.E = x + tm.B*y - tm.A*x
+ tm.F = y - tm.A*y - tm.B*x
+ f.Transform(tm)
+}
+
+// TransformSkewX horizontally skews the following text, drawings and images
+// keeping the point (x, y) stationary. angleX ranges from -90 degrees (skew to
+// the left) to 90 degrees (skew to the right).
+//
+// The TransformBegin() example demonstrates this method.
+func (f *Fpdf) TransformSkewX(angleX, x, y float64) {
+ f.TransformSkew(angleX, 0, x, y)
+}
+
+// TransformSkewY vertically skews the following text, drawings and images
+// keeping the point (x, y) stationary. angleY ranges from -90 degrees (skew to
+// the bottom) to 90 degrees (skew to the top).
+//
+// The TransformBegin() example demonstrates this method.
+func (f *Fpdf) TransformSkewY(angleY, x, y float64) {
+ f.TransformSkew(0, angleY, x, y)
+}
+
+// TransformSkew generally skews the following text, drawings and images
+// keeping the point (x, y) stationary. angleX ranges from -90 degrees (skew to
+// the left) to 90 degrees (skew to the right). angleY ranges from -90 degrees
+// (skew to the bottom) to 90 degrees (skew to the top).
+//
+// The TransformBegin() example demonstrates this method.
+func (f *Fpdf) TransformSkew(angleX, angleY, x, y float64) {
+ if angleX <= -90 || angleX >= 90 || angleY <= -90 || angleY >= 90 {
+ f.err = fmt.Errorf("skew values must be between -90° and 90°")
+ return
+ }
+ x *= f.k
+ y = (f.h - y) * f.k
+ var tm TransformMatrix
+ tm.A = 1
+ tm.B = math.Tan(angleY * math.Pi / 180)
+ tm.C = math.Tan(angleX * math.Pi / 180)
+ tm.D = 1
+ tm.E = -tm.C * y
+ tm.F = -tm.B * x
+ f.Transform(tm)
+}
+
+// Transform generally transforms the following text, drawings and images
+// according to the specified matrix. It is typically easier to use the various
+// methods such as TransformRotate() and TransformMirrorVertical() instead.
+func (f *Fpdf) Transform(tm TransformMatrix) {
+ if f.transformNest > 0 {
+ f.outf("%.5f %.5f %.5f %.5f %.5f %.5f cm",
+ tm.A, tm.B, tm.C, tm.D, tm.E, tm.F)
+ } else if f.err == nil {
+ f.err = fmt.Errorf("transformation context is not active")
+ }
+}
+
+// TransformEnd applies a transformation that was begun with a call to TransformBegin().
+//
+// The TransformBegin() example demonstrates this method.
+func (f *Fpdf) TransformEnd() {
+ if f.transformNest > 0 {
+ f.transformNest--
+ f.out("Q")
+ } else {
+ f.err = fmt.Errorf("error attempting to end transformation operation out of sequence")
+ }
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/htmlbasic.go b/vendor/github.com/jung-kurt/gofpdf/htmlbasic.go
new file mode 100644
index 0000000..ee3be7d
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/htmlbasic.go
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2014 Kurt Jung (Gmail: kurt.w.jung)
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package gofpdf
+
+import (
+ "regexp"
+ "strings"
+)
+
+// HTMLBasicSegmentType defines a segment of literal text in which the current
+// attributes do not vary, or an open tag or a close tag.
+type HTMLBasicSegmentType struct {
+ Cat byte // 'O' open tag, 'C' close tag, 'T' text
+ Str string // Literal text unchanged, tags are lower case
+ Attr map[string]string // Attribute keys are lower case
+}
+
+// HTMLBasicTokenize returns a list of HTML tags and literal elements. This is
+// done with regular expressions, so the result is only marginally better than
+// useless.
+func HTMLBasicTokenize(htmlStr string) (list []HTMLBasicSegmentType) {
+ // This routine is adapted from http://www.fpdf.org/
+ list = make([]HTMLBasicSegmentType, 0, 16)
+ htmlStr = strings.Replace(htmlStr, "\n", " ", -1)
+ htmlStr = strings.Replace(htmlStr, "\r", "", -1)
+ tagRe, _ := regexp.Compile(`(?U)<.*>`)
+ attrRe, _ := regexp.Compile(`([^=]+)=["']?([^"']+)`)
+ capList := tagRe.FindAllStringIndex(htmlStr, -1)
+ if capList != nil {
+ var seg HTMLBasicSegmentType
+ var parts []string
+ pos := 0
+ for _, cap := range capList {
+ if pos < cap[0] {
+ seg.Cat = 'T'
+ seg.Str = htmlStr[pos:cap[0]]
+ seg.Attr = nil
+ list = append(list, seg)
+ }
+ if htmlStr[cap[0]+1] == '/' {
+ seg.Cat = 'C'
+ seg.Str = strings.ToLower(htmlStr[cap[0]+2 : cap[1]-1])
+ seg.Attr = nil
+ list = append(list, seg)
+ } else {
+ // Extract attributes
+ parts = strings.Split(htmlStr[cap[0]+1:cap[1]-1], " ")
+ if len(parts) > 0 {
+ for j, part := range parts {
+ if j == 0 {
+ seg.Cat = 'O'
+ seg.Str = strings.ToLower(parts[0])
+ seg.Attr = make(map[string]string)
+ } else {
+ attrList := attrRe.FindAllStringSubmatch(part, -1)
+ if attrList != nil {
+ for _, attr := range attrList {
+ seg.Attr[strings.ToLower(attr[1])] = attr[2]
+ }
+ }
+ }
+ }
+ list = append(list, seg)
+ }
+ }
+ pos = cap[1]
+ }
+ if len(htmlStr) > pos {
+ seg.Cat = 'T'
+ seg.Str = htmlStr[pos:]
+ seg.Attr = nil
+ list = append(list, seg)
+ }
+ } else {
+ list = append(list, HTMLBasicSegmentType{Cat: 'T', Str: htmlStr, Attr: nil})
+ }
+ return
+}
+
+// HTMLBasicType is used for rendering a very basic subset of HTML. It supports
+// only hyperlinks and bold, italic and underscore attributes. In the Link
+// structure, the ClrR, ClrG and ClrB fields (0 through 255) define the color
+// of hyperlinks. The Bold, Italic and Underscore values define the hyperlink
+// style.
+type HTMLBasicType struct {
+ pdf *Fpdf
+ Link struct {
+ ClrR, ClrG, ClrB int
+ Bold, Italic, Underscore bool
+ }
+}
+
+// HTMLBasicNew returns an instance that facilitates writing basic HTML in the
+// specified PDF file.
+func (f *Fpdf) HTMLBasicNew() (html HTMLBasicType) {
+ html.pdf = f
+ html.Link.ClrR, html.Link.ClrG, html.Link.ClrB = 0, 0, 128
+ html.Link.Bold, html.Link.Italic, html.Link.Underscore = false, false, true
+ return
+}
+
+// Write prints text from the current position using the currently selected
+// font. See HTMLBasicNew() to create a receiver that is associated with the
+// PDF document instance. The text can be encoded with a basic subset of HTML
+// that includes hyperlinks and tags for italic (I), bold (B), underscore
+// (U) and center (CENTER) attributes. When the right margin is reached a line
+// break occurs and text continues from the left margin. Upon method exit, the
+// current position is left at the end of the text.
+//
+// lineHt indicates the line height in the unit of measure specified in New().
+func (html *HTMLBasicType) Write(lineHt float64, htmlStr string) {
+ var boldLvl, italicLvl, underscoreLvl, linkBold, linkItalic, linkUnderscore int
+ var textR, textG, textB = html.pdf.GetTextColor()
+ var hrefStr string
+ if html.Link.Bold {
+ linkBold = 1
+ }
+ if html.Link.Italic {
+ linkItalic = 1
+ }
+ if html.Link.Underscore {
+ linkUnderscore = 1
+ }
+ setStyle := func(boldAdj, italicAdj, underscoreAdj int) {
+ styleStr := ""
+ boldLvl += boldAdj
+ if boldLvl > 0 {
+ styleStr += "B"
+ }
+ italicLvl += italicAdj
+ if italicLvl > 0 {
+ styleStr += "I"
+ }
+ underscoreLvl += underscoreAdj
+ if underscoreLvl > 0 {
+ styleStr += "U"
+ }
+ html.pdf.SetFont("", styleStr, 0)
+ }
+ putLink := func(urlStr, txtStr string) {
+ // Put a hyperlink
+ html.pdf.SetTextColor(html.Link.ClrR, html.Link.ClrG, html.Link.ClrB)
+ setStyle(linkBold, linkItalic, linkUnderscore)
+ html.pdf.WriteLinkString(lineHt, txtStr, urlStr)
+ setStyle(-linkBold, -linkItalic, -linkUnderscore)
+ html.pdf.SetTextColor(textR, textG, textB)
+ }
+ list := HTMLBasicTokenize(htmlStr)
+ var ok bool
+ alignStr := "L"
+ for _, el := range list {
+ switch el.Cat {
+ case 'T':
+ if len(hrefStr) > 0 {
+ putLink(hrefStr, el.Str)
+ hrefStr = ""
+ } else {
+ if alignStr == "C" {
+ html.pdf.WriteAligned(0, lineHt, el.Str, alignStr)
+ } else {
+ html.pdf.Write(lineHt, el.Str)
+ }
+ }
+ case 'O':
+ switch el.Str {
+ case "b":
+ setStyle(1, 0, 0)
+ case "i":
+ setStyle(0, 1, 0)
+ case "u":
+ setStyle(0, 0, 1)
+ case "br":
+ html.pdf.Ln(lineHt)
+ case "center":
+ html.pdf.Ln(lineHt)
+ alignStr = "C"
+ case "a":
+ hrefStr, ok = el.Attr["href"]
+ if !ok {
+ hrefStr = ""
+ }
+ }
+ case 'C':
+ switch el.Str {
+ case "b":
+ setStyle(-1, 0, 0)
+ case "i":
+ setStyle(0, -1, 0)
+ case "u":
+ setStyle(0, 0, -1)
+ case "center":
+ html.pdf.Ln(lineHt)
+ alignStr = "L"
+ }
+ }
+ }
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/internal/example/example.go b/vendor/github.com/jung-kurt/gofpdf/internal/example/example.go
new file mode 100644
index 0000000..edf2388
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/internal/example/example.go
@@ -0,0 +1,126 @@
+// Copyright (c) 2015 Kurt Jung (Gmail: kurt.w.jung)
+//
+// Permission to use, copy, modify, and distribute this software for any purpose
+// with or without fee is hereby granted, provided that the above copyright notice
+// and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+// Package example provides some helper routines for the test packages of
+// gofpdf and its various contributed packages located beneath the contrib
+// directory.
+package example
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+ "time"
+
+ "github.com/jung-kurt/gofpdf"
+)
+
+var gofpdfDir string
+
+func init() {
+ setRoot()
+ gofpdf.SetDefaultCompression(false)
+ gofpdf.SetDefaultCatalogSort(true)
+ gofpdf.SetDefaultCreationDate(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC))
+}
+
+// Assign the relative path to the gofpdfDir directory based on current working
+// directory
+func setRoot() {
+ wdStr, err := os.Getwd()
+ if err == nil {
+ gofpdfDir = ""
+ list := strings.Split(filepath.ToSlash(wdStr), "/")
+ for j := len(list) - 1; j >= 0 && list[j] != "gofpdf"; j-- {
+ gofpdfDir = filepath.Join(gofpdfDir, "..")
+ }
+ } else {
+ panic(err)
+ }
+}
+
+// ImageFile returns a qualified filename in which the path to the image
+// directory is prepended to the specified filename.
+func ImageFile(fileStr string) string {
+ return filepath.Join(gofpdfDir, "image", fileStr)
+}
+
+// FontDir returns the path to the font directory.
+func FontDir() string {
+ return filepath.Join(gofpdfDir, "font")
+}
+
+// FontFile returns a qualified filename in which the path to the font
+// directory is prepended to the specified filename.
+func FontFile(fileStr string) string {
+ return filepath.Join(FontDir(), fileStr)
+}
+
+// TextFile returns a qualified filename in which the path to the text
+// directory is prepended to the specified filename.
+func TextFile(fileStr string) string {
+ return filepath.Join(gofpdfDir, "text", fileStr)
+}
+
+// PdfDir returns the path to the PDF output directory.
+func PdfDir() string {
+ return filepath.Join(gofpdfDir, "pdf")
+}
+
+// PdfFile returns a qualified filename in which the path to the PDF output
+// directory is prepended to the specified filename.
+func PdfFile(fileStr string) string {
+ return filepath.Join(PdfDir(), fileStr)
+}
+
+// Filename returns a qualified filename in which the example PDF directory
+// path is prepended and the suffix ".pdf" is appended to the specified
+// filename.
+func Filename(baseStr string) string {
+ return PdfFile(baseStr + ".pdf")
+}
+
+// referenceCompare compares the specified file with the file's reference copy
+// located in the 'reference' subdirectory. All bytes of the two files are
+// compared except for the value of the /CreationDate field in the PDF. This
+// function succeeds if both files are equivalent except for their
+// /CreationDate values or if the reference file does not exist.
+func referenceCompare(fileStr string) (err error) {
+ var refFileStr, refDirStr, dirStr, baseFileStr string
+ dirStr, baseFileStr = filepath.Split(fileStr)
+ refDirStr = filepath.Join(dirStr, "reference")
+ err = os.MkdirAll(refDirStr, 0755)
+ if err == nil {
+ refFileStr = filepath.Join(refDirStr, baseFileStr)
+ err = gofpdf.ComparePDFFiles(fileStr, refFileStr)
+ }
+ return
+}
+
+// Summary generates a predictable report for use by test examples. If the
+// specified error is nil, the filename delimiters are normalized and the
+// filename printed to standard output with a success message. If the specified
+// error is not nil, its String() value is printed to standard output.
+func Summary(err error, fileStr string) {
+ if err == nil {
+ err = referenceCompare(fileStr)
+ }
+ if err == nil {
+ fileStr = filepath.ToSlash(fileStr)
+ fmt.Printf("Successfully generated %s\n", fileStr)
+ } else {
+ fmt.Println(err)
+ }
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/internal/files/bin/bin.go b/vendor/github.com/jung-kurt/gofpdf/internal/files/bin/bin.go
new file mode 100644
index 0000000..5b56313
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/internal/files/bin/bin.go
@@ -0,0 +1,28 @@
+package main
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+)
+
+func main() {
+ var buf []byte
+ var pos int
+ var b byte
+ var err error
+ buf, err = ioutil.ReadAll(os.Stdin)
+ if err == nil {
+ for _, b = range buf {
+ fmt.Printf("0x%02X, ", b)
+ pos++
+ if pos >= 16 {
+ fmt.Println("")
+ pos = 0
+ }
+ }
+ }
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "%s\n", err)
+ }
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/internal/files/files.go b/vendor/github.com/jung-kurt/gofpdf/internal/files/files.go
new file mode 100644
index 0000000..7f73413
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/internal/files/files.go
@@ -0,0 +1,1691 @@
+package files
+
+// CalligraJson is embedded byte slice for calligra.json
+var CalligraJson = []byte{
+ 0x7B, 0x22, 0x54, 0x70, 0x22, 0x3A, 0x22, 0x54, 0x72, 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22,
+ 0x2C, 0x22, 0x4E, 0x61, 0x6D, 0x65, 0x22, 0x3A, 0x22, 0x43, 0x61, 0x6C, 0x6C, 0x69, 0x67, 0x72,
+ 0x61, 0x70, 0x68, 0x65, 0x72, 0x52, 0x65, 0x67, 0x75, 0x6C, 0x61, 0x72, 0x22, 0x2C, 0x22, 0x44,
+ 0x65, 0x73, 0x63, 0x22, 0x3A, 0x7B, 0x22, 0x41, 0x73, 0x63, 0x65, 0x6E, 0x74, 0x22, 0x3A, 0x38,
+ 0x39, 0x39, 0x2C, 0x22, 0x44, 0x65, 0x73, 0x63, 0x65, 0x6E, 0x74, 0x22, 0x3A, 0x2D, 0x32, 0x33,
+ 0x34, 0x2C, 0x22, 0x43, 0x61, 0x70, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3A, 0x38, 0x39,
+ 0x39, 0x2C, 0x22, 0x46, 0x6C, 0x61, 0x67, 0x73, 0x22, 0x3A, 0x33, 0x32, 0x2C, 0x22, 0x46, 0x6F,
+ 0x6E, 0x74, 0x42, 0x42, 0x6F, 0x78, 0x22, 0x3A, 0x7B, 0x22, 0x58, 0x6D, 0x69, 0x6E, 0x22, 0x3A,
+ 0x2D, 0x31, 0x37, 0x33, 0x2C, 0x22, 0x59, 0x6D, 0x69, 0x6E, 0x22, 0x3A, 0x2D, 0x32, 0x33, 0x34,
+ 0x2C, 0x22, 0x58, 0x6D, 0x61, 0x78, 0x22, 0x3A, 0x31, 0x33, 0x32, 0x38, 0x2C, 0x22, 0x59, 0x6D,
+ 0x61, 0x78, 0x22, 0x3A, 0x38, 0x39, 0x39, 0x7D, 0x2C, 0x22, 0x49, 0x74, 0x61, 0x6C, 0x69, 0x63,
+ 0x41, 0x6E, 0x67, 0x6C, 0x65, 0x22, 0x3A, 0x30, 0x2C, 0x22, 0x53, 0x74, 0x65, 0x6D, 0x56, 0x22,
+ 0x3A, 0x37, 0x30, 0x2C, 0x22, 0x4D, 0x69, 0x73, 0x73, 0x69, 0x6E, 0x67, 0x57, 0x69, 0x64, 0x74,
+ 0x68, 0x22, 0x3A, 0x38, 0x30, 0x30, 0x7D, 0x2C, 0x22, 0x55, 0x70, 0x22, 0x3A, 0x2D, 0x32, 0x30,
+ 0x30, 0x2C, 0x22, 0x55, 0x74, 0x22, 0x3A, 0x32, 0x30, 0x2C, 0x22, 0x43, 0x77, 0x22, 0x3A, 0x5B,
+ 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C,
+ 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C,
+ 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C,
+ 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C,
+ 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C,
+ 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C,
+ 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C,
+ 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C,
+ 0x32, 0x38, 0x32, 0x2C, 0x33, 0x32, 0x34, 0x2C, 0x34, 0x30, 0x35, 0x2C, 0x35, 0x38, 0x34, 0x2C,
+ 0x36, 0x33, 0x32, 0x2C, 0x39, 0x38, 0x30, 0x2C, 0x37, 0x37, 0x36, 0x2C, 0x32, 0x35, 0x39, 0x2C,
+ 0x32, 0x39, 0x39, 0x2C, 0x32, 0x39, 0x39, 0x2C, 0x33, 0x37, 0x37, 0x2C, 0x36, 0x30, 0x30, 0x2C,
+ 0x32, 0x35, 0x39, 0x2C, 0x34, 0x33, 0x32, 0x2C, 0x32, 0x35, 0x34, 0x2C, 0x35, 0x39, 0x37, 0x2C,
+ 0x35, 0x32, 0x39, 0x2C, 0x32, 0x39, 0x38, 0x2C, 0x34, 0x35, 0x31, 0x2C, 0x33, 0x35, 0x39, 0x2C,
+ 0x35, 0x32, 0x35, 0x2C, 0x34, 0x32, 0x33, 0x2C, 0x34, 0x36, 0x34, 0x2C, 0x34, 0x31, 0x37, 0x2C,
+ 0x34, 0x35, 0x37, 0x2C, 0x34, 0x37, 0x39, 0x2C, 0x32, 0x37, 0x35, 0x2C, 0x32, 0x38, 0x32, 0x2C,
+ 0x36, 0x30, 0x30, 0x2C, 0x36, 0x30, 0x30, 0x2C, 0x36, 0x30, 0x30, 0x2C, 0x35, 0x30, 0x31, 0x2C,
+ 0x38, 0x30, 0x30, 0x2C, 0x37, 0x34, 0x33, 0x2C, 0x36, 0x33, 0x36, 0x2C, 0x35, 0x39, 0x38, 0x2C,
+ 0x37, 0x31, 0x32, 0x2C, 0x36, 0x30, 0x38, 0x2C, 0x35, 0x36, 0x32, 0x2C, 0x36, 0x38, 0x30, 0x2C,
+ 0x37, 0x35, 0x36, 0x2C, 0x33, 0x30, 0x38, 0x2C, 0x33, 0x31, 0x34, 0x2C, 0x36, 0x37, 0x36, 0x2C,
+ 0x35, 0x35, 0x32, 0x2C, 0x31, 0x30, 0x34, 0x31, 0x2C, 0x38, 0x31, 0x37, 0x2C, 0x37, 0x32, 0x39,
+ 0x2C, 0x35, 0x36, 0x39, 0x2C, 0x36, 0x39, 0x38, 0x2C, 0x36, 0x37, 0x34, 0x2C, 0x36, 0x31, 0x38,
+ 0x2C, 0x36, 0x37, 0x33, 0x2C, 0x38, 0x30, 0x35, 0x2C, 0x37, 0x35, 0x33, 0x2C, 0x31, 0x32, 0x33,
+ 0x38, 0x2C, 0x37, 0x31, 0x36, 0x2C, 0x37, 0x35, 0x34, 0x2C, 0x35, 0x39, 0x39, 0x2C, 0x33, 0x31,
+ 0x35, 0x2C, 0x34, 0x36, 0x33, 0x2C, 0x33, 0x31, 0x35, 0x2C, 0x36, 0x30, 0x30, 0x2C, 0x35, 0x34,
+ 0x37, 0x2C, 0x32, 0x37, 0x38, 0x2C, 0x35, 0x38, 0x31, 0x2C, 0x35, 0x36, 0x34, 0x2C, 0x34, 0x34,
+ 0x30, 0x2C, 0x35, 0x37, 0x31, 0x2C, 0x34, 0x35, 0x30, 0x2C, 0x33, 0x34, 0x37, 0x2C, 0x36, 0x32,
+ 0x38, 0x2C, 0x36, 0x31, 0x31, 0x2C, 0x32, 0x38, 0x33, 0x2C, 0x32, 0x38, 0x33, 0x2C, 0x35, 0x36,
+ 0x30, 0x2C, 0x32, 0x35, 0x32, 0x2C, 0x39, 0x37, 0x36, 0x2C, 0x35, 0x39, 0x35, 0x2C, 0x35, 0x30,
+ 0x38, 0x2C, 0x35, 0x34, 0x39, 0x2C, 0x35, 0x34, 0x30, 0x2C, 0x33, 0x39, 0x35, 0x2C, 0x34, 0x34,
+ 0x31, 0x2C, 0x33, 0x30, 0x37, 0x2C, 0x36, 0x31, 0x34, 0x2C, 0x35, 0x35, 0x36, 0x2C, 0x39, 0x31,
+ 0x35, 0x2C, 0x35, 0x35, 0x39, 0x2C, 0x35, 0x39, 0x37, 0x2C, 0x34, 0x35, 0x32, 0x2C, 0x33, 0x31,
+ 0x35, 0x2C, 0x32, 0x32, 0x32, 0x2C, 0x33, 0x31, 0x35, 0x2C, 0x36, 0x30, 0x30, 0x2C, 0x38, 0x30,
+ 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C,
+ 0x37, 0x38, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x32, 0x37, 0x38, 0x2C, 0x30, 0x2C, 0x30, 0x2C,
+ 0x30, 0x2C, 0x31, 0x30, 0x36, 0x34, 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x30, 0x2C, 0x38, 0x30, 0x30,
+ 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x32, 0x35, 0x39, 0x2C, 0x32, 0x35, 0x39, 0x2C, 0x34, 0x37, 0x30,
+ 0x2C, 0x34, 0x37, 0x30, 0x2C, 0x35, 0x30, 0x30, 0x2C, 0x33, 0x30, 0x30, 0x2C, 0x36, 0x30, 0x30,
+ 0x2C, 0x32, 0x37, 0x38, 0x2C, 0x39, 0x39, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x37, 0x39, 0x30,
+ 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x38, 0x30, 0x30, 0x2C, 0x37, 0x35, 0x34, 0x2C, 0x32, 0x38, 0x32,
+ 0x2C, 0x33, 0x32, 0x34, 0x2C, 0x34, 0x35, 0x30, 0x2C, 0x36, 0x34, 0x30, 0x2C, 0x35, 0x31, 0x38,
+ 0x2C, 0x36, 0x30, 0x33, 0x2C, 0x30, 0x2C, 0x35, 0x31, 0x39, 0x2C, 0x32, 0x35, 0x34, 0x2C, 0x38,
+ 0x30, 0x30, 0x2C, 0x33, 0x34, 0x39, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x34, 0x33, 0x32, 0x2C, 0x38,
+ 0x30, 0x30, 0x2C, 0x32, 0x37, 0x38, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x32,
+ 0x37, 0x38, 0x2C, 0x36, 0x31, 0x34, 0x2C, 0x30, 0x2C, 0x32, 0x35, 0x34, 0x2C, 0x32, 0x37, 0x38,
+ 0x2C, 0x30, 0x2C, 0x33, 0x30, 0x35, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x35,
+ 0x30, 0x31, 0x2C, 0x37, 0x34, 0x33, 0x2C, 0x37, 0x34, 0x33, 0x2C, 0x37, 0x34, 0x33, 0x2C, 0x37,
+ 0x34, 0x33, 0x2C, 0x37, 0x34, 0x33, 0x2C, 0x37, 0x34, 0x33, 0x2C, 0x31, 0x30, 0x36, 0x30, 0x2C,
+ 0x35, 0x39, 0x38, 0x2C, 0x36, 0x30, 0x38, 0x2C, 0x36, 0x30, 0x38, 0x2C, 0x36, 0x30, 0x38, 0x2C,
+ 0x36, 0x30, 0x38, 0x2C, 0x33, 0x30, 0x38, 0x2C, 0x33, 0x30, 0x38, 0x2C, 0x33, 0x30, 0x38, 0x2C,
+ 0x33, 0x30, 0x38, 0x2C, 0x30, 0x2C, 0x38, 0x31, 0x37, 0x2C, 0x37, 0x32, 0x39, 0x2C, 0x37, 0x32,
+ 0x39, 0x2C, 0x37, 0x32, 0x39, 0x2C, 0x37, 0x32, 0x39, 0x2C, 0x37, 0x32, 0x39, 0x2C, 0x30, 0x2C,
+ 0x37, 0x32, 0x39, 0x2C, 0x38, 0x30, 0x35, 0x2C, 0x38, 0x30, 0x35, 0x2C, 0x38, 0x30, 0x35, 0x2C,
+ 0x38, 0x30, 0x35, 0x2C, 0x30, 0x2C, 0x30, 0x2C, 0x36, 0x38, 0x38, 0x2C, 0x35, 0x38, 0x31, 0x2C,
+ 0x35, 0x38, 0x31, 0x2C, 0x35, 0x38, 0x31, 0x2C, 0x35, 0x38, 0x31, 0x2C, 0x35, 0x38, 0x31, 0x2C,
+ 0x35, 0x38, 0x31, 0x2C, 0x37, 0x39, 0x32, 0x2C, 0x34, 0x34, 0x30, 0x2C, 0x34, 0x35, 0x30, 0x2C,
+ 0x34, 0x35, 0x30, 0x2C, 0x34, 0x35, 0x30, 0x2C, 0x34, 0x35, 0x30, 0x2C, 0x32, 0x38, 0x33, 0x2C,
+ 0x32, 0x38, 0x33, 0x2C, 0x32, 0x38, 0x33, 0x2C, 0x32, 0x38, 0x33, 0x2C, 0x30, 0x2C, 0x35, 0x39,
+ 0x35, 0x2C, 0x35, 0x30, 0x38, 0x2C, 0x35, 0x30, 0x38, 0x2C, 0x35, 0x30, 0x38, 0x2C, 0x35, 0x30,
+ 0x38, 0x2C, 0x35, 0x30, 0x38, 0x2C, 0x30, 0x2C, 0x35, 0x30, 0x38, 0x2C, 0x36, 0x31, 0x34, 0x2C,
+ 0x36, 0x31, 0x34, 0x2C, 0x36, 0x31, 0x34, 0x2C, 0x36, 0x31, 0x34, 0x2C, 0x30, 0x2C, 0x30, 0x2C,
+ 0x35, 0x39, 0x37, 0x5D, 0x2C, 0x22, 0x45, 0x6E, 0x63, 0x22, 0x3A, 0x22, 0x63, 0x70, 0x31, 0x32,
+ 0x35, 0x32, 0x22, 0x2C, 0x22, 0x44, 0x69, 0x66, 0x66, 0x22, 0x3A, 0x22, 0x22, 0x2C, 0x22, 0x46,
+ 0x69, 0x6C, 0x65, 0x22, 0x3A, 0x22, 0x63, 0x61, 0x6C, 0x6C, 0x69, 0x67, 0x72, 0x61, 0x2E, 0x7A,
+ 0x22, 0x2C, 0x22, 0x53, 0x69, 0x7A, 0x65, 0x31, 0x22, 0x3A, 0x30, 0x2C, 0x22, 0x53, 0x69, 0x7A,
+ 0x65, 0x32, 0x22, 0x3A, 0x30, 0x2C, 0x22, 0x4F, 0x72, 0x69, 0x67, 0x69, 0x6E, 0x61, 0x6C, 0x53,
+ 0x69, 0x7A, 0x65, 0x22, 0x3A, 0x34, 0x30, 0x31, 0x32, 0x30, 0x2C, 0x22, 0x49, 0x22, 0x3A, 0x30,
+ 0x2C, 0x22, 0x4E, 0x22, 0x3A, 0x30, 0x2C, 0x22, 0x44, 0x69, 0x66, 0x66, 0x4E, 0x22, 0x3A, 0x30,
+ 0x7D}
+
+// CalligraZ is embedded byte slice for calligra.z
+var CalligraZ = []byte{
+ 0x78, 0x9C, 0xA4, 0xFC, 0x07, 0x80, 0x5C, 0x57, 0x7D, 0x2F, 0x8E, 0x9F, 0x73, 0x6E, 0xEF, 0xFD,
+ 0xDE, 0xE9, 0xBD, 0xF7, 0x9D, 0xD9, 0x99, 0xD9, 0xDD, 0x99, 0xDD, 0x99, 0xED, 0xAB, 0xDE, 0x65,
+ 0xAD, 0xEC, 0xB5, 0x25, 0x4B, 0xB2, 0xE4, 0x22, 0x5B, 0x96, 0x6D, 0x59, 0xC6, 0x35, 0xB8, 0x51,
+ 0x0D, 0xBC, 0x47, 0x4B, 0x80, 0x40, 0x02, 0x06, 0x02, 0x04, 0x4C, 0x7B, 0x0F, 0xF1, 0x02, 0xA4,
+ 0x40, 0x02, 0x04, 0x0C, 0x8F, 0xBC, 0x88, 0x16, 0x02, 0xFF, 0x07, 0x8F, 0x7F, 0x78, 0x18, 0x1B,
+ 0x1B, 0x48, 0x20, 0x41, 0xDA, 0xDF, 0xB9, 0x77, 0x66, 0x57, 0x2B, 0xD9, 0x3C, 0x7E, 0x65, 0x77,
+ 0xEE, 0xCC, 0x9D, 0x33, 0x33, 0xF7, 0x9E, 0xF2, 0x2D, 0x9F, 0x6F, 0x3B, 0x00, 0x02, 0x00, 0x64,
+ 0x50, 0x03, 0x04, 0x78, 0x6A, 0xC7, 0x9E, 0x6A, 0xFD, 0x1E, 0xA6, 0x29, 0x02, 0xF0, 0x9A, 0x77,
+ 0xE1, 0xD6, 0xED, 0x47, 0x4E, 0x1E, 0x3E, 0xE5, 0xFF, 0xD5, 0xB1, 0xDF, 0x00, 0xF0, 0x07, 0xAF,
+ 0x07, 0x80, 0xBC, 0xE6, 0xC8, 0x99, 0x3B, 0x63, 0xAF, 0xFF, 0xCD, 0xC7, 0x9E, 0x01, 0xE0, 0x95,
+ 0x5F, 0x04, 0x00, 0x9D, 0xBF, 0xE1, 0xD4, 0xF1, 0x93, 0xEF, 0xFB, 0xF6, 0xB5, 0xFF, 0xD9, 0xFD,
+ 0x0C, 0x7F, 0xFF, 0xE8, 0xF1, 0x5B, 0xEE, 0xB9, 0x21, 0xF2, 0x96, 0x57, 0x75, 0xF1, 0x7B, 0xFC,
+ 0xF9, 0x99, 0xF3, 0x27, 0x8E, 0x9E, 0x3C, 0x7B, 0xEC, 0x0B, 0xC2, 0xF5, 0xF8, 0x7A, 0x3F, 0x07,
+ 0x40, 0xF9, 0xE2, 0x89, 0x63, 0x87, 0x8F, 0x1E, 0x2F, 0xDE, 0xF5, 0x49, 0xFC, 0x5D, 0x7C, 0x0D,
+ 0xD0, 0x3A, 0x81, 0x1B, 0x58, 0x0E, 0xDD, 0x0A, 0x00, 0x4C, 0xE1, 0xF7, 0xA9, 0x13, 0x27, 0xEF,
+ 0x3C, 0xFB, 0x5F, 0xF6, 0x33, 0x0D, 0x00, 0x1E, 0xC5, 0x9F, 0x13, 0xFF, 0x74, 0xCB, 0x6D, 0x47,
+ 0x0E, 0x83, 0x4D, 0xF4, 0x5F, 0x00, 0x70, 0x2F, 0xEE, 0x0F, 0xF1, 0x83, 0x93, 0x87, 0xCF, 0x9E,
+ 0x82, 0xF7, 0xC0, 0x1F, 0xE0, 0xEF, 0x2F, 0xE1, 0xEF, 0xC7, 0x6E, 0x3D, 0x7C, 0xF2, 0x58, 0x3D,
+ 0x7D, 0xF4, 0x53, 0xF8, 0xFD, 0x09, 0xDC, 0x9F, 0xE7, 0x4F, 0xDD, 0x76, 0xC7, 0x9D, 0x9D, 0xCD,
+ 0x9D, 0x3F, 0x03, 0xE0, 0xC1, 0x87, 0xF0, 0x7B, 0xF5, 0xD4, 0xE9, 0x63, 0xA7, 0x7E, 0x4D, 0x40,
+ 0x1D, 0xF7, 0xE7, 0x2F, 0xF1, 0xF7, 0x59, 0x6F, 0xAC, 0xF8, 0x58, 0xFA, 0x8F, 0x7F, 0x50, 0xAE,
+ 0x53, 0xBA, 0xBF, 0xC2, 0xD7, 0xFC, 0x17, 0xDC, 0x02, 0xDE, 0xBB, 0x84, 0x9E, 0x5C, 0x7B, 0x5D,
+ 0xDD, 0xB3, 0x6A, 0x53, 0x35, 0xE2, 0x61, 0xFC, 0x96, 0x00, 0xC8, 0xFB, 0x85, 0xF7, 0x1B, 0xE2,
+ 0xE1, 0x55, 0x1B, 0x5F, 0xE7, 0xFC, 0xEA, 0x9E, 0x0B, 0xAF, 0xA2, 0x6A, 0xC3, 0xF6, 0x4B, 0x7F,
+ 0xFF, 0xE6, 0xB5, 0xFC, 0x1B, 0xB8, 0x19, 0x90, 0xE0, 0x30, 0x3E, 0x10, 0xBE, 0x5B, 0x1F, 0xF0,
+ 0xB8, 0xED, 0x18, 0xF8, 0x1A, 0x7E, 0x47, 0xE0, 0x33, 0x0B, 0xA2, 0xF5, 0xEF, 0x4F, 0x80, 0xF0,
+ 0xF0, 0x0C, 0x02, 0x1F, 0x38, 0x32, 0x3C, 0x47, 0x78, 0x25, 0x5E, 0x3E, 0x3C, 0x27, 0xC0, 0x41,
+ 0xF0, 0x99, 0xE1, 0x39, 0x09, 0x72, 0xB0, 0x38, 0x3C, 0xA7, 0x40, 0x1F, 0xDE, 0x31, 0x3C, 0xA7,
+ 0x71, 0xFB, 0xDF, 0xAD, 0xF7, 0x25, 0x3C, 0xE8, 0xA9, 0xF7, 0x2C, 0x82, 0xAB, 0x86, 0xE7, 0x08,
+ 0x30, 0xE0, 0xDE, 0xE1, 0x39, 0x01, 0xCA, 0xE0, 0xF5, 0xC3, 0x73, 0x12, 0x98, 0xD0, 0x19, 0x9E,
+ 0x53, 0x20, 0x06, 0xF7, 0x0C, 0xCF, 0x69, 0xDC, 0xFE, 0x71, 0xFC, 0x4D, 0x48, 0x72, 0xC3, 0x7E,
+ 0x0E, 0xCE, 0x07, 0xFD, 0x1C, 0x9C, 0x0F, 0xFA, 0x39, 0x38, 0x1F, 0xF4, 0x73, 0x70, 0x3E, 0xE8,
+ 0xE7, 0xE0, 0x7C, 0xD0, 0xCF, 0xC1, 0xB9, 0xD7, 0xCF, 0xC5, 0x63, 0xB7, 0x1E, 0x3B, 0x7D, 0xF8,
+ 0xCE, 0x63, 0x47, 0x63, 0xD7, 0xDF, 0x13, 0x5B, 0xB8, 0xED, 0xD6, 0x3B, 0x6F, 0x3B, 0x7E, 0xFA,
+ 0xF0, 0xA9, 0x13, 0xC7, 0x4E, 0xC7, 0x1A, 0x95, 0x26, 0x58, 0xC4, 0x13, 0x75, 0x2B, 0x3E, 0x4E,
+ 0xE3, 0xE9, 0xBB, 0x13, 0xBF, 0x1E, 0x05, 0x31, 0x70, 0x3D, 0xB8, 0x07, 0x3F, 0x2F, 0x80, 0xDB,
+ 0xF0, 0x27, 0x77, 0xE2, 0xE7, 0xE3, 0xDE, 0xA7, 0xA7, 0xC0, 0x09, 0xEF, 0x7B, 0x31, 0xD0, 0x00,
+ 0x15, 0xD0, 0x9C, 0x3D, 0x7C, 0xCB, 0x2D, 0x37, 0x0E, 0xAF, 0x04, 0x66, 0xF1, 0xE7, 0xB7, 0xE0,
+ 0xFF, 0x1B, 0x2F, 0xFF, 0xEE, 0xEE, 0x63, 0xC7, 0xEF, 0xBA, 0xE5, 0xF0, 0x69, 0xB0, 0x1B, 0xBF,
+ 0x39, 0x0E, 0xEE, 0xC2, 0x5F, 0x38, 0x0C, 0x4E, 0x4F, 0xDF, 0x72, 0xE7, 0x1D, 0xF7, 0xDC, 0xF1,
+ 0xA2, 0x9E, 0xC4, 0x62, 0x1B, 0xAF, 0x18, 0x5B, 0xFB, 0xE9, 0x34, 0xFE, 0xD1, 0x9D, 0xE0, 0x0E,
+ 0xDC, 0xA3, 0x3B, 0x7E, 0x7F, 0x9F, 0xF0, 0x6B, 0xEC, 0x77, 0xF5, 0x05, 0x7F, 0x72, 0x59, 0x37,
+ 0x5E, 0xF2, 0x6E, 0xFF, 0x37, 0x7F, 0xFB, 0x3B, 0x87, 0xD0, 0xAC, 0xD6, 0x5B, 0xD5, 0xF1, 0xFA,
+ 0xFF, 0x8B, 0x5E, 0x37, 0x41, 0x15, 0xD4, 0x41, 0x0B, 0x3F, 0x8F, 0x83, 0xFA, 0xFF, 0x97, 0xBE,
+ 0x61, 0xE2, 0xE9, 0x53, 0x14, 0x49, 0x20, 0x50, 0x3A, 0x33, 0x1F, 0x7B, 0x8A, 0x48, 0xCF, 0x27,
+ 0x0F, 0x9F, 0xF0, 0x25, 0x4F, 0x1C, 0x9A, 0x2B, 0x97, 0xD6, 0xDF, 0x0F, 0xDE, 0xC6, 0x62, 0x9F,
+ 0x5A, 0xFD, 0xCB, 0x31, 0xFD, 0xA3, 0x7D, 0xD8, 0x1A, 0x73, 0xDF, 0x3D, 0xD5, 0x1F, 0xD3, 0x9F,
+ 0x82, 0x2D, 0xB7, 0xB1, 0x5C, 0x82, 0x4F, 0x2D, 0x9C, 0x89, 0x2D, 0xE2, 0x5F, 0x2E, 0x1C, 0x3E,
+ 0x11, 0x3B, 0xE0, 0xFE, 0x30, 0x39, 0xF6, 0x14, 0x4A, 0xBB, 0x5F, 0x38, 0x36, 0xB6, 0x5C, 0xEE,
+ 0x43, 0xF8, 0xDA, 0x4F, 0xC1, 0xD5, 0x47, 0x31, 0x4D, 0xD6, 0x31, 0xB1, 0x3F, 0x4B, 0xC4, 0x30,
+ 0xCD, 0x31, 0x60, 0xB2, 0x1F, 0x64, 0xC8, 0xBF, 0x03, 0x34, 0xF5, 0x77, 0x90, 0x22, 0x11, 0x81,
+ 0x18, 0x1A, 0x41, 0x80, 0xE0, 0x3F, 0x62, 0x7A, 0x84, 0x60, 0xE1, 0x4C, 0xB5, 0xED, 0x03, 0xBD,
+ 0x6E, 0xAF, 0x0B, 0xAB, 0xDD, 0x0B, 0x5D, 0xF7, 0x00, 0xEA, 0x85, 0x2E, 0x7E, 0x8C, 0xD4, 0x3E,
+ 0xC6, 0x02, 0xAA, 0xD8, 0xD0, 0xE2, 0x5A, 0x16, 0x1F, 0x75, 0xF4, 0x17, 0xF5, 0x0B, 0xEF, 0x27,
+ 0x62, 0xBF, 0xFD, 0x01, 0x3E, 0xBB, 0x30, 0x87, 0xEF, 0x31, 0xBB, 0xFA, 0x73, 0xF0, 0x1F, 0xE8,
+ 0x69, 0xCC, 0xD9, 0x3E, 0x30, 0xDB, 0x0F, 0x09, 0xC0, 0x86, 0x0C, 0x81, 0x1F, 0xB4, 0xDF, 0xA6,
+ 0xFC, 0x1A, 0x03, 0x11, 0x03, 0x98, 0x15, 0x51, 0x66, 0xA1, 0xB6, 0x76, 0x93, 0x33, 0x3D, 0x1F,
+ 0xAC, 0x5E, 0x50, 0xCF, 0xE3, 0x3B, 0xA8, 0x17, 0xA0, 0xA6, 0x8F, 0xE3, 0x07, 0xAC, 0x54, 0xF0,
+ 0x9D, 0xFC, 0x1A, 0x55, 0x34, 0x14, 0x54, 0x25, 0x7A, 0xC8, 0x60, 0xE8, 0x64, 0x22, 0xD3, 0x1C,
+ 0xED, 0x11, 0x8E, 0xFD, 0x0C, 0x45, 0x9F, 0x16, 0x05, 0x8E, 0xCB, 0x17, 0x0A, 0x63, 0x47, 0x78,
+ 0x3A, 0x9A, 0x89, 0xC5, 0x89, 0x14, 0xED, 0xA0, 0xA7, 0xFF, 0xE9, 0x17, 0x5B, 0xCE, 0xDC, 0x75,
+ 0xCD, 0x35, 0xE1, 0x70, 0xE4, 0xC2, 0x63, 0xB3, 0xA8, 0x6D, 0x05, 0x7C, 0x3E, 0x14, 0x30, 0xA6,
+ 0x70, 0xAF, 0xBA, 0xF0, 0x2B, 0xF0, 0x30, 0xEE, 0x95, 0x3B, 0xF2, 0x64, 0x5F, 0xA4, 0x49, 0x84,
+ 0x59, 0x91, 0x59, 0xA1, 0x11, 0x77, 0x16, 0x9C, 0x71, 0xBB, 0xD0, 0xF5, 0x01, 0x7C, 0x4F, 0xEF,
+ 0xAE, 0x2C, 0x4D, 0x15, 0xA1, 0x02, 0xDB, 0x59, 0x7C, 0xC0, 0xC3, 0xF5, 0xBD, 0x62, 0x1A, 0x1F,
+ 0xE8, 0xE9, 0x5F, 0xF3, 0x2F, 0xA8, 0xF8, 0x70, 0xE5, 0x45, 0x12, 0x3F, 0xA5, 0xD1, 0x67, 0x40,
+ 0x10, 0x44, 0xC1, 0xD7, 0xFA, 0x47, 0x74, 0x99, 0x04, 0x8E, 0x8D, 0x7C, 0x7E, 0xBF, 0x2F, 0xCA,
+ 0xB1, 0x21, 0x14, 0xE1, 0x85, 0x70, 0x58, 0xC0, 0x2D, 0x96, 0x7B, 0x86, 0x4C, 0x4D, 0x95, 0x44,
+ 0xCB, 0x12, 0x7D, 0x7E, 0x14, 0xF0, 0x3E, 0x0F, 0xD2, 0x78, 0xBA, 0x03, 0x01, 0x26, 0x1C, 0xD2,
+ 0x35, 0x44, 0x41, 0x3E, 0xE8, 0x73, 0x4C, 0x83, 0x02, 0xE3, 0xD1, 0x88, 0xAA, 0x90, 0x14, 0xC1,
+ 0xCB, 0x12, 0xCF, 0xD1, 0x14, 0x15, 0xF0, 0xDB, 0x84, 0x25, 0x89, 0x02, 0x4B, 0x30, 0x10, 0xF4,
+ 0x9C, 0x2E, 0x7E, 0x80, 0xAA, 0xD3, 0xBD, 0xE0, 0x9D, 0xE1, 0xE7, 0xC7, 0x2B, 0xF2, 0xE7, 0xD7,
+ 0xFF, 0x7F, 0x3B, 0x78, 0xAD, 0xB8, 0x27, 0xBF, 0xFF, 0x83, 0x61, 0xA3, 0xF7, 0x1E, 0x9F, 0xAF,
+ 0x8D, 0x3C, 0x26, 0xE3, 0x91, 0x33, 0x49, 0xA6, 0x81, 0x8F, 0x64, 0xDB, 0x3B, 0xDA, 0x0D, 0xEF,
+ 0x68, 0x30, 0xF8, 0x50, 0x20, 0xFE, 0x08, 0xA5, 0x95, 0x53, 0xA9, 0x53, 0xF2, 0xA9, 0xC2, 0x42,
+ 0x61, 0x1F, 0x3E, 0x4E, 0x79, 0xEF, 0x6E, 0xCF, 0x2F, 0xE4, 0xF7, 0xBA, 0x2D, 0x7B, 0x93, 0x7B,
+ 0xE0, 0xAF, 0x17, 0xDE, 0xB7, 0xF0, 0x05, 0xFC, 0xB7, 0xFE, 0x82, 0x67, 0x3D, 0xB6, 0xFA, 0x72,
+ 0xB4, 0x87, 0xA8, 0x80, 0xAD, 0x60, 0x2F, 0x38, 0x04, 0x5E, 0xD1, 0x9F, 0x3D, 0xB0, 0x6D, 0x22,
+ 0x29, 0x6F, 0xDF, 0xA6, 0x14, 0xEA, 0x33, 0x33, 0xD5, 0x2A, 0xA7, 0x1C, 0xB8, 0xE6, 0x68, 0xDF,
+ 0xD7, 0x7C, 0xD3, 0x4A, 0xC4, 0xD1, 0x67, 0x66, 0xCC, 0xFA, 0x03, 0xD7, 0x1D, 0xDC, 0x5D, 0x10,
+ 0x78, 0x96, 0xE0, 0xB6, 0x17, 0x0B, 0x68, 0x2E, 0x1A, 0x51, 0xD0, 0xD5, 0x07, 0x17, 0xEB, 0xE4,
+ 0xB2, 0x4F, 0xD9, 0x72, 0xA0, 0x1A, 0x92, 0xC3, 0xD0, 0x37, 0x24, 0x9F, 0x1E, 0x54, 0xBF, 0xA7,
+ 0x7E, 0x6F, 0xC4, 0x9D, 0x98, 0x6E, 0xB7, 0xEA, 0x1E, 0x4E, 0x57, 0x3D, 0x8F, 0xA9, 0xA9, 0x77,
+ 0xA1, 0x77, 0xA1, 0x8B, 0x9F, 0xCE, 0xBB, 0x24, 0xA5, 0x76, 0x01, 0x7E, 0x06, 0x78, 0x98, 0xDE,
+ 0x58, 0xDD, 0xC1, 0x1E, 0xF6, 0x51, 0xC5, 0xB4, 0x0C, 0x15, 0x84, 0x0F, 0x68, 0x39, 0x32, 0x64,
+ 0xDA, 0x32, 0x4C, 0x26, 0xAA, 0xB0, 0x02, 0x31, 0x99, 0x41, 0xC7, 0x76, 0x9A, 0x55, 0x88, 0x29,
+ 0xAE, 0xD5, 0x9E, 0x82, 0x3D, 0x98, 0xED, 0x11, 0x32, 0xB4, 0xA6, 0x60, 0xA3, 0x1E, 0x41, 0x96,
+ 0xE9, 0xFE, 0x2C, 0x93, 0xA5, 0x2D, 0xD3, 0x8E, 0x22, 0xDB, 0x32, 0xD3, 0xD9, 0x04, 0xFE, 0xD0,
+ 0x74, 0x8C, 0x0A, 0xCC, 0x46, 0xF1, 0xB5, 0xDA, 0xAD, 0xE6, 0x28, 0x1A, 0xE5, 0xA2, 0x8E, 0x42,
+ 0x45, 0xDA, 0x09, 0x88, 0x7C, 0x39, 0x93, 0xD2, 0x55, 0x2D, 0x5B, 0x0B, 0x96, 0x0B, 0xCE, 0xCB,
+ 0xF8, 0xE8, 0xCC, 0x13, 0xEA, 0x96, 0x50, 0xCE, 0x8A, 0x4A, 0xD7, 0x42, 0x4D, 0xF3, 0xF9, 0x48,
+ 0x12, 0x7F, 0x18, 0x1E, 0x8B, 0x15, 0x03, 0x69, 0xDD, 0x09, 0x07, 0xCB, 0x1C, 0x24, 0x5F, 0x6F,
+ 0x6F, 0xBD, 0xF8, 0x45, 0x4A, 0xF6, 0xA5, 0x3B, 0x4F, 0x11, 0x63, 0x61, 0x84, 0xA0, 0xD5, 0xFB,
+ 0xB8, 0x9C, 0x30, 0x24, 0xCA, 0x9F, 0x50, 0x75, 0xA3, 0x2D, 0xF8, 0xB5, 0xBB, 0x08, 0x24, 0xF3,
+ 0x6A, 0xC1, 0x17, 0x14, 0x17, 0xEC, 0xBE, 0xF6, 0x74, 0x91, 0xC9, 0xCC, 0x06, 0x36, 0xA7, 0x2C,
+ 0x87, 0xAE, 0x2D, 0x0A, 0xBC, 0x22, 0xDB, 0xED, 0x00, 0x81, 0x44, 0x21, 0x6A, 0x6A, 0xBA, 0xC9,
+ 0x09, 0x62, 0xCE, 0xDF, 0x6C, 0x29, 0x81, 0x4C, 0x95, 0x4B, 0x2F, 0x16, 0xFE, 0xF7, 0xFB, 0x84,
+ 0x74, 0xBC, 0x19, 0xB8, 0xF8, 0x4C, 0xA4, 0x4E, 0xD6, 0xEA, 0xC5, 0x02, 0x1D, 0x6C, 0xB2, 0xAE,
+ 0xE6, 0x4B, 0xAE, 0xFE, 0x9C, 0xF8, 0x28, 0xFA, 0x1C, 0x28, 0x61, 0x01, 0x76, 0x13, 0x78, 0xA0,
+ 0xDF, 0xD8, 0xB7, 0x7B, 0x5B, 0xD9, 0xD4, 0xF9, 0xCD, 0xE5, 0x80, 0xC6, 0x64, 0xF2, 0xF1, 0xA3,
+ 0xC7, 0x0F, 0x8D, 0xB5, 0xC7, 0x5B, 0xA8, 0x3B, 0x39, 0xD9, 0xDD, 0x75, 0x30, 0x76, 0x73, 0x2A,
+ 0x1E, 0xCD, 0x1F, 0x8A, 0xAC, 0x20, 0xCC, 0xF5, 0xE1, 0x7C, 0xA2, 0xD3, 0x65, 0x21, 0xBF, 0x2E,
+ 0x37, 0x30, 0x43, 0x57, 0x2F, 0x80, 0x73, 0xE0, 0x38, 0x5C, 0xE9, 0x5D, 0xF0, 0x24, 0xC7, 0x39,
+ 0x70, 0x04, 0xCE, 0xF4, 0xCE, 0xAF, 0x91, 0x9C, 0xFB, 0x0F, 0x06, 0xBC, 0x0E, 0xBC, 0x15, 0x19,
+ 0xAC, 0x8B, 0xB7, 0x32, 0x37, 0xF3, 0x98, 0x0C, 0x4D, 0x19, 0x0D, 0x59, 0xBE, 0x39, 0x85, 0xF0,
+ 0x72, 0x28, 0xD0, 0x8C, 0x10, 0x8D, 0x7A, 0x0F, 0x8E, 0x56, 0xF0, 0x2A, 0xD1, 0x49, 0x26, 0xDB,
+ 0x6E, 0xE1, 0xC5, 0x80, 0x69, 0x85, 0xC4, 0xAB, 0x41, 0xD2, 0x98, 0x59, 0x5B, 0x3A, 0x5E, 0xAA,
+ 0xB6, 0x61, 0xCA, 0x84, 0xF7, 0xBB, 0x29, 0x18, 0x85, 0x0C, 0x5E, 0xA3, 0x08, 0x6A, 0xD4, 0xF1,
+ 0x82, 0x64, 0x92, 0x09, 0x05, 0x0E, 0x7F, 0x04, 0xBF, 0x14, 0x1B, 0xE3, 0xED, 0xA5, 0xFE, 0x35,
+ 0x9B, 0x11, 0xED, 0x73, 0x0A, 0x32, 0xC5, 0xF9, 0x23, 0x7A, 0x39, 0xD4, 0xD3, 0x48, 0x7A, 0xEE,
+ 0x5A, 0x46, 0xA5, 0x7C, 0xAC, 0x7F, 0x53, 0x73, 0x74, 0x77, 0x06, 0xF6, 0x17, 0x3A, 0xD7, 0xFB,
+ 0xAB, 0x62, 0x49, 0x8B, 0x97, 0x7C, 0x4A, 0x24, 0x66, 0x9D, 0xB9, 0xED, 0x2F, 0x36, 0xD1, 0x11,
+ 0xF6, 0xAB, 0x47, 0x9D, 0x62, 0x37, 0x72, 0xD5, 0x96, 0x7A, 0x5E, 0x94, 0x19, 0xBD, 0x56, 0x49,
+ 0x2B, 0x8D, 0xF8, 0xF4, 0x71, 0x45, 0xB7, 0x18, 0x7B, 0x6F, 0x21, 0xBA, 0x6B, 0x1A, 0xB1, 0xE3,
+ 0x3B, 0xA6, 0x59, 0xBD, 0xFE, 0xEA, 0x3C, 0x4D, 0xB3, 0xB9, 0x74, 0xB0, 0x41, 0xE7, 0x97, 0x7C,
+ 0xDD, 0x9C, 0x1E, 0xD9, 0x16, 0x8D, 0x4F, 0x3E, 0x8A, 0x48, 0x5E, 0xCD, 0xF7, 0xB6, 0x3C, 0x72,
+ 0xFD, 0x9E, 0x57, 0x26, 0x66, 0xD5, 0xBE, 0xBF, 0x36, 0x9B, 0x76, 0x38, 0x02, 0xFD, 0xC9, 0x5B,
+ 0xA0, 0x72, 0x3B, 0xC1, 0xA2, 0x8B, 0xF3, 0xFB, 0x0F, 0x19, 0x61, 0xF3, 0xE1, 0x46, 0xFE, 0xAA,
+ 0x34, 0x49, 0x2A, 0x85, 0x74, 0x79, 0x6F, 0x56, 0x3E, 0x90, 0x2C, 0xBF, 0x97, 0x20, 0x65, 0xA1,
+ 0x90, 0xBC, 0xDA, 0x95, 0x40, 0xF9, 0xD5, 0xE7, 0x88, 0x22, 0xFA, 0x63, 0x8C, 0xA0, 0x76, 0x82,
+ 0x53, 0xFD, 0x56, 0xBF, 0x97, 0xA7, 0x41, 0xC3, 0xE9, 0xCE, 0xF4, 0xFA, 0xA5, 0x5C, 0x9A, 0x22,
+ 0xB3, 0x60, 0xEB, 0x96, 0x8C, 0x30, 0x6D, 0xA7, 0xFB, 0xB3, 0x33, 0xC9, 0xC9, 0xEE, 0x11, 0x23,
+ 0xBC, 0xD0, 0xDE, 0xB9, 0x63, 0x86, 0x98, 0x46, 0x54, 0x1B, 0x85, 0xD3, 0xC9, 0xA2, 0x50, 0x82,
+ 0xC6, 0x1A, 0x03, 0x75, 0xBD, 0xC5, 0x5A, 0xE3, 0x1A, 0x57, 0xDC, 0x7B, 0x92, 0xDE, 0x7B, 0xC6,
+ 0x2D, 0xDE, 0x0A, 0xAD, 0x73, 0xCD, 0x2E, 0xC3, 0x15, 0x8E, 0x44, 0xD2, 0xC1, 0xEB, 0x93, 0x4C,
+ 0x54, 0x28, 0xCC, 0x1F, 0x98, 0x39, 0x2A, 0x84, 0xF7, 0x8A, 0xE7, 0xD6, 0xC1, 0xB3, 0x6B, 0x99,
+ 0x0A, 0xAC, 0x50, 0x49, 0x8F, 0x27, 0xF0, 0xE4, 0xF7, 0x10, 0x9E, 0x77, 0xBC, 0x64, 0xDE, 0x1B,
+ 0x8F, 0x99, 0x88, 0xA2, 0x3F, 0x10, 0x8F, 0x1D, 0x80, 0x63, 0xAF, 0xDA, 0x52, 0x34, 0x5B, 0x39,
+ 0x7F, 0x2B, 0x67, 0x8F, 0x76, 0x45, 0x35, 0x91, 0x30, 0xC5, 0xCD, 0xDB, 0xA6, 0x3A, 0x55, 0x95,
+ 0x29, 0xB6, 0x8C, 0xDC, 0x66, 0x9E, 0xB3, 0x43, 0xC1, 0x08, 0x14, 0x4B, 0x89, 0xC8, 0xFC, 0xE8,
+ 0xA6, 0xAD, 0xE8, 0x15, 0xD4, 0xAB, 0xD0, 0x1D, 0x27, 0x16, 0x26, 0x37, 0xDB, 0x5A, 0xA2, 0x90,
+ 0xA0, 0x20, 0xFC, 0x40, 0x20, 0x10, 0x4F, 0xDA, 0x13, 0xFB, 0xEE, 0x4D, 0xF2, 0x02, 0x1F, 0xCA,
+ 0xD4, 0x7D, 0xE9, 0xA5, 0x22, 0xC7, 0x1A, 0xC1, 0x68, 0x42, 0xCB, 0xEF, 0x2F, 0x85, 0x4C, 0xE8,
+ 0x0B, 0xB3, 0xAA, 0xAF, 0xAA, 0x8A, 0x86, 0xCE, 0x22, 0x21, 0x1F, 0x72, 0x26, 0x4C, 0x04, 0x23,
+ 0xBB, 0x6E, 0xBA, 0x9D, 0xC8, 0xD5, 0x13, 0x1D, 0x9B, 0x44, 0x54, 0x20, 0xA2, 0x60, 0xDC, 0xB6,
+ 0x04, 0xBF, 0x02, 0x9E, 0xF6, 0xB4, 0x43, 0xB0, 0xCF, 0x62, 0x08, 0xCA, 0xAC, 0x0C, 0xF4, 0x02,
+ 0xD6, 0x4C, 0x60, 0xA0, 0x89, 0xF0, 0x57, 0xB1, 0x26, 0x82, 0xED, 0xA7, 0xD7, 0x54, 0x01, 0xFE,
+ 0xD5, 0xF8, 0xEA, 0x2B, 0x61, 0x91, 0xD0, 0x30, 0xFE, 0x8B, 0xF7, 0x05, 0x13, 0xF8, 0x91, 0x68,
+ 0x56, 0x56, 0xC8, 0xEA, 0xF0, 0x87, 0x78, 0x52, 0x87, 0xBF, 0x8D, 0x88, 0x54, 0x91, 0x62, 0xB0,
+ 0x7C, 0xA9, 0x40, 0x2C, 0x5C, 0x10, 0x26, 0x4C, 0x84, 0x85, 0x09, 0x81, 0xA7, 0x03, 0x3A, 0xB0,
+ 0xD8, 0xF5, 0x8B, 0x72, 0x30, 0x67, 0x88, 0x02, 0x2F, 0xDA, 0x41, 0x9F, 0xC8, 0x70, 0x8F, 0xA8,
+ 0xF1, 0x82, 0x9D, 0x4A, 0xA7, 0x7C, 0x55, 0x5B, 0x50, 0x12, 0xDB, 0xC7, 0x33, 0xD9, 0xFA, 0x9D,
+ 0xD5, 0xE6, 0x7D, 0x57, 0x4D, 0x07, 0x04, 0xB5, 0x17, 0x59, 0x38, 0x75, 0xDB, 0xD2, 0xF2, 0x1F,
+ 0x5F, 0x33, 0xEE, 0x62, 0xD1, 0xD5, 0x57, 0x82, 0x17, 0xD6, 0xEE, 0x6F, 0x09, 0x0A, 0x42, 0xBE,
+ 0xCA, 0x8A, 0xF0, 0x12, 0xF7, 0xB7, 0x70, 0xDF, 0xB1, 0x94, 0x92, 0x09, 0x85, 0x98, 0xC2, 0xB7,
+ 0xAF, 0xA0, 0x2A, 0xC4, 0x8B, 0x15, 0xC1, 0xEC, 0x61, 0xFF, 0x84, 0xD3, 0x39, 0x3B, 0x20, 0xD0,
+ 0xDC, 0xA3, 0xA9, 0x31, 0x9B, 0x0F, 0x64, 0x52, 0x62, 0x24, 0xDC, 0x08, 0xE6, 0x0D, 0x41, 0x87,
+ 0x5F, 0xDC, 0x59, 0x6B, 0x5F, 0x9F, 0xDA, 0x32, 0xEB, 0x13, 0xD5, 0x7E, 0xFF, 0x8D, 0xB7, 0x2D,
+ 0x15, 0xF7, 0xDD, 0xBD, 0x32, 0x66, 0x58, 0x81, 0x6A, 0x62, 0xDB, 0x58, 0x66, 0x12, 0xDF, 0x3F,
+ 0x09, 0xDF, 0x02, 0xF7, 0xA3, 0x2F, 0x83, 0x49, 0xF0, 0x70, 0xBF, 0x5B, 0x4F, 0xA7, 0xA2, 0x41,
+ 0x9E, 0x03, 0x9D, 0x6C, 0x54, 0x46, 0x80, 0x2E, 0x44, 0x4B, 0x4D, 0x55, 0x05, 0x25, 0x7B, 0xB4,
+ 0x24, 0x33, 0x0C, 0x28, 0x75, 0x40, 0x49, 0xB5, 0x9A, 0xCF, 0xC7, 0x47, 0x0A, 0x7B, 0xAB, 0x95,
+ 0x52, 0x53, 0x1B, 0x45, 0x25, 0x0C, 0xC0, 0x56, 0xEC, 0xF6, 0x59, 0x98, 0x1A, 0xD0, 0xA1, 0xDB,
+ 0xE9, 0xAE, 0xDB, 0xEB, 0x2E, 0x26, 0xC4, 0xAE, 0x27, 0xBD, 0x87, 0x58, 0x40, 0xED, 0x0E, 0xE5,
+ 0xC4, 0x46, 0x71, 0xB1, 0x2E, 0x2F, 0xDC, 0x11, 0x4E, 0xA5, 0x30, 0x51, 0x62, 0xFE, 0xC6, 0x42,
+ 0x00, 0x8B, 0x6D, 0xCB, 0x9D, 0xEB, 0x4C, 0xD6, 0x15, 0xEC, 0x4C, 0x85, 0xC8, 0xBA, 0x32, 0x81,
+ 0x76, 0xE5, 0x7A, 0xB3, 0xD5, 0x76, 0xEC, 0x46, 0xBD, 0x9D, 0x99, 0x84, 0xF5, 0x56, 0x83, 0x66,
+ 0xB0, 0x34, 0x77, 0x3F, 0x73, 0x6C, 0xB8, 0x5F, 0x65, 0xC5, 0x90, 0xE4, 0x04, 0x53, 0x3E, 0x89,
+ 0xD7, 0x0D, 0xA3, 0x46, 0x12, 0x18, 0x18, 0x48, 0x52, 0xC4, 0xB2, 0x59, 0xC3, 0xEF, 0xD0, 0x56,
+ 0xC0, 0x0E, 0x4A, 0x94, 0x22, 0xA5, 0x03, 0x2C, 0x17, 0xD1, 0xE6, 0x74, 0x8D, 0x62, 0x1C, 0x41,
+ 0xB6, 0x15, 0xD5, 0x46, 0x58, 0x7E, 0x50, 0x22, 0x67, 0xA6, 0x38, 0x53, 0x33, 0xF5, 0x89, 0xA2,
+ 0x4F, 0x88, 0xF1, 0xBA, 0x42, 0x8A, 0x92, 0xC6, 0x48, 0x7A, 0xD4, 0xE2, 0x39, 0x32, 0x98, 0x4B,
+ 0x8B, 0x71, 0x22, 0x9D, 0x0D, 0xA1, 0x78, 0xD1, 0x2F, 0x38, 0x1C, 0x27, 0x50, 0x56, 0xCC, 0xB5,
+ 0x3F, 0xAA, 0x98, 0x8D, 0xF3, 0xF0, 0xDF, 0x81, 0x00, 0x76, 0xF6, 0x53, 0x14, 0x09, 0x09, 0x60,
+ 0x09, 0x3C, 0x43, 0x08, 0x00, 0xD2, 0x18, 0x02, 0x70, 0x88, 0x80, 0x88, 0x65, 0x48, 0x82, 0xE0,
+ 0xD8, 0x71, 0x02, 0x41, 0x48, 0x6D, 0x84, 0x64, 0x9E, 0xFA, 0x57, 0xBF, 0xE7, 0x3E, 0x46, 0xB0,
+ 0x90, 0xA5, 0xE1, 0xE8, 0x00, 0x11, 0xE0, 0xA9, 0x10, 0x29, 0xAC, 0xD5, 0x92, 0x56, 0xB2, 0x99,
+ 0x6C, 0x36, 0x9A, 0x0D, 0xAB, 0x81, 0xF2, 0x5F, 0x3D, 0xF4, 0x55, 0xF7, 0xE1, 0x3D, 0xB9, 0xAB,
+ 0xB6, 0xFA, 0x19, 0xF0, 0x03, 0xF0, 0xA7, 0xC0, 0x04, 0xD1, 0x3E, 0x6F, 0x88, 0x1C, 0xAD, 0x76,
+ 0x56, 0xA8, 0xEE, 0x06, 0x6A, 0xF7, 0x66, 0xD4, 0xC2, 0x34, 0xDB, 0x56, 0xC8, 0xAC, 0xAB, 0xC9,
+ 0xAA, 0xDE, 0x34, 0xB9, 0x6C, 0xFD, 0x05, 0x95, 0x0E, 0x4B, 0x2D, 0x4D, 0x08, 0x56, 0x75, 0xD9,
+ 0xA8, 0xF8, 0xF5, 0x59, 0x41, 0x22, 0x35, 0x36, 0xA5, 0x09, 0x11, 0x2B, 0x94, 0x11, 0x05, 0x2D,
+ 0x2A, 0x09, 0xCD, 0xA4, 0xE3, 0x8E, 0x2E, 0x04, 0x7E, 0x03, 0xDF, 0x08, 0xEF, 0x01, 0x1A, 0xE8,
+ 0xF4, 0x7D, 0x02, 0xD0, 0x54, 0x00, 0x44, 0x4E, 0xE0, 0xB9, 0xC7, 0x44, 0x4D, 0x55, 0x26, 0x69,
+ 0xB1, 0xB7, 0x42, 0xF7, 0xD7, 0xEE, 0xA9, 0xBA, 0x4B, 0x8E, 0x0F, 0xE0, 0xAD, 0x75, 0xD7, 0x15,
+ 0x36, 0xB8, 0x07, 0xBA, 0xE0, 0x0A, 0x1A, 0x6F, 0x0D, 0x21, 0x06, 0x25, 0xF8, 0xFE, 0x8D, 0x1E,
+ 0x84, 0x6F, 0x34, 0xF9, 0x06, 0x62, 0xA9, 0x50, 0x27, 0xB7, 0xB0, 0xE7, 0xB8, 0x93, 0xDF, 0x39,
+ 0xD2, 0x84, 0xB7, 0xFA, 0xA4, 0x09, 0x24, 0x70, 0x34, 0x09, 0xEF, 0xE6, 0x49, 0x8C, 0x5D, 0xF1,
+ 0xDD, 0x8B, 0x18, 0x83, 0xFE, 0x10, 0x8F, 0x51, 0x02, 0x85, 0xBE, 0x22, 0x60, 0xE3, 0x0A, 0xD1,
+ 0x42, 0x67, 0x05, 0x12, 0x2C, 0xA4, 0x2F, 0x07, 0x9D, 0xC0, 0x25, 0x31, 0x7C, 0x33, 0x19, 0x43,
+ 0xBE, 0xF6, 0x06, 0x84, 0xF9, 0xC3, 0x0D, 0xB0, 0xB2, 0xB9, 0x11, 0x49, 0x42, 0xC0, 0xAC, 0xBE,
+ 0x80, 0x76, 0x60, 0xAA, 0xD7, 0x81, 0xDD, 0xA7, 0x45, 0x6C, 0xA3, 0x8B, 0x33, 0x58, 0x86, 0x0E,
+ 0x59, 0xCD, 0x10, 0x3D, 0xE8, 0x88, 0x39, 0x0D, 0x77, 0x3C, 0xD9, 0xF6, 0x08, 0x0C, 0xED, 0xF0,
+ 0x27, 0x13, 0x57, 0xBF, 0xFD, 0x70, 0x44, 0x31, 0x9C, 0xAC, 0x79, 0xEC, 0x83, 0x6F, 0xDB, 0x66,
+ 0x65, 0xD1, 0x97, 0xD3, 0xD5, 0xF2, 0x03, 0xFF, 0xF4, 0xDA, 0x8A, 0x13, 0x66, 0x98, 0x57, 0xFF,
+ 0xE4, 0xFB, 0x67, 0x69, 0xC6, 0xED, 0xB7, 0xB5, 0xFA, 0x2C, 0xFC, 0x2D, 0x5A, 0x04, 0x35, 0x90,
+ 0xEB, 0x2B, 0x69, 0x53, 0xE1, 0xD3, 0xC1, 0x32, 0x1D, 0x45, 0xA8, 0x34, 0x4B, 0xCF, 0xB9, 0x48,
+ 0x07, 0x77, 0x58, 0xBD, 0x30, 0x14, 0xC6, 0xF8, 0x6E, 0x23, 0xAE, 0x9E, 0x74, 0x19, 0x1B, 0x2B,
+ 0x44, 0x17, 0xB4, 0xB8, 0xA2, 0xD5, 0x93, 0x2B, 0x64, 0xA3, 0x3E, 0x85, 0xDF, 0x57, 0x88, 0x24,
+ 0x96, 0xC9, 0xED, 0x01, 0x68, 0x81, 0xDF, 0x0F, 0x8F, 0x7F, 0x70, 0xA9, 0x73, 0xDC, 0x3F, 0x5E,
+ 0xAB, 0xE8, 0x94, 0x22, 0xB2, 0x08, 0xA9, 0xB9, 0x76, 0x28, 0x97, 0xE1, 0x47, 0xA7, 0xF7, 0x06,
+ 0x14, 0x96, 0x56, 0x94, 0xE2, 0xB8, 0x8F, 0xE6, 0xC7, 0x17, 0xE1, 0x67, 0xFA, 0xA3, 0xCD, 0x9B,
+ 0xFF, 0xDB, 0x6D, 0xFB, 0x12, 0xAD, 0x03, 0x59, 0x8B, 0xD6, 0xFD, 0x66, 0x22, 0xC0, 0xE8, 0x91,
+ 0xE2, 0x64, 0xBA, 0xDE, 0xC8, 0xD6, 0x4E, 0x76, 0xC3, 0x14, 0x4B, 0x29, 0x6C, 0x38, 0x00, 0xC5,
+ 0x69, 0xDC, 0x67, 0x76, 0xF5, 0x79, 0xF0, 0x13, 0xB4, 0x00, 0xFC, 0xA0, 0xD4, 0xD7, 0x6C, 0x0C,
+ 0x56, 0x11, 0x44, 0x7E, 0x9F, 0x43, 0x00, 0x63, 0x01, 0x2E, 0xBA, 0x4B, 0xEC, 0xEB, 0xC1, 0x01,
+ 0x38, 0x03, 0x5E, 0xCF, 0x71, 0xBF, 0x03, 0x82, 0x3B, 0xDB, 0x93, 0x58, 0x93, 0x63, 0x15, 0xC2,
+ 0x64, 0x7B, 0x70, 0x0A, 0x77, 0xD8, 0xB6, 0x30, 0x72, 0xFA, 0xC9, 0x2B, 0x08, 0xDE, 0x51, 0x05,
+ 0x5E, 0x95, 0x74, 0xC1, 0x48, 0x8D, 0x84, 0x78, 0xD5, 0x42, 0x68, 0xE9, 0xAA, 0xDA, 0x77, 0x9A,
+ 0xDD, 0xB1, 0x18, 0xA3, 0x89, 0x32, 0xA7, 0xF8, 0x63, 0x92, 0xDF, 0xDA, 0xF3, 0xF6, 0xBF, 0x77,
+ 0xE7, 0x4B, 0x5B, 0xFD, 0x35, 0xFC, 0x30, 0xDA, 0x8A, 0x79, 0x69, 0xB2, 0x1F, 0x28, 0x65, 0xC3,
+ 0x1A, 0x08, 0x39, 0x2C, 0xE4, 0xB8, 0x12, 0x05, 0xB6, 0xD6, 0xAA, 0x95, 0xF2, 0x12, 0x05, 0xE3,
+ 0xDB, 0xD0, 0xC3, 0xEE, 0xFA, 0xF4, 0x3C, 0x22, 0x1B, 0x90, 0xD8, 0x65, 0x30, 0xB0, 0xC6, 0x61,
+ 0x86, 0xC1, 0xFA, 0xCA, 0x05, 0x15, 0x83, 0xBE, 0x60, 0xC4, 0xE1, 0x76, 0x8C, 0x56, 0x50, 0x76,
+ 0x0A, 0x43, 0x07, 0xDB, 0x71, 0x49, 0xDF, 0x05, 0x89, 0x3D, 0x04, 0x3F, 0xBC, 0x23, 0x92, 0xDF,
+ 0xBF, 0x57, 0xCB, 0x09, 0x7E, 0x95, 0xD1, 0x4A, 0xDD, 0x76, 0x8C, 0xF0, 0xDD, 0x8A, 0x25, 0x09,
+ 0xAD, 0x62, 0xF9, 0x6D, 0xDE, 0x52, 0x93, 0x23, 0xA6, 0xB5, 0x48, 0x15, 0x3A, 0x7B, 0xC6, 0x26,
+ 0x66, 0xFE, 0xE0, 0x48, 0x46, 0xA4, 0x68, 0x18, 0xD1, 0x28, 0xA3, 0x38, 0xBE, 0x34, 0x1F, 0xA3,
+ 0x68, 0xE9, 0x90, 0x4C, 0x40, 0x82, 0x30, 0x38, 0x75, 0x33, 0xCB, 0xF0, 0x13, 0x5B, 0x94, 0xF2,
+ 0xA6, 0xC5, 0x1B, 0x20, 0x26, 0x59, 0x08, 0x84, 0xD5, 0x2F, 0xC3, 0x5D, 0x78, 0x16, 0x47, 0x40,
+ 0xB1, 0xAF, 0xD6, 0xCA, 0xB9, 0xA8, 0xCF, 0x90, 0x98, 0x48, 0x50, 0x57, 0x93, 0x0B, 0xF4, 0x0E,
+ 0xB7, 0xFF, 0xE0, 0x4A, 0x99, 0x57, 0x8F, 0xBA, 0xF0, 0x95, 0x70, 0x21, 0x0D, 0x26, 0xB3, 0x01,
+ 0xBE, 0x71, 0x31, 0x51, 0xFB, 0x12, 0xD4, 0xD9, 0x80, 0x56, 0xB1, 0x5C, 0xB4, 0x4C, 0xB8, 0x85,
+ 0x8A, 0xD6, 0x3B, 0x0B, 0x51, 0x23, 0x91, 0x2B, 0x33, 0xE2, 0x49, 0x93, 0x95, 0x99, 0xF1, 0x80,
+ 0x69, 0xF5, 0x6D, 0x4B, 0xD7, 0xB4, 0x93, 0x42, 0xCC, 0xA4, 0x63, 0xE5, 0x74, 0xC6, 0x54, 0x55,
+ 0xFF, 0x91, 0x77, 0xF9, 0xAA, 0x95, 0x5C, 0x4E, 0xF3, 0x59, 0xE1, 0x9A, 0x19, 0x0C, 0xEE, 0xC8,
+ 0x21, 0x2B, 0xAA, 0x9A, 0x01, 0xAC, 0x1A, 0x18, 0x56, 0xDB, 0xC3, 0xF0, 0xA4, 0x5E, 0x8F, 0xA6,
+ 0xAA, 0xA6, 0x24, 0x71, 0xD5, 0xFD, 0xB6, 0xBB, 0x12, 0xFA, 0xEA, 0x33, 0x88, 0x41, 0x07, 0x31,
+ 0xE5, 0xDE, 0xD2, 0xAF, 0x57, 0x42, 0x96, 0x04, 0x6A, 0x15, 0x2D, 0x58, 0x2B, 0x53, 0x7B, 0x46,
+ 0x8A, 0x85, 0x8C, 0x5E, 0x2C, 0x4D, 0x1A, 0x7A, 0x27, 0x5B, 0xE6, 0x30, 0x32, 0x45, 0xBC, 0xAA,
+ 0x68, 0x88, 0x2F, 0xA3, 0x6A, 0x2D, 0xB8, 0x77, 0x45, 0xDA, 0x77, 0x16, 0x5A, 0x97, 0x34, 0x80,
+ 0xCF, 0xB5, 0x37, 0xAB, 0x03, 0x81, 0xB0, 0x8E, 0x47, 0x3C, 0xFC, 0x08, 0xAF, 0xC4, 0xEF, 0x23,
+ 0x58, 0xAD, 0x41, 0x17, 0x88, 0xE3, 0x95, 0x22, 0x68, 0xA6, 0x47, 0x30, 0xC9, 0x04, 0xE6, 0x01,
+ 0xA2, 0x8D, 0xA1, 0xA2, 0x87, 0x08, 0x31, 0x3A, 0x6F, 0x44, 0x31, 0x4B, 0x28, 0xD8, 0xE6, 0x14,
+ 0xFD, 0x92, 0xA6, 0x73, 0x16, 0xCD, 0x93, 0x81, 0x46, 0x0B, 0xC3, 0x69, 0xF8, 0xA0, 0xB5, 0xA2,
+ 0xE5, 0x8E, 0x6E, 0x2B, 0xFA, 0xCD, 0x92, 0xA4, 0xEA, 0xB4, 0x41, 0x69, 0xAC, 0x63, 0x06, 0xF2,
+ 0xE4, 0x83, 0xF8, 0xC3, 0xA4, 0x9E, 0x51, 0x1D, 0x1F, 0x5E, 0xAA, 0x9B, 0xB5, 0x78, 0xA8, 0x54,
+ 0x29, 0x14, 0x51, 0x47, 0xAF, 0xCC, 0xBE, 0x7A, 0x7F, 0xC2, 0xF1, 0x8D, 0xA9, 0x76, 0x98, 0x4F,
+ 0x70, 0x29, 0x5D, 0x32, 0x1C, 0x04, 0x5F, 0xB5, 0xEB, 0x6D, 0x13, 0xEE, 0xE8, 0xF9, 0xD5, 0x2F,
+ 0xC1, 0xF7, 0xE0, 0xD5, 0x2B, 0x81, 0x91, 0xBE, 0x1A, 0x0F, 0xF9, 0x14, 0x1E, 0x70, 0x80, 0xDA,
+ 0x5C, 0xC8, 0x2C, 0x38, 0x57, 0x0D, 0x58, 0x00, 0x4B, 0xE9, 0x3C, 0x3C, 0x8C, 0x07, 0x03, 0xD6,
+ 0x57, 0x11, 0x0F, 0xA1, 0x1C, 0x1F, 0x88, 0x0B, 0x8F, 0x7F, 0xB3, 0x8C, 0xE3, 0x2D, 0x16, 0xE1,
+ 0xD1, 0x1D, 0x16, 0xBB, 0x04, 0xE6, 0x67, 0x14, 0x81, 0x1D, 0xAC, 0xAD, 0xE0, 0x7B, 0x46, 0x05,
+ 0x3D, 0x1E, 0x96, 0x1B, 0xD9, 0x02, 0x93, 0x2A, 0x76, 0xBB, 0x6C, 0xA4, 0xD5, 0x4D, 0x27, 0x13,
+ 0xA6, 0x11, 0xBD, 0x7A, 0xBF, 0x14, 0x2B, 0x27, 0x4B, 0x0D, 0x45, 0xB1, 0x27, 0xCC, 0x40, 0xB3,
+ 0x84, 0xFA, 0xCB, 0x8A, 0xA5, 0xD3, 0x94, 0x9C, 0xD5, 0x9C, 0xD2, 0xA6, 0x86, 0x92, 0xAD, 0xB4,
+ 0x2B, 0x3E, 0xCB, 0x0C, 0x63, 0xB4, 0x3B, 0xB3, 0xD4, 0x64, 0x8D, 0xC0, 0xE8, 0xD2, 0xBE, 0x80,
+ 0x9F, 0xE2, 0x09, 0xB7, 0xDF, 0xCE, 0xEA, 0x0B, 0xF0, 0x73, 0x68, 0x1B, 0x18, 0x03, 0xF9, 0xBE,
+ 0x52, 0xF2, 0x89, 0x44, 0x2B, 0xB7, 0x3C, 0x6E, 0xD4, 0x63, 0xCE, 0x41, 0x66, 0xC6, 0x93, 0x37,
+ 0xE7, 0xBB, 0x97, 0x09, 0x9C, 0x71, 0x2C, 0xDE, 0xD2, 0xB6, 0xB9, 0x26, 0x71, 0x46, 0xDD, 0xE9,
+ 0xEE, 0x51, 0x8E, 0x8B, 0xC0, 0xAD, 0x10, 0x8C, 0x20, 0x57, 0xBD, 0xBA, 0x82, 0x07, 0xDB, 0x4D,
+ 0x55, 0xE8, 0xC1, 0x41, 0x1B, 0x7E, 0x06, 0xCD, 0x3F, 0x5A, 0x1E, 0x3B, 0x66, 0x2A, 0x9D, 0x05,
+ 0x4E, 0xE0, 0x66, 0x0C, 0xC2, 0x6F, 0xF0, 0x9A, 0xC1, 0x46, 0xEA, 0x23, 0xE6, 0x58, 0x44, 0xE2,
+ 0x65, 0xCD, 0x47, 0x08, 0x6C, 0x74, 0xC6, 0x9A, 0x92, 0x32, 0xA1, 0x91, 0xF6, 0x2F, 0x18, 0x89,
+ 0x19, 0xB9, 0x66, 0xF9, 0xE8, 0xB2, 0x46, 0xDB, 0xFB, 0xAE, 0x5B, 0xE2, 0x58, 0x6E, 0x5C, 0x45,
+ 0x6A, 0x88, 0x91, 0x15, 0x26, 0xDC, 0x3C, 0xD1, 0x10, 0xD4, 0x7D, 0x13, 0x3E, 0x92, 0x72, 0x6C,
+ 0xDE, 0x8C, 0xD9, 0x13, 0x3E, 0xA6, 0xCC, 0x38, 0x47, 0x3C, 0x19, 0xF4, 0x2C, 0x7C, 0x27, 0x1E,
+ 0x47, 0x0C, 0x6C, 0xEF, 0x87, 0xF8, 0x98, 0x13, 0x96, 0x41, 0x58, 0xA6, 0x48, 0x6C, 0x66, 0x4B,
+ 0xA2, 0x2C, 0x8B, 0xBA, 0x26, 0x5F, 0x1D, 0x38, 0xB8, 0x22, 0xCE, 0xAD, 0x69, 0x9C, 0x73, 0x20,
+ 0x8C, 0x11, 0x10, 0xA6, 0xB2, 0xA1, 0x41, 0x7C, 0xA5, 0x3D, 0xE2, 0x29, 0xA0, 0xB8, 0x33, 0xA0,
+ 0x2F, 0x42, 0x46, 0x96, 0x02, 0x8D, 0x36, 0xB6, 0x39, 0xAA, 0x30, 0xE1, 0x0E, 0x0C, 0x2F, 0x0A,
+ 0xB6, 0x28, 0xDA, 0xF0, 0x9D, 0xA2, 0xC8, 0x13, 0xF9, 0xC5, 0xA0, 0xC2, 0xED, 0xDC, 0xFC, 0xF1,
+ 0x54, 0xB0, 0x15, 0xD4, 0xA3, 0xA9, 0x92, 0xC5, 0x3B, 0xCE, 0x16, 0xBB, 0xBF, 0xC5, 0x19, 0x0D,
+ 0xA2, 0xB0, 0xAC, 0xAB, 0xF4, 0xAE, 0xD7, 0x4D, 0xD5, 0xC6, 0x63, 0xC5, 0x2C, 0x3C, 0xB5, 0x09,
+ 0x42, 0xC2, 0xB0, 0x04, 0xCB, 0x9E, 0xB7, 0xB0, 0xC2, 0xC1, 0x28, 0xDE, 0x58, 0xFD, 0x39, 0x7C,
+ 0x0A, 0xCB, 0xFB, 0x16, 0x58, 0x04, 0x9B, 0xFA, 0xC1, 0x54, 0x24, 0xE8, 0x88, 0x6C, 0x21, 0x59,
+ 0x40, 0xB5, 0xCE, 0x54, 0xBB, 0x9C, 0xAD, 0x21, 0x80, 0x46, 0x67, 0x0D, 0x16, 0x3A, 0xEB, 0xB6,
+ 0xAE, 0xCB, 0x1D, 0xE7, 0xAB, 0xE7, 0xF1, 0x08, 0x66, 0xE0, 0x35, 0x03, 0xD3, 0xF6, 0x32, 0x8A,
+ 0x5A, 0x72, 0x06, 0x2A, 0x81, 0x71, 0x79, 0x3E, 0xEA, 0x29, 0x07, 0x72, 0xA0, 0x1C, 0x5C, 0x98,
+ 0x9E, 0x19, 0xE8, 0x08, 0xC7, 0xB5, 0x8A, 0x6C, 0x67, 0x5D, 0xB7, 0xE3, 0x65, 0x22, 0x46, 0xF1,
+ 0xC0, 0x3C, 0x63, 0xC9, 0x1B, 0xDA, 0x14, 0x84, 0xEF, 0x84, 0x2C, 0xC6, 0x35, 0x85, 0x05, 0xA9,
+ 0x96, 0x5D, 0x58, 0x0A, 0x74, 0x42, 0x5C, 0xBB, 0xAD, 0x07, 0x97, 0xED, 0xEB, 0x82, 0x8A, 0x6F,
+ 0x93, 0xC2, 0x85, 0x96, 0xFD, 0x8A, 0xDC, 0xD4, 0x3B, 0x66, 0x44, 0x0A, 0xE5, 0x6E, 0x69, 0x34,
+ 0x78, 0x23, 0x22, 0x26, 0x23, 0x54, 0x55, 0xA7, 0x59, 0x8C, 0x88, 0x58, 0xDD, 0x32, 0x02, 0x18,
+ 0xA2, 0x33, 0x99, 0x42, 0xB0, 0x3B, 0x59, 0x51, 0x23, 0x4C, 0xBB, 0xA4, 0x4F, 0x05, 0x76, 0xF0,
+ 0xD5, 0x6E, 0xB8, 0xA0, 0x98, 0x93, 0x82, 0x58, 0x88, 0x8D, 0x54, 0x09, 0x23, 0x60, 0x95, 0x03,
+ 0x4C, 0x5D, 0xE5, 0x53, 0x17, 0x6F, 0x8D, 0x77, 0x55, 0x42, 0x8B, 0xE7, 0x98, 0x46, 0x92, 0xF5,
+ 0xF1, 0x2A, 0x5E, 0xD3, 0x00, 0x9E, 0x9B, 0xBF, 0xC6, 0xB2, 0xBD, 0x09, 0x32, 0x7D, 0xA9, 0x1A,
+ 0x8B, 0x48, 0x28, 0xC8, 0x66, 0xAD, 0xC6, 0x36, 0x91, 0x5D, 0xA3, 0xCC, 0x0D, 0x56, 0x49, 0xAB,
+ 0xBA, 0xA6, 0x09, 0x15, 0x3A, 0xDB, 0x23, 0x87, 0xCA, 0x0F, 0x9B, 0x1C, 0x9E, 0x89, 0x0E, 0xF1,
+ 0x43, 0x81, 0xF4, 0x9A, 0x92, 0x74, 0xA9, 0xF2, 0x2F, 0x68, 0x6D, 0x62, 0x22, 0xCA, 0xCD, 0x1A,
+ 0x84, 0xCF, 0xE4, 0x0D, 0x8D, 0xC3, 0xE4, 0xA8, 0x8F, 0xC5, 0x02, 0xBC, 0x11, 0xC0, 0xF0, 0x8B,
+ 0x0F, 0xCE, 0xD9, 0x3D, 0x31, 0x19, 0xAD, 0x4D, 0x50, 0x2E, 0xED, 0x1E, 0x85, 0xEF, 0x0F, 0xDA,
+ 0x81, 0x5D, 0xD7, 0x75, 0xC3, 0xEC, 0x84, 0x47, 0x8C, 0x8A, 0xCC, 0x44, 0x46, 0x4F, 0xD4, 0xAD,
+ 0x03, 0x53, 0x3E, 0xDE, 0x36, 0x78, 0x8A, 0x0B, 0x68, 0xF6, 0xB8, 0x9F, 0x2E, 0xB3, 0xF6, 0x91,
+ 0x2A, 0x5B, 0xBB, 0x76, 0xF9, 0x98, 0x6B, 0xA1, 0x75, 0x30, 0x06, 0x79, 0x01, 0xFE, 0x14, 0x63,
+ 0x90, 0x20, 0x98, 0xE8, 0x3B, 0x84, 0x5F, 0xC0, 0x40, 0xC4, 0x4F, 0x85, 0x4C, 0x1A, 0xC9, 0x40,
+ 0x38, 0xB4, 0xA2, 0x68, 0x57, 0xA2, 0x91, 0x81, 0x93, 0x6D, 0xE8, 0xAD, 0x70, 0x47, 0x15, 0xC2,
+ 0xA8, 0x64, 0xA3, 0xDF, 0x6B, 0xE3, 0xF9, 0x0B, 0x47, 0x28, 0x21, 0xE2, 0x21, 0x14, 0xCA, 0x69,
+ 0x1C, 0xE1, 0xA9, 0xE8, 0xF0, 0x1C, 0xDE, 0x3F, 0x83, 0xDA, 0x66, 0xD0, 0x83, 0x2B, 0x93, 0x17,
+ 0xFF, 0x68, 0x76, 0xFD, 0x8D, 0xEB, 0x05, 0x6B, 0x61, 0xEC, 0xF7, 0x2B, 0xAF, 0x4F, 0x09, 0xB0,
+ 0xD8, 0x0F, 0xC7, 0x1D, 0x13, 0xE3, 0x4D, 0x3A, 0x02, 0x68, 0x03, 0x3F, 0x53, 0x49, 0x80, 0x02,
+ 0x34, 0xEE, 0x99, 0xD1, 0x3D, 0xBB, 0xD6, 0xB3, 0x75, 0x91, 0x0C, 0xD6, 0x3D, 0x73, 0xEB, 0xE6,
+ 0x20, 0xEE, 0x60, 0xF2, 0xCA, 0x0E, 0x5E, 0x86, 0x18, 0x5D, 0x95, 0xF3, 0xB3, 0x0D, 0xDD, 0x8C,
+ 0xA9, 0x54, 0x44, 0x6C, 0xAB, 0xBC, 0x87, 0x1E, 0xCB, 0xC1, 0x68, 0xF3, 0xF2, 0xBE, 0x9E, 0xBA,
+ 0x1C, 0x4B, 0x46, 0x64, 0xBB, 0x98, 0xF0, 0x7B, 0x48, 0x79, 0xF5, 0xD7, 0x28, 0x8F, 0xB0, 0x51,
+ 0x01, 0x16, 0xFA, 0x3E, 0x8A, 0x44, 0x88, 0x20, 0x30, 0x8D, 0x21, 0xD7, 0x4F, 0x49, 0x61, 0x69,
+ 0x4D, 0x5C, 0xBF, 0x02, 0x1E, 0x3E, 0xBB, 0xA1, 0xAB, 0x2E, 0x53, 0x9F, 0xFB, 0xC2, 0xF6, 0x1F,
+ 0x3F, 0x28, 0xAC, 0xB9, 0xBC, 0x7E, 0x8B, 0xDF, 0xFA, 0xFF, 0x40, 0xF8, 0x3C, 0xEE, 0x32, 0x03,
+ 0xB1, 0x31, 0x96, 0x6E, 0xA6, 0x2D, 0x09, 0xA2, 0xFC, 0x45, 0x1A, 0xFE, 0xFB, 0xC5, 0x97, 0xC3,
+ 0x07, 0xD8, 0xEF, 0xED, 0xFC, 0xDE, 0x75, 0xEF, 0x7D, 0x2F, 0x9E, 0xA1, 0x2A, 0xB8, 0x1E, 0xA3,
+ 0xF2, 0xB7, 0x7A, 0x7E, 0xC2, 0xD1, 0xBE, 0xCD, 0xD0, 0xAE, 0x7F, 0x16, 0x83, 0x3E, 0xDA, 0x22,
+ 0x31, 0x3C, 0x43, 0x04, 0x3A, 0x42, 0x91, 0x47, 0x3D, 0x14, 0x3E, 0xF4, 0x87, 0x6E, 0x54, 0xC9,
+ 0x2C, 0xBE, 0x36, 0x8C, 0x37, 0xE3, 0x1A, 0x3E, 0x86, 0x17, 0xC7, 0x07, 0x1C, 0x3B, 0x74, 0xF1,
+ 0xCB, 0x87, 0xAE, 0x1C, 0x07, 0x41, 0xE2, 0x31, 0x50, 0x34, 0x72, 0xAF, 0x0E, 0x20, 0x1E, 0x10,
+ 0xA0, 0xAE, 0x5F, 0x81, 0x2F, 0x1E, 0xC7, 0xC4, 0xC7, 0x2E, 0x1B, 0xC7, 0xC4, 0xC7, 0x36, 0x8C,
+ 0x23, 0x4D, 0x35, 0xCB, 0xB0, 0x49, 0x79, 0xB7, 0x7A, 0x00, 0x8F, 0xE3, 0xDF, 0xFF, 0xD1, 0x1D,
+ 0xC5, 0x75, 0xDF, 0xC3, 0xE3, 0xB0, 0x30, 0xF7, 0x7C, 0x1B, 0xFD, 0x77, 0xBC, 0xCE, 0x75, 0x2C,
+ 0x59, 0xA2, 0x3E, 0xDE, 0x31, 0xAA, 0xC9, 0x02, 0x87, 0x1F, 0xC7, 0x1A, 0x55, 0xAA, 0x91, 0x44,
+ 0x05, 0x6C, 0x2E, 0x06, 0x6F, 0x48, 0x65, 0xD8, 0xB3, 0x6B, 0x9E, 0x34, 0xD7, 0xFC, 0x1A, 0xFA,
+ 0x6D, 0x36, 0x38, 0x62, 0x07, 0xD2, 0x05, 0xDF, 0xB0, 0xE1, 0x5B, 0x67, 0x31, 0x22, 0xEB, 0xDA,
+ 0xFA, 0x4D, 0xCF, 0x11, 0x83, 0xF1, 0xB9, 0xE7, 0x53, 0xB1, 0x1B, 0x11, 0x82, 0x60, 0x86, 0x3C,
+ 0x86, 0x69, 0x21, 0x02, 0xE1, 0x37, 0xD1, 0xE8, 0xA6, 0xF1, 0x71, 0x49, 0x76, 0xD2, 0x59, 0x27,
+ 0xDD, 0xDF, 0x11, 0xD3, 0xAD, 0xBA, 0x2D, 0xDD, 0x9A, 0xEF, 0x68, 0x36, 0x9D, 0xC8, 0xCD, 0xD6,
+ 0xDE, 0x73, 0x8C, 0xA7, 0xE4, 0x60, 0xC8, 0x03, 0xD9, 0x7C, 0x16, 0x85, 0x45, 0xAB, 0xBA, 0x77,
+ 0x53, 0xB9, 0xC0, 0xF2, 0xA1, 0x50, 0x39, 0xD2, 0x1C, 0x6B, 0xEE, 0xF5, 0x21, 0x9E, 0x35, 0x0F,
+ 0xC4, 0x49, 0x5A, 0xAE, 0xCC, 0x5F, 0x78, 0x6E, 0x16, 0xC9, 0xF9, 0x21, 0xAD, 0x84, 0x2B, 0x78,
+ 0x84, 0xE1, 0xD5, 0x5F, 0x62, 0x3A, 0xF8, 0x0E, 0x18, 0x05, 0x7D, 0x70, 0xAC, 0x5F, 0xC9, 0x3B,
+ 0xB4, 0x1E, 0xC5, 0xFA, 0x30, 0x77, 0x72, 0x7A, 0xEC, 0x16, 0xFF, 0xCD, 0x1C, 0x11, 0x5D, 0xAE,
+ 0xA7, 0x97, 0x4B, 0x53, 0x37, 0xD1, 0xCD, 0x8E, 0x19, 0xEA, 0x20, 0x31, 0x81, 0xAA, 0x21, 0x04,
+ 0xEA, 0xB7, 0x97, 0x4E, 0xC3, 0xEA, 0x25, 0x71, 0x7A, 0xC1, 0xFD, 0xF7, 0x80, 0x06, 0x7E, 0xC1,
+ 0xFF, 0x78, 0xDE, 0xCF, 0x01, 0x05, 0x1E, 0x72, 0x9D, 0x56, 0xD8, 0x0C, 0x55, 0xCF, 0x0F, 0x29,
+ 0x7D, 0xDA, 0x15, 0x30, 0xA6, 0x47, 0xE9, 0xAE, 0xEE, 0x73, 0xDD, 0x82, 0x2E, 0x32, 0x6C, 0x37,
+ 0x08, 0x2C, 0x61, 0xD6, 0xDC, 0x4B, 0x1E, 0xE2, 0xC0, 0xD2, 0xB3, 0xB1, 0xE1, 0x2B, 0xD4, 0x86,
+ 0x0F, 0x08, 0xE2, 0xCF, 0x0F, 0xF8, 0x62, 0xF6, 0x78, 0x68, 0x6A, 0xF9, 0xBE, 0xFD, 0x99, 0x31,
+ 0x53, 0xD9, 0x31, 0x49, 0xFB, 0xAB, 0x9B, 0xFF, 0xF0, 0x81, 0x57, 0xBC, 0xF3, 0x7D, 0xAF, 0x59,
+ 0xBA, 0x23, 0xBB, 0xAB, 0xFE, 0xCE, 0x13, 0xEF, 0xFF, 0xFE, 0xF7, 0x9E, 0x7C, 0xCB, 0x57, 0x2F,
+ 0xFE, 0x28, 0x17, 0x1F, 0x5D, 0x28, 0xA4, 0xEA, 0xB3, 0xF0, 0x93, 0x6F, 0x78, 0x6B, 0x28, 0xE4,
+ 0x8B, 0x1D, 0x99, 0x3F, 0xFE, 0xC6, 0x68, 0xAA, 0x75, 0x71, 0xD5, 0x56, 0x83, 0x37, 0x6E, 0xBB,
+ 0xF3, 0xE5, 0xEF, 0x7B, 0xE8, 0x91, 0x77, 0x16, 0x73, 0xDB, 0xF7, 0xFC, 0xC3, 0xBB, 0xFE, 0xF8,
+ 0x1F, 0xDF, 0xF6, 0x97, 0xE9, 0x91, 0x83, 0x13, 0xD9, 0xD1, 0xC3, 0x58, 0xEE, 0xAC, 0xFE, 0x04,
+ 0xDB, 0x27, 0x2F, 0xA0, 0x7F, 0x00, 0x65, 0x8C, 0x25, 0xFB, 0x7D, 0xBB, 0x56, 0x31, 0x40, 0x95,
+ 0x38, 0x5C, 0xAF, 0xDC, 0xC5, 0xD5, 0xEE, 0x1C, 0x31, 0x79, 0x36, 0xF6, 0x5F, 0x8D, 0x99, 0x75,
+ 0x4C, 0xC2, 0xC1, 0x48, 0xAF, 0xEB, 0x0E, 0xB9, 0x80, 0x4F, 0xBC, 0x09, 0xB8, 0xA4, 0xEC, 0xEB,
+ 0x86, 0xE7, 0x1F, 0xCD, 0x62, 0x95, 0x47, 0x78, 0x88, 0xCA, 0xB5, 0xC5, 0xA6, 0xC8, 0x1E, 0xC2,
+ 0x10, 0xAB, 0x85, 0x25, 0x6A, 0x84, 0x8E, 0xC2, 0x74, 0x96, 0x70, 0xD0, 0x0B, 0xE9, 0x7D, 0x96,
+ 0x3F, 0x16, 0x0B, 0xD9, 0x6F, 0x79, 0x0D, 0x4D, 0xD2, 0x88, 0x3A, 0x29, 0x15, 0x34, 0x2D, 0xD3,
+ 0x1D, 0xED, 0xC9, 0x51, 0x83, 0x89, 0x26, 0x62, 0x1A, 0xEB, 0xA3, 0x05, 0x42, 0x1A, 0x5F, 0x72,
+ 0x4A, 0x35, 0x2D, 0x74, 0xF1, 0xAF, 0x6F, 0x39, 0x71, 0x70, 0x5B, 0x78, 0x02, 0xE5, 0x9A, 0x95,
+ 0x3C, 0x82, 0x58, 0x82, 0x2A, 0x85, 0x1A, 0x2D, 0xD3, 0xFE, 0xA9, 0xC7, 0xEF, 0x7E, 0x75, 0xF5,
+ 0xC0, 0x38, 0x21, 0x9B, 0x2A, 0x4B, 0xF2, 0x5A, 0x46, 0xC8, 0x3E, 0xFE, 0xA1, 0xCA, 0xAE, 0x05,
+ 0x82, 0xFA, 0xD0, 0xEA, 0x2A, 0x5E, 0x6F, 0xB4, 0x7A, 0x7E, 0xF5, 0x37, 0xE8, 0x10, 0xFA, 0x6B,
+ 0x90, 0x03, 0x9B, 0xC1, 0x74, 0x3F, 0xB4, 0xA9, 0x9A, 0x74, 0x34, 0xE4, 0x58, 0xB3, 0xC9, 0x2D,
+ 0x9D, 0xA9, 0x60, 0x13, 0xC5, 0xA6, 0x3A, 0xC8, 0x08, 0xBE, 0x4C, 0x78, 0x78, 0xA3, 0xBA, 0x74,
+ 0xDD, 0x58, 0x60, 0x30, 0xAE, 0x0D, 0x5A, 0x72, 0xCB, 0x50, 0x4B, 0xD2, 0x0C, 0x06, 0xF9, 0x1E,
+ 0xCD, 0x56, 0x11, 0x5E, 0x42, 0xD7, 0xE1, 0xBF, 0x86, 0x99, 0xB1, 0xF6, 0xC4, 0x6A, 0x9E, 0xA9,
+ 0xA0, 0x2A, 0xC2, 0x36, 0x01, 0xF2, 0xF4, 0x89, 0xA9, 0x5B, 0xAE, 0x31, 0xD0, 0xA8, 0x37, 0xDC,
+ 0x06, 0xB4, 0x42, 0xA4, 0x47, 0x04, 0x25, 0x18, 0x3C, 0xD4, 0x13, 0xC2, 0x93, 0x9B, 0x74, 0x49,
+ 0xE3, 0x67, 0x26, 0xEF, 0x0F, 0x4F, 0x07, 0x6F, 0xB9, 0x7B, 0x5F, 0xA9, 0x29, 0x63, 0x50, 0x6D,
+ 0x05, 0x5E, 0x6D, 0x54, 0xC2, 0x01, 0xBF, 0x00, 0xD5, 0x7C, 0x4E, 0xAF, 0xC6, 0xD2, 0x85, 0x18,
+ 0x32, 0xA4, 0xF8, 0xAC, 0x46, 0xD3, 0x6C, 0x32, 0x0F, 0x73, 0x9A, 0x12, 0xEF, 0x96, 0x45, 0xC1,
+ 0x30, 0x17, 0x09, 0xC6, 0xA2, 0xA8, 0xC7, 0x6E, 0xFD, 0xE1, 0x76, 0x82, 0xBE, 0x93, 0xE6, 0x95,
+ 0xEA, 0x4C, 0xAA, 0x53, 0x11, 0x25, 0x59, 0x31, 0x2B, 0x53, 0xB1, 0xB8, 0xCC, 0xD0, 0x84, 0x41,
+ 0x8A, 0x99, 0x9C, 0x51, 0x0D, 0x2B, 0x12, 0xB5, 0xF5, 0xE2, 0xD7, 0xB7, 0x70, 0x48, 0xE0, 0x11,
+ 0x55, 0x4F, 0x46, 0x5D, 0xF9, 0x18, 0x5C, 0xFD, 0x25, 0xEA, 0xA2, 0x2F, 0x62, 0x4E, 0x2F, 0xF5,
+ 0xF5, 0x62, 0x58, 0x01, 0x99, 0x7A, 0xB9, 0x51, 0xBB, 0xBF, 0x91, 0xBC, 0xD7, 0xEF, 0x7F, 0x80,
+ 0x3E, 0xED, 0x5A, 0x0F, 0xEA, 0x15, 0x6B, 0xDB, 0x50, 0xF0, 0xDA, 0xBA, 0x6E, 0x12, 0x3C, 0xF8,
+ 0xA4, 0xEB, 0xC4, 0x73, 0x2D, 0x55, 0xB2, 0xE1, 0xF9, 0xEE, 0x3C, 0xE8, 0x30, 0x60, 0x6D, 0x73,
+ 0xE0, 0x3C, 0x6D, 0xA3, 0x6E, 0xAC, 0xDE, 0xCE, 0x58, 0x58, 0x1C, 0x72, 0x3B, 0x5F, 0xDE, 0x71,
+ 0x24, 0x3B, 0xC1, 0x09, 0x76, 0xF9, 0xE0, 0x1F, 0x8C, 0x96, 0xEB, 0x61, 0x51, 0xAA, 0xEA, 0x21,
+ 0x63, 0x6F, 0x7A, 0x6C, 0x2B, 0xC7, 0xF4, 0xFF, 0xAA, 0x99, 0xCD, 0xDF, 0xE8, 0xCF, 0x25, 0x14,
+ 0x02, 0x31, 0xFB, 0x8E, 0x4E, 0x4C, 0x65, 0x72, 0x5B, 0x27, 0x54, 0x31, 0x9C, 0xED, 0x16, 0x94,
+ 0x90, 0x80, 0xD1, 0x52, 0x56, 0x32, 0xC2, 0xC9, 0xED, 0xDB, 0x54, 0xD2, 0x1A, 0xFB, 0xF4, 0xA2,
+ 0xE0, 0xAD, 0xE9, 0xAF, 0xD0, 0x87, 0xD0, 0x5F, 0x61, 0x39, 0x35, 0x06, 0xB6, 0xF5, 0x13, 0x96,
+ 0xA5, 0xB5, 0x26, 0xC7, 0x8B, 0x95, 0x07, 0x43, 0xB6, 0xA8, 0xD4, 0x6B, 0x23, 0x95, 0x6A, 0x05,
+ 0x69, 0xAA, 0x92, 0x41, 0xC0, 0x1F, 0x7A, 0x39, 0xF7, 0xF0, 0x9A, 0xA5, 0x30, 0xF4, 0x59, 0x76,
+ 0x5D, 0xDB, 0xE0, 0xFC, 0xC0, 0x5F, 0xE4, 0x49, 0x63, 0x6F, 0x91, 0x5D, 0x9C, 0x6A, 0x79, 0xDC,
+ 0xCA, 0xB8, 0xD8, 0xA7, 0x0A, 0x47, 0xF5, 0x26, 0x06, 0x6E, 0xF4, 0x60, 0x71, 0x27, 0x60, 0xBB,
+ 0x1E, 0x21, 0x19, 0x0F, 0x21, 0xA0, 0x64, 0x26, 0x91, 0xB4, 0xF0, 0x3A, 0xBB, 0x0E, 0x62, 0xF4,
+ 0x21, 0x25, 0xAC, 0x4E, 0x14, 0xAE, 0xDB, 0x53, 0xAD, 0x1E, 0x6F, 0x0A, 0x10, 0xC6, 0x6A, 0x81,
+ 0xFC, 0xAB, 0x04, 0x43, 0x0D, 0x34, 0xFC, 0x8B, 0xAF, 0x3E, 0x39, 0x99, 0xB1, 0x1F, 0x86, 0xB0,
+ 0xFF, 0x67, 0x8E, 0xC1, 0x5A, 0x34, 0x01, 0x61, 0x65, 0x8F, 0x9F, 0x9E, 0x9F, 0x86, 0x77, 0x95,
+ 0xEB, 0x8D, 0x58, 0x2F, 0x35, 0x97, 0xF5, 0xCB, 0x93, 0x70, 0x7E, 0xAA, 0x57, 0x43, 0x24, 0xFB,
+ 0x00, 0x22, 0x60, 0x60, 0x7C, 0xBE, 0xB3, 0xED, 0x3D, 0xBC, 0x4A, 0x8D, 0x7C, 0x0E, 0xCB, 0xE7,
+ 0xC7, 0x9E, 0xE8, 0x1C, 0x09, 0xB2, 0xB0, 0x0F, 0xE0, 0xEA, 0x4F, 0x31, 0x8B, 0x1E, 0x42, 0x9F,
+ 0x07, 0xE3, 0xE0, 0xC9, 0xFE, 0x8E, 0xE6, 0x68, 0x23, 0x1F, 0xB3, 0x34, 0x1E, 0xB0, 0x46, 0xA6,
+ 0x2A, 0x8E, 0x51, 0xD5, 0xB4, 0xC1, 0xA6, 0x0D, 0x7F, 0xDA, 0x68, 0x6A, 0xE0, 0x15, 0x13, 0xE9,
+ 0x87, 0x42, 0x95, 0xB2, 0xF6, 0x60, 0x26, 0x55, 0x56, 0xCB, 0x99, 0x4A, 0xF5, 0xB1, 0xCC, 0xF8,
+ 0xD8, 0x63, 0x94, 0x65, 0x3E, 0x12, 0xF5, 0x27, 0x42, 0xC8, 0xA8, 0x65, 0xD2, 0xC8, 0x54, 0x15,
+ 0x91, 0x34, 0x62, 0x4F, 0xF0, 0x14, 0x09, 0x2F, 0x85, 0xD3, 0xBA, 0x6B, 0xF6, 0x36, 0x9E, 0x8F,
+ 0xA1, 0xF5, 0x54, 0x1D, 0x38, 0xE0, 0x43, 0x70, 0xA7, 0xE7, 0x8C, 0xEF, 0x7A, 0xE4, 0x70, 0x7E,
+ 0x83, 0x42, 0xDF, 0xA8, 0xD7, 0xD7, 0xB9, 0x64, 0x42, 0x1B, 0x04, 0x48, 0x5C, 0x11, 0x80, 0x59,
+ 0xA3, 0x07, 0x47, 0x5B, 0x93, 0x90, 0x69, 0xB5, 0xB3, 0xCC, 0xC0, 0x1F, 0x84, 0x27, 0xAD, 0xD1,
+ 0xC6, 0xD4, 0x92, 0x64, 0x1C, 0x2C, 0xF4, 0x64, 0x84, 0xE1, 0xB1, 0x83, 0x61, 0x25, 0x63, 0xB9,
+ 0xED, 0xE8, 0x90, 0x95, 0x8B, 0xF8, 0x26, 0x8E, 0xDC, 0x37, 0x6E, 0x85, 0x11, 0x24, 0x1F, 0xDD,
+ 0x34, 0x01, 0x1F, 0x2A, 0x66, 0xE2, 0x76, 0xE4, 0x20, 0x9D, 0xF9, 0x1B, 0x67, 0xAB, 0xBE, 0x67,
+ 0xE4, 0xE0, 0x0A, 0x9C, 0x79, 0x78, 0x46, 0x9F, 0x99, 0xDF, 0x12, 0xA5, 0x5D, 0x0F, 0xD7, 0xE8,
+ 0x93, 0xE2, 0xEC, 0x7D, 0x81, 0x72, 0xD4, 0x76, 0xCD, 0x33, 0x54, 0x4C, 0x86, 0xDE, 0xA0, 0xA7,
+ 0x51, 0x75, 0xE6, 0x23, 0x30, 0x82, 0x61, 0x31, 0x81, 0x48, 0x5A, 0xDF, 0xEF, 0x27, 0xDF, 0x88,
+ 0x60, 0x70, 0x31, 0x80, 0x60, 0x3E, 0x33, 0x17, 0xA3, 0x39, 0x0C, 0x02, 0xDC, 0x39, 0x5D, 0x7D,
+ 0x16, 0x2D, 0xA1, 0xAF, 0x80, 0x06, 0xB8, 0xBF, 0x3F, 0x56, 0xCC, 0x06, 0x35, 0x50, 0xCC, 0x67,
+ 0x93, 0xB1, 0x68, 0x32, 0x29, 0xD9, 0x29, 0xC9, 0x2E, 0x89, 0x29, 0xC7, 0x7E, 0x85, 0x2C, 0xD1,
+ 0xAF, 0x28, 0xD5, 0x5F, 0xC6, 0xB1, 0xCC, 0x43, 0x3E, 0x14, 0x76, 0x24, 0x11, 0x45, 0x23, 0xE1,
+ 0x10, 0x99, 0x02, 0x6F, 0x0A, 0xCE, 0x9D, 0x85, 0xC5, 0x35, 0x15, 0xE8, 0xDB, 0x30, 0x79, 0xE7,
+ 0x40, 0x15, 0xCE, 0xBA, 0x56, 0x02, 0x9E, 0x45, 0x17, 0x9C, 0xC1, 0x4B, 0x33, 0xE5, 0xB9, 0xA9,
+ 0x36, 0x1A, 0xA3, 0xA3, 0xC5, 0xA1, 0xB7, 0x2A, 0xE9, 0x3E, 0x85, 0x3D, 0x10, 0xED, 0x19, 0x76,
+ 0x0C, 0x06, 0xDB, 0x4C, 0x0F, 0x7A, 0x14, 0x98, 0x6C, 0x8F, 0x66, 0x9A, 0x5E, 0x68, 0x71, 0x38,
+ 0x79, 0x68, 0x69, 0x06, 0x43, 0xCE, 0x74, 0xE4, 0xA0, 0x93, 0x81, 0xE8, 0x40, 0xA5, 0xBF, 0xB5,
+ 0x25, 0xE7, 0x6A, 0xD7, 0x3A, 0x4C, 0xBA, 0xD1, 0x86, 0x10, 0x86, 0xD5, 0xBE, 0x7A, 0x3F, 0xE5,
+ 0xF7, 0xA7, 0xD3, 0x8F, 0x85, 0xAA, 0x89, 0xCC, 0x87, 0xD2, 0x5B, 0xD1, 0x57, 0x7A, 0x01, 0x41,
+ 0x57, 0xF0, 0x6A, 0x73, 0xC5, 0xD8, 0x34, 0xCD, 0x4E, 0x28, 0x15, 0x03, 0xFE, 0x4F, 0x27, 0x9A,
+ 0x3F, 0x10, 0xB8, 0x7F, 0x05, 0xA1, 0xE3, 0xB9, 0xFB, 0x78, 0x08, 0xEF, 0x26, 0x11, 0x45, 0xBB,
+ 0x72, 0x21, 0x8C, 0xF1, 0xC6, 0xDB, 0xD1, 0x97, 0x41, 0x0F, 0x94, 0xFB, 0xFA, 0x78, 0x23, 0x84,
+ 0xA6, 0x6A, 0x66, 0x3F, 0xF6, 0x66, 0x5F, 0x0E, 0xA9, 0xBE, 0x96, 0xF8, 0xF0, 0xBA, 0x43, 0x69,
+ 0xA3, 0x60, 0xE8, 0xAB, 0x43, 0x2D, 0x4F, 0x0C, 0x05, 0x63, 0x76, 0x74, 0x8A, 0x6A, 0x78, 0x02,
+ 0x11, 0xB9, 0x4E, 0x11, 0xCF, 0xA5, 0x4F, 0x79, 0x0A, 0xCF, 0x33, 0xF2, 0xDA, 0xAE, 0x87, 0x04,
+ 0xBD, 0x85, 0xAA, 0xC7, 0x5A, 0x96, 0x5F, 0xD7, 0xA6, 0xA7, 0x6E, 0xB9, 0x67, 0x82, 0x2D, 0xEE,
+ 0xDB, 0xB4, 0x75, 0x77, 0x53, 0x6B, 0xE4, 0xA3, 0xDA, 0x9E, 0x00, 0x1B, 0x6E, 0x95, 0xAA, 0x8B,
+ 0x41, 0x5A, 0x43, 0xCD, 0x87, 0xC7, 0x84, 0x6C, 0x95, 0x60, 0x7C, 0xDB, 0x84, 0x30, 0x63, 0x37,
+ 0x33, 0x9B, 0xE1, 0xBC, 0xAD, 0x56, 0x76, 0x64, 0xAB, 0x8A, 0x2C, 0x70, 0xC9, 0xC7, 0x8F, 0xEC,
+ 0xBE, 0xEA, 0xDE, 0x03, 0x95, 0xBC, 0x4A, 0x51, 0x9C, 0xA3, 0x69, 0x62, 0x53, 0xE1, 0xFD, 0xC9,
+ 0xCE, 0x72, 0xD9, 0x37, 0xD2, 0x67, 0xEE, 0xDE, 0xCE, 0x8E, 0x14, 0x25, 0xCD, 0x37, 0x1F, 0x20,
+ 0x1C, 0x46, 0x4D, 0xE1, 0xB1, 0x2D, 0xAC, 0x3E, 0x47, 0x70, 0xE8, 0x5B, 0x60, 0x19, 0xFC, 0x97,
+ 0xFE, 0x72, 0xAB, 0x91, 0x53, 0xC0, 0xF2, 0x44, 0x16, 0x4C, 0x44, 0x46, 0xE4, 0x07, 0x0F, 0x8A,
+ 0x6F, 0x3B, 0x98, 0x36, 0x0F, 0x5A, 0xD3, 0x07, 0x47, 0xB7, 0x6D, 0x4D, 0xEC, 0xD8, 0xB5, 0xF3,
+ 0xF9, 0xDE, 0xD4, 0xEC, 0xFD, 0xC1, 0xDE, 0x54, 0x3F, 0x15, 0x0E, 0xB1, 0x34, 0x45, 0x2C, 0xB3,
+ 0x8B, 0x0B, 0x73, 0xB3, 0xE4, 0x3C, 0xC2, 0x86, 0x30, 0xDA, 0xBF, 0x6F, 0xF7, 0xAE, 0x9D, 0x3B,
+ 0xB6, 0x6F, 0xDB, 0xBA, 0x85, 0xA5, 0x45, 0x66, 0xAA, 0x13, 0x25, 0x22, 0x68, 0x64, 0xCB, 0xDB,
+ 0x57, 0xCA, 0x25, 0xD8, 0x18, 0x72, 0xD4, 0xC0, 0x55, 0xE8, 0x74, 0x3D, 0xC2, 0x50, 0xBD, 0x40,
+ 0x89, 0xD3, 0xC5, 0xD4, 0x11, 0x84, 0xD7, 0xBA, 0xCA, 0x73, 0xE0, 0xBC, 0xEC, 0x9D, 0x3F, 0x07,
+ 0xB6, 0xC3, 0xEB, 0x7B, 0xE7, 0xDD, 0x93, 0x26, 0xB6, 0x2E, 0xCF, 0x0F, 0x64, 0xEE, 0x25, 0xC7,
+ 0xC5, 0x25, 0x62, 0x39, 0xD8, 0xC0, 0x93, 0x4C, 0xBB, 0x72, 0x16, 0x39, 0x9E, 0xC1, 0xE5, 0xB9,
+ 0x2C, 0xF0, 0xEC, 0x56, 0xC9, 0xA4, 0xE2, 0x5A, 0xD2, 0xB6, 0xE7, 0xA7, 0x76, 0xE8, 0x35, 0xA3,
+ 0xA5, 0x0A, 0x27, 0x91, 0x6B, 0xB8, 0x31, 0x98, 0xBD, 0x1A, 0x98, 0xD9, 0x7A, 0x68, 0x12, 0xF6,
+ 0x88, 0x30, 0x6D, 0xD2, 0x61, 0x68, 0xDA, 0x16, 0xC1, 0x25, 0x52, 0x02, 0xB6, 0x2B, 0x20, 0x54,
+ 0x82, 0xB4, 0xCC, 0x0B, 0xD3, 0x44, 0xAD, 0xA0, 0x33, 0x41, 0x8A, 0xA0, 0x60, 0xE1, 0x7C, 0x38,
+ 0xCA, 0x50, 0xAC, 0x2C, 0xB0, 0xE2, 0x26, 0x73, 0x9C, 0x67, 0x0C, 0x8E, 0xA4, 0x90, 0x95, 0x65,
+ 0x97, 0x30, 0x7D, 0xA5, 0x33, 0x9D, 0x33, 0x1D, 0x08, 0x33, 0x99, 0x78, 0x1C, 0x52, 0xF0, 0x91,
+ 0x7C, 0x44, 0x50, 0x28, 0x55, 0x29, 0xB6, 0xD3, 0x1C, 0xAF, 0x97, 0x88, 0x64, 0x88, 0x49, 0xC5,
+ 0x1E, 0xDD, 0x47, 0x20, 0x62, 0xDC, 0x29, 0x26, 0x79, 0x81, 0x55, 0xB3, 0x6A, 0x8E, 0x0A, 0xD4,
+ 0x02, 0xDF, 0x7F, 0x63, 0x61, 0x7C, 0x93, 0xE0, 0xA3, 0x46, 0x37, 0x4F, 0x3D, 0xBC, 0x00, 0x11,
+ 0xEC, 0x74, 0x7A, 0xFD, 0x60, 0xC0, 0xF1, 0xF9, 0x2D, 0x43, 0x53, 0x24, 0x41, 0x4B, 0x68, 0x7C,
+ 0xFC, 0xB8, 0x9B, 0x49, 0x24, 0xAF, 0x3E, 0x0F, 0x9E, 0x45, 0x4F, 0x83, 0x00, 0x68, 0xF5, 0x2D,
+ 0x6C, 0x46, 0x8B, 0x24, 0x02, 0x01, 0x1A, 0xF9, 0x1D, 0x9F, 0xC9, 0x10, 0x8B, 0x67, 0xA1, 0xB2,
+ 0x91, 0xE9, 0xBA, 0x1E, 0x8F, 0x81, 0x75, 0xB8, 0x19, 0x54, 0x5C, 0x07, 0x34, 0x6A, 0x67, 0x06,
+ 0x96, 0x1C, 0x93, 0xED, 0x21, 0x0C, 0xA7, 0xA2, 0xC8, 0x32, 0x9E, 0x8D, 0xC7, 0xB6, 0x41, 0x92,
+ 0xA2, 0x69, 0x49, 0x92, 0x38, 0x99, 0xBE, 0x3B, 0x22, 0x89, 0x41, 0x1A, 0x21, 0x6A, 0x97, 0x6D,
+ 0x35, 0xBF, 0xF4, 0xC9, 0x4C, 0x67, 0xB4, 0xE8, 0x98, 0x82, 0x4E, 0xED, 0xD0, 0x99, 0x98, 0xDE,
+ 0x63, 0x2F, 0x1E, 0xF3, 0x7C, 0xB6, 0x71, 0xF0, 0x4B, 0xF4, 0x4D, 0x90, 0x05, 0x53, 0xFD, 0xA0,
+ 0xCD, 0x00, 0x4B, 0xCB, 0x66, 0x12, 0x71, 0x32, 0x92, 0x96, 0x50, 0x5A, 0x44, 0x89, 0x78, 0x3A,
+ 0xF8, 0x0E, 0xFA, 0x8F, 0xA1, 0xBD, 0xC1, 0xCA, 0xEE, 0x7A, 0x12, 0xD2, 0xE9, 0x0E, 0x3B, 0xE4,
+ 0xF6, 0x28, 0x67, 0x53, 0x45, 0xC7, 0x03, 0x41, 0xD9, 0x29, 0xA2, 0x99, 0xF5, 0xD0, 0xAF, 0x82,
+ 0xB2, 0x83, 0xB0, 0x97, 0x0B, 0x26, 0xF0, 0x5A, 0xD0, 0x56, 0x14, 0xFE, 0x52, 0x67, 0x6F, 0xE0,
+ 0x42, 0x61, 0x59, 0xB5, 0x1C, 0x9E, 0x10, 0x75, 0x9D, 0xE3, 0x44, 0x42, 0x59, 0x8A, 0xCC, 0x29,
+ 0x92, 0x9F, 0x83, 0x18, 0xEF, 0xB7, 0x14, 0x66, 0x2F, 0x13, 0x88, 0xF8, 0xB5, 0xCC, 0xC2, 0xC9,
+ 0x9B, 0xDE, 0xFA, 0xE8, 0x5D, 0x93, 0x24, 0x05, 0xCD, 0x8C, 0x59, 0xE6, 0xCA, 0x71, 0x5F, 0xD1,
+ 0xD0, 0xAA, 0xCF, 0x4F, 0x2C, 0x6D, 0x76, 0xF3, 0x87, 0x56, 0x7F, 0x8E, 0x3E, 0x88, 0xFE, 0x11,
+ 0xE4, 0xC1, 0x1C, 0xB8, 0xB9, 0x5F, 0xE9, 0x34, 0x42, 0xB6, 0xC6, 0x32, 0x60, 0x62, 0xCC, 0xC7,
+ 0xC6, 0xA2, 0x48, 0x92, 0x65, 0x29, 0xFF, 0x27, 0xF3, 0xD9, 0x33, 0xF3, 0xCC, 0xBB, 0xE6, 0xC9,
+ 0x77, 0xCE, 0x57, 0x46, 0xE6, 0x0A, 0xB3, 0x68, 0xA4, 0xF7, 0xA7, 0x15, 0x0C, 0xE8, 0x3B, 0x1B,
+ 0x27, 0xD6, 0x8B, 0xA7, 0x80, 0x35, 0x62, 0x7C, 0xBC, 0x72, 0xEE, 0xBB, 0x7B, 0x47, 0xCF, 0x0A,
+ 0x9E, 0xCF, 0xE3, 0x45, 0x3E, 0xC5, 0xF9, 0xCE, 0x00, 0x16, 0x60, 0xF4, 0x9A, 0x75, 0xDC, 0x30,
+ 0x91, 0x07, 0xF3, 0xB3, 0x58, 0x0A, 0xF4, 0x06, 0xCE, 0x04, 0x05, 0x45, 0x49, 0x97, 0x34, 0xBD,
+ 0x70, 0xD6, 0x68, 0x0B, 0xAF, 0x4E, 0xD5, 0x83, 0x0A, 0xCC, 0xD0, 0xD9, 0x08, 0x2D, 0x07, 0x7D,
+ 0x30, 0x58, 0x19, 0x53, 0xA5, 0x30, 0x6F, 0x26, 0xFC, 0xBB, 0x2A, 0xD3, 0x6F, 0x49, 0x1B, 0x65,
+ 0xC1, 0xCF, 0x6F, 0x6A, 0xDA, 0xA9, 0x49, 0xDF, 0x89, 0x43, 0x12, 0x73, 0x92, 0xD9, 0xEE, 0x37,
+ 0x04, 0xF1, 0xE2, 0x96, 0x8C, 0x83, 0x97, 0x13, 0x32, 0x90, 0x26, 0x54, 0x55, 0x12, 0xF8, 0xAB,
+ 0x93, 0x15, 0xDE, 0x96, 0x09, 0xB8, 0xDB, 0x4A, 0xC7, 0x35, 0xC9, 0x28, 0xA7, 0xEE, 0x9E, 0x5F,
+ 0x79, 0x20, 0x65, 0x1A, 0x41, 0x93, 0x16, 0x50, 0xB5, 0x40, 0xCB, 0xE1, 0x98, 0x19, 0xBC, 0xFA,
+ 0x2A, 0x99, 0x7B, 0x2B, 0x77, 0x3C, 0x46, 0x87, 0x4C, 0x29, 0xEA, 0xDF, 0xFA, 0xDA, 0x85, 0xBF,
+ 0x2F, 0x30, 0x29, 0x15, 0x63, 0xC8, 0xF1, 0x60, 0x24, 0x73, 0xE2, 0x7F, 0xFD, 0x17, 0x8F, 0xEA,
+ 0x7E, 0x8D, 0xE6, 0xD0, 0x97, 0x40, 0x1A, 0xEC, 0xEC, 0x67, 0x1C, 0x89, 0x06, 0xB6, 0x01, 0x36,
+ 0x65, 0x38, 0xF6, 0x68, 0xFA, 0xDD, 0x64, 0xE2, 0x71, 0xAC, 0x29, 0x13, 0x88, 0x89, 0xC7, 0x10,
+ 0xCF, 0xB1, 0x04, 0x13, 0x7A, 0x92, 0xBE, 0x0C, 0x2D, 0x0E, 0x18, 0xDC, 0xD5, 0x9A, 0xEA, 0x05,
+ 0x97, 0x81, 0xD7, 0x40, 0x23, 0x9E, 0x9A, 0x8C, 0x33, 0x44, 0x4C, 0x71, 0xA6, 0x3D, 0x89, 0x46,
+ 0x33, 0x59, 0x3C, 0x2D, 0x68, 0xE8, 0x66, 0x45, 0xEE, 0xC8, 0xC3, 0x10, 0x33, 0x66, 0x03, 0x61,
+ 0x28, 0x90, 0x0F, 0x5E, 0xFC, 0xDB, 0x34, 0x24, 0x20, 0x41, 0x71, 0x18, 0xF2, 0x28, 0x14, 0xE7,
+ 0xAB, 0x75, 0x53, 0x4C, 0x4C, 0x40, 0x64, 0xE1, 0x13, 0x63, 0x8F, 0x66, 0x7C, 0xA5, 0x18, 0x31,
+ 0x36, 0x3A, 0x76, 0x55, 0x75, 0x5B, 0xAE, 0xEB, 0xF3, 0x55, 0xFD, 0x1C, 0x61, 0xD8, 0xA5, 0x9C,
+ 0xB4, 0xEB, 0x0D, 0xFF, 0x8D, 0xFF, 0x73, 0xDE, 0x95, 0xDB, 0x05, 0x2C, 0xDB, 0x7E, 0x83, 0x7E,
+ 0x08, 0x66, 0xC0, 0x4C, 0xDF, 0x37, 0x3D, 0x39, 0xDE, 0x6A, 0xA6, 0x62, 0xC1, 0xBC, 0x49, 0x3B,
+ 0x55, 0xA5, 0x7A, 0xD2, 0x37, 0xFE, 0xDE, 0x15, 0x14, 0x2C, 0x0D, 0xB3, 0x56, 0x5C, 0x57, 0x96,
+ 0x02, 0xAF, 0x71, 0xFD, 0x8A, 0x97, 0xB9, 0x47, 0x07, 0x7D, 0x9E, 0x0D, 0x7A, 0xAE, 0x6D, 0x77,
+ 0xFD, 0x30, 0xFB, 0x11, 0x1E, 0xCE, 0xC5, 0x3A, 0xC9, 0x8B, 0x8F, 0xF5, 0xC8, 0xEC, 0xC0, 0x52,
+ 0xF3, 0x82, 0x05, 0x04, 0x96, 0x27, 0x5E, 0x1E, 0x84, 0x2B, 0xE9, 0x89, 0x5F, 0x04, 0x6F, 0x32,
+ 0xC2, 0x39, 0xC1, 0xCF, 0x36, 0x1D, 0x3A, 0x9C, 0x6B, 0x07, 0x52, 0x0B, 0xBD, 0xEA, 0x2C, 0x27,
+ 0x14, 0x92, 0xE3, 0x49, 0x9B, 0xD5, 0x03, 0x6A, 0xC0, 0x67, 0x4B, 0xD2, 0x78, 0x9D, 0x8D, 0x9F,
+ 0xBA, 0x67, 0x77, 0xA2, 0x33, 0x17, 0xD0, 0xD8, 0xD3, 0xE5, 0x8A, 0xE9, 0x08, 0x9A, 0x38, 0xDE,
+ 0x5C, 0x50, 0x17, 0x5A, 0x07, 0xDE, 0x35, 0x9B, 0x15, 0xF7, 0xC5, 0x30, 0xC6, 0x4D, 0xD4, 0x7A,
+ 0xCD, 0x6D, 0xF5, 0xBB, 0xAB, 0x3E, 0x3B, 0x1D, 0x78, 0xB0, 0x7C, 0xCD, 0x83, 0x3B, 0xCB, 0xE5,
+ 0x96, 0xAC, 0xC9, 0x42, 0x22, 0x5A, 0xD9, 0xFA, 0xB9, 0xC7, 0xC6, 0xEE, 0xD9, 0xBC, 0x69, 0x2E,
+ 0x1F, 0xEA, 0x07, 0x83, 0x23, 0xDD, 0x68, 0xF1, 0xC4, 0x0F, 0x1E, 0xE1, 0xDD, 0x28, 0x08, 0xC6,
+ 0x84, 0xCF, 0xA1, 0x9F, 0xA2, 0x1F, 0x60, 0xBB, 0xEE, 0x54, 0xBF, 0x59, 0x8A, 0x31, 0x34, 0xE8,
+ 0x54, 0x8B, 0x79, 0x53, 0xEC, 0x74, 0x88, 0x5E, 0x97, 0xE8, 0x89, 0xD3, 0xD3, 0xF1, 0x44, 0x32,
+ 0x15, 0x0A, 0x5A, 0x44, 0xD8, 0xEA, 0x21, 0x44, 0x84, 0x82, 0x01, 0xBF, 0x45, 0xD9, 0x28, 0x05,
+ 0xDE, 0xB7, 0x12, 0x2B, 0x9D, 0x85, 0xA5, 0xCB, 0x7C, 0x17, 0xAE, 0xE0, 0xEE, 0x7A, 0xBC, 0xAC,
+ 0xBA, 0x8E, 0x33, 0xF5, 0x52, 0x54, 0x71, 0x63, 0xDE, 0x81, 0x6B, 0xE2, 0x95, 0x86, 0x2A, 0x3C,
+ 0x0C, 0x15, 0x3C, 0x39, 0xC8, 0xB5, 0x7A, 0x3C, 0x86, 0xB6, 0x3C, 0x15, 0x4E, 0xAC, 0x53, 0xBA,
+ 0x2B, 0x87, 0x06, 0xD1, 0xD3, 0x28, 0x81, 0x35, 0x7A, 0xB6, 0x8D, 0x7E, 0x8A, 0x01, 0x0B, 0x49,
+ 0x51, 0xA1, 0x70, 0x38, 0xCC, 0xF9, 0x1B, 0xA7, 0x1B, 0x73, 0xBA, 0x49, 0x60, 0xC9, 0x48, 0xC0,
+ 0xF4, 0xD8, 0x38, 0x4D, 0xD3, 0x14, 0x6B, 0x66, 0x6B, 0xA6, 0x28, 0x89, 0x0F, 0x49, 0x82, 0x1E,
+ 0x8A, 0x07, 0x66, 0x83, 0xCD, 0x1B, 0xC7, 0xAA, 0x4A, 0x08, 0x72, 0xF2, 0x16, 0xF4, 0x83, 0x6C,
+ 0x7C, 0x76, 0xF9, 0xAB, 0x2F, 0x97, 0xAF, 0x36, 0x4D, 0xD3, 0xF6, 0x75, 0x36, 0x3F, 0x50, 0xEF,
+ 0x29, 0x9A, 0x5F, 0x71, 0x4E, 0x07, 0xF4, 0x79, 0x2E, 0x61, 0x25, 0x8A, 0x0F, 0x3D, 0xF4, 0x9A,
+ 0x27, 0x18, 0x2D, 0x16, 0xA0, 0xD4, 0xEB, 0x58, 0xDD, 0x36, 0x3A, 0xFE, 0xDA, 0xA1, 0x6E, 0x43,
+ 0xF5, 0x77, 0xEE, 0xBB, 0x6D, 0xB4, 0x8D, 0xA9, 0x25, 0x86, 0xE5, 0xC4, 0xA7, 0xD1, 0x17, 0xC0,
+ 0x04, 0x28, 0xF4, 0xD5, 0x7A, 0xCA, 0xEF, 0x68, 0xC4, 0x48, 0xD9, 0x8E, 0xBD, 0xBF, 0xD3, 0xFE,
+ 0x33, 0x81, 0x1D, 0x60, 0xFF, 0x0D, 0x74, 0x81, 0xC7, 0xD9, 0xD1, 0x5C, 0x15, 0x6F, 0xBA, 0x26,
+ 0x8E, 0x47, 0x13, 0xC4, 0xD0, 0x29, 0x48, 0x6F, 0x08, 0x1C, 0xD1, 0x5E, 0x2C, 0x75, 0x8D, 0xB4,
+ 0xD1, 0x39, 0xB8, 0x1C, 0xB4, 0xFC, 0xFB, 0x0F, 0x8F, 0xDD, 0xBB, 0x9F, 0x0B, 0xEB, 0xD5, 0xA9,
+ 0x11, 0xD9, 0x2C, 0xA7, 0xCC, 0xE2, 0x64, 0xC3, 0xC9, 0x4D, 0x25, 0x10, 0xAB, 0x95, 0x16, 0xFA,
+ 0x11, 0xC3, 0xAC, 0xE8, 0xAA, 0x94, 0x93, 0x53, 0xCB, 0x55, 0x67, 0xEB, 0x87, 0xE1, 0x07, 0x58,
+ 0x9D, 0xBD, 0xFB, 0xB6, 0x98, 0xE5, 0xF4, 0x33, 0xA7, 0xA4, 0x91, 0x6B, 0x23, 0x95, 0x95, 0x99,
+ 0x04, 0x2B, 0x77, 0xB6, 0x4F, 0xEC, 0x8A, 0x4F, 0x94, 0xF4, 0xD2, 0xFE, 0xBE, 0x66, 0x4E, 0x35,
+ 0x77, 0xCC, 0xFA, 0x19, 0x86, 0x20, 0x4C, 0x87, 0xD3, 0x0B, 0xF2, 0x8D, 0xEE, 0xDA, 0x7F, 0x6F,
+ 0xF5, 0x79, 0x34, 0x81, 0xB1, 0x5C, 0x1E, 0x6C, 0xED, 0xC7, 0xA3, 0x61, 0x5F, 0x94, 0x0D, 0xEB,
+ 0xDA, 0x43, 0x19, 0xCE, 0x94, 0x10, 0x32, 0x2D, 0x14, 0x30, 0x75, 0x03, 0xF9, 0x03, 0x99, 0x37,
+ 0xF9, 0xB0, 0xFE, 0x88, 0x5E, 0xA6, 0x3F, 0x06, 0x7A, 0x78, 0x98, 0x47, 0xE6, 0xC1, 0xB3, 0xA1,
+ 0xDC, 0x2E, 0x44, 0x87, 0x90, 0x06, 0x0D, 0x62, 0x22, 0x9E, 0xDF, 0x82, 0x89, 0xBA, 0x82, 0x1C,
+ 0x43, 0xDA, 0x4C, 0x33, 0xC1, 0xB8, 0x7E, 0x76, 0x2F, 0x2D, 0x04, 0x8D, 0x70, 0x13, 0x7B, 0xC7,
+ 0xC3, 0x29, 0x26, 0x30, 0x52, 0x10, 0xF6, 0x4C, 0x05, 0x21, 0x42, 0xD1, 0x7D, 0x31, 0x0E, 0x52,
+ 0x8B, 0x1D, 0x5F, 0xC5, 0xEF, 0x9B, 0x19, 0xAB, 0x6E, 0xBB, 0xFD, 0x18, 0x6A, 0x05, 0x03, 0xC5,
+ 0xCD, 0x55, 0x93, 0x13, 0x2D, 0x29, 0xD0, 0x4E, 0xCB, 0x93, 0x13, 0xE8, 0xD9, 0xC7, 0x1E, 0x35,
+ 0x26, 0x7C, 0x9F, 0x19, 0x79, 0xEC, 0xFB, 0xA2, 0x60, 0x56, 0x82, 0x41, 0x8E, 0x0E, 0xCE, 0x0E,
+ 0x2C, 0xB3, 0x36, 0x55, 0x43, 0x7F, 0x8F, 0x25, 0xF8, 0x78, 0xDF, 0xD7, 0x2C, 0x64, 0x31, 0xE2,
+ 0x54, 0x46, 0xC0, 0x34, 0x99, 0xD9, 0x3A, 0x3F, 0xF7, 0xE7, 0xF3, 0xD3, 0xEF, 0x27, 0x7D, 0x1F,
+ 0x26, 0x3F, 0xB2, 0xC1, 0x3E, 0xBB, 0x0C, 0x83, 0xBB, 0xF2, 0x58, 0x19, 0x64, 0x0E, 0xE0, 0x55,
+ 0x62, 0xDD, 0xB4, 0x81, 0xE1, 0x7A, 0x38, 0x61, 0x37, 0x3B, 0x46, 0x21, 0x3C, 0x5F, 0x5B, 0xA6,
+ 0x3A, 0x34, 0xD6, 0xF0, 0xF2, 0x71, 0x2E, 0xEC, 0xA4, 0x6A, 0xA5, 0x7B, 0x5F, 0xFF, 0x64, 0xFF,
+ 0xF0, 0x6B, 0xC6, 0x4E, 0x6D, 0xBD, 0x71, 0x76, 0x36, 0xDF, 0xED, 0xE9, 0xBE, 0x4C, 0x6F, 0x31,
+ 0x7B, 0xCB, 0xC9, 0x34, 0x8D, 0xB8, 0xE2, 0x98, 0x8F, 0x0C, 0xC9, 0x5A, 0x24, 0xE6, 0x77, 0xD2,
+ 0xBB, 0x0B, 0xDB, 0xEB, 0x8C, 0x3F, 0x56, 0xEB, 0x1D, 0x3C, 0x7D, 0xDB, 0xD6, 0x7B, 0x9F, 0xD8,
+ 0x74, 0xFD, 0xAD, 0xFD, 0xFB, 0x94, 0x82, 0x29, 0x26, 0xD4, 0x42, 0x7A, 0xB1, 0xB3, 0xEF, 0x68,
+ 0x7D, 0xEA, 0xD5, 0x5B, 0x74, 0x27, 0x9E, 0xB5, 0xEE, 0xB9, 0x7A, 0x32, 0x29, 0x52, 0xE2, 0xC4,
+ 0xB6, 0xAE, 0x8F, 0x08, 0xF2, 0xD1, 0xDE, 0x58, 0xE3, 0xFA, 0x7C, 0xB4, 0x5A, 0xDE, 0x53, 0xCD,
+ 0x87, 0xAE, 0xEA, 0x4E, 0x4E, 0xCC, 0x4D, 0x15, 0x03, 0x51, 0x9B, 0xE2, 0xBD, 0xF5, 0x7B, 0x06,
+ 0x7D, 0x0A, 0xDB, 0xA2, 0xD3, 0xE0, 0xFA, 0x7E, 0xB9, 0x95, 0x0E, 0x83, 0x74, 0x72, 0xFA, 0xA3,
+ 0x33, 0x3D, 0x6B, 0x86, 0xBA, 0x67, 0xC6, 0xD6, 0x9D, 0x12, 0x6F, 0xFB, 0xED, 0x64, 0x22, 0x12,
+ 0x97, 0xD1, 0x88, 0xCF, 0xB1, 0xB1, 0x00, 0x8D, 0x97, 0x1E, 0x08, 0xEF, 0x3B, 0x0B, 0xD3, 0x57,
+ 0x60, 0x81, 0xAE, 0xB7, 0x92, 0xDD, 0x41, 0x0C, 0xC8, 0xB3, 0xED, 0x36, 0x1A, 0xF1, 0x78, 0x6A,
+ 0x66, 0xD2, 0xAE, 0x6C, 0xF3, 0x30, 0x2A, 0xCA, 0xAE, 0x7B, 0xA3, 0x92, 0x74, 0x52, 0x8B, 0x42,
+ 0x05, 0xB3, 0x65, 0xAB, 0x5D, 0x75, 0x23, 0x76, 0xC4, 0x9A, 0x3D, 0x8F, 0x0D, 0x7D, 0x0C, 0xED,
+ 0x08, 0xD7, 0x98, 0xFD, 0x94, 0xEF, 0x08, 0x2D, 0x0A, 0xA1, 0x4D, 0xCB, 0x71, 0xA5, 0xAF, 0x8D,
+ 0x4D, 0xEF, 0x0E, 0xD2, 0x34, 0x47, 0x22, 0x22, 0x9F, 0x4B, 0xA6, 0x48, 0x8C, 0xA1, 0xE0, 0xEC,
+ 0x42, 0x04, 0xFF, 0xE5, 0x9B, 0x81, 0xBB, 0x97, 0xAF, 0x3A, 0x10, 0x4F, 0x55, 0x74, 0x8D, 0x4D,
+ 0x62, 0x83, 0xB7, 0x9E, 0x12, 0x49, 0x76, 0xB7, 0xD2, 0x27, 0xE9, 0xFD, 0x6F, 0x5C, 0xCA, 0x27,
+ 0xF8, 0xE2, 0x68, 0x61, 0x5A, 0x46, 0x17, 0xEF, 0xE8, 0x74, 0x83, 0x41, 0x9F, 0x6F, 0xDB, 0xC7,
+ 0x9F, 0x3E, 0xE4, 0xF3, 0x41, 0x32, 0x1C, 0x0E, 0x85, 0x59, 0x96, 0x09, 0x6E, 0xE9, 0xC4, 0xA6,
+ 0xE2, 0x49, 0x3E, 0x20, 0xB4, 0x9A, 0xB2, 0x36, 0x9D, 0x72, 0xF3, 0xA4, 0xA3, 0x98, 0x53, 0xB7,
+ 0x61, 0x4E, 0xED, 0x81, 0xF9, 0x7E, 0x64, 0xAA, 0xE4, 0x97, 0x1A, 0x5A, 0x3B, 0xA9, 0x7D, 0xB2,
+ 0x6F, 0x7E, 0xA2, 0x6F, 0x7F, 0xBC, 0x5F, 0xFB, 0x58, 0xBE, 0x8D, 0x92, 0xF9, 0x3F, 0x63, 0x59,
+ 0x28, 0x6D, 0xF0, 0x5F, 0x80, 0xCB, 0x61, 0xE4, 0x3A, 0x4E, 0x97, 0x5C, 0xDB, 0xCC, 0x1B, 0xBD,
+ 0xE7, 0xDA, 0xC7, 0x28, 0xD2, 0xF6, 0x50, 0xB9, 0xEB, 0xCA, 0xF0, 0x72, 0x4C, 0x08, 0x0F, 0x94,
+ 0x60, 0x80, 0x92, 0x19, 0x10, 0xC7, 0x20, 0x53, 0x0D, 0x4D, 0x0A, 0xE5, 0x96, 0x53, 0x9B, 0xDB,
+ 0x56, 0x28, 0x2D, 0x15, 0xD4, 0x7A, 0x37, 0x26, 0xEC, 0xCF, 0xD1, 0x42, 0xA3, 0x27, 0x15, 0x1B,
+ 0xF6, 0xC7, 0x45, 0x67, 0x7C, 0x76, 0xD9, 0x7F, 0x7A, 0xAE, 0xBF, 0x95, 0x4F, 0xEC, 0x12, 0xEB,
+ 0x3D, 0x66, 0xB3, 0x7F, 0x74, 0x9C, 0xFD, 0xA3, 0x97, 0x7F, 0xC5, 0x6E, 0x8D, 0x68, 0xD1, 0xB0,
+ 0xEE, 0x4B, 0xDB, 0x82, 0x5E, 0x48, 0x1B, 0xB9, 0x25, 0xD8, 0xCA, 0x31, 0xB5, 0x8C, 0xC1, 0x8C,
+ 0x90, 0x52, 0x65, 0xB4, 0x7C, 0x6D, 0x5B, 0x2A, 0x8D, 0x38, 0x12, 0x63, 0x95, 0xB4, 0xAE, 0x34,
+ 0xA5, 0x86, 0x6B, 0x36, 0x2A, 0x24, 0xAF, 0x8E, 0x0D, 0x6C, 0xB3, 0x67, 0xD0, 0x67, 0xB1, 0x0D,
+ 0xE2, 0x07, 0x4B, 0xFD, 0x98, 0x2E, 0x01, 0x9D, 0x66, 0x5E, 0x8F, 0x71, 0xED, 0xEB, 0x9C, 0x97,
+ 0x09, 0x48, 0x61, 0x90, 0xC2, 0x22, 0x59, 0xB1, 0x41, 0xCB, 0x8D, 0x02, 0xEA, 0x97, 0x48, 0xC0,
+ 0xCB, 0x3A, 0xF5, 0x16, 0xBC, 0xE7, 0xD9, 0xAF, 0xEB, 0x0E, 0xE7, 0x80, 0xEE, 0x26, 0x28, 0xBA,
+ 0xD0, 0x19, 0x03, 0x65, 0x0C, 0x86, 0x69, 0xA6, 0x6D, 0x24, 0x32, 0x49, 0x0C, 0x88, 0x9D, 0x7A,
+ 0x0A, 0x7D, 0xF6, 0x84, 0x9C, 0x55, 0x4A, 0xC1, 0x49, 0x82, 0x66, 0xAF, 0xDA, 0x43, 0xC1, 0xF2,
+ 0xC7, 0x8A, 0xAD, 0x29, 0x55, 0x39, 0x39, 0x0F, 0xA7, 0xD1, 0x97, 0x6F, 0x90, 0x05, 0x82, 0x84,
+ 0x67, 0x8F, 0x7F, 0xE0, 0x60, 0x7D, 0xA6, 0x8B, 0x22, 0x6A, 0xBD, 0xCC, 0x0B, 0x0C, 0xE3, 0x65,
+ 0xD1, 0xFC, 0x8C, 0x48, 0xA1, 0x6F, 0x80, 0x11, 0x37, 0x06, 0x56, 0x2E, 0x15, 0x0B, 0x36, 0xF0,
+ 0xA7, 0x5E, 0x57, 0x07, 0xFF, 0x75, 0x45, 0xFE, 0x14, 0x18, 0xE6, 0x27, 0x80, 0x0D, 0xE2, 0xB3,
+ 0x6E, 0x0F, 0x62, 0x76, 0xFC, 0x20, 0xFB, 0xC9, 0x05, 0x46, 0x11, 0x14, 0xF5, 0x42, 0x42, 0xAE,
+ 0x1A, 0xCD, 0x36, 0x7B, 0x04, 0x91, 0x22, 0x29, 0x46, 0x0C, 0x1B, 0x05, 0xB9, 0x3F, 0x3F, 0x51,
+ 0x2C, 0x1A, 0xA9, 0x2D, 0xDB, 0x67, 0xCB, 0xA1, 0x6A, 0xEA, 0x5E, 0x44, 0x72, 0xC1, 0x80, 0x0A,
+ 0xB5, 0xF2, 0x81, 0x7A, 0x71, 0x2E, 0xA9, 0x62, 0x3B, 0xAE, 0x5C, 0x1A, 0x45, 0xDF, 0x08, 0xD8,
+ 0xD9, 0xCA, 0xA1, 0xF6, 0xE1, 0xC8, 0xD9, 0x1B, 0xA7, 0xA2, 0x62, 0xFB, 0xF0, 0xE9, 0x83, 0xBD,
+ 0xFB, 0xAA, 0x65, 0x73, 0x4B, 0x30, 0xBE, 0x74, 0xC3, 0x62, 0x92, 0x8C, 0x5D, 0x73, 0xE6, 0x86,
+ 0xE5, 0x5D, 0x53, 0xD9, 0x78, 0x89, 0xF1, 0x07, 0x02, 0xAE, 0xC7, 0x67, 0xF5, 0x47, 0xAB, 0xCF,
+ 0x10, 0x26, 0xFA, 0x36, 0xA8, 0xBA, 0xB1, 0x91, 0x72, 0x48, 0xE4, 0x41, 0x2C, 0x18, 0x00, 0xE7,
+ 0x56, 0xB4, 0x7D, 0x83, 0x1E, 0x5F, 0x1E, 0xE0, 0x0E, 0x0D, 0xF5, 0x9A, 0x6B, 0x8F, 0x5A, 0xA6,
+ 0x17, 0x1D, 0x65, 0xAA, 0x44, 0x85, 0x58, 0x0B, 0x11, 0xDB, 0x51, 0xD7, 0xA9, 0x07, 0x9B, 0x3D,
+ 0x48, 0x98, 0xA6, 0x1A, 0xD9, 0x77, 0x75, 0xD4, 0x12, 0x59, 0x1E, 0x43, 0xFA, 0x54, 0x42, 0x12,
+ 0xFA, 0xBB, 0x2B, 0xE3, 0x31, 0x83, 0xF5, 0xF1, 0x0F, 0x92, 0x16, 0x6B, 0xE4, 0x73, 0x07, 0x1B,
+ 0x21, 0x4B, 0xE2, 0x0A, 0xF9, 0x50, 0x24, 0x82, 0xBE, 0x9D, 0x0C, 0xB6, 0xFE, 0xE8, 0x13, 0xF3,
+ 0xB5, 0x70, 0x40, 0x52, 0x1C, 0x51, 0x12, 0x2C, 0x23, 0x19, 0xFA, 0xCF, 0x1F, 0x3A, 0x7C, 0x24,
+ 0xCE, 0x43, 0xD1, 0xDE, 0x4F, 0xF0, 0xA3, 0x8B, 0x4F, 0x9D, 0x98, 0x28, 0x87, 0xF4, 0x23, 0xD7,
+ 0x9F, 0x6A, 0xAA, 0x8A, 0xD7, 0xEF, 0xE7, 0xC8, 0xDF, 0x60, 0xCD, 0x7E, 0x35, 0x18, 0xE9, 0x1B,
+ 0x9D, 0x4C, 0x4A, 0x91, 0xC0, 0xF6, 0xA9, 0x89, 0xB1, 0x90, 0x39, 0x7D, 0x0D, 0x78, 0x5F, 0xBE,
+ 0x34, 0x74, 0x4B, 0x0E, 0x14, 0xD6, 0x46, 0x95, 0x75, 0x4D, 0xC7, 0x0D, 0xC5, 0x51, 0x5E, 0x4C,
+ 0x77, 0xD8, 0x7F, 0x54, 0x21, 0xB2, 0x5E, 0xDC, 0x11, 0x37, 0xA0, 0x2A, 0x8D, 0xC9, 0x9E, 0xC8,
+ 0xAC, 0x69, 0x67, 0x97, 0xD4, 0x1D, 0x37, 0xD1, 0x8C, 0x72, 0xF0, 0xD8, 0xDC, 0x13, 0x44, 0xFE,
+ 0x86, 0x09, 0x4C, 0x6C, 0xEB, 0xE5, 0x05, 0x24, 0x49, 0x58, 0x2F, 0xAB, 0x9A, 0x3D, 0xA6, 0x92,
+ 0x28, 0x2B, 0x76, 0x26, 0x8D, 0x80, 0xAE, 0x09, 0xB9, 0x58, 0x34, 0x80, 0x2C, 0x6B, 0xBF, 0xE4,
+ 0x08, 0x04, 0x52, 0xE4, 0x70, 0xAB, 0x99, 0x21, 0x2C, 0xD3, 0x47, 0xB2, 0xE8, 0x6E, 0x96, 0x51,
+ 0x32, 0x23, 0x85, 0x6E, 0xBA, 0x1A, 0x2B, 0x36, 0x28, 0xD7, 0x5D, 0xFF, 0x9A, 0xCC, 0xF1, 0x9C,
+ 0x98, 0x40, 0x42, 0xBA, 0x99, 0xA3, 0xB1, 0xDE, 0xFF, 0x81, 0x54, 0xBA, 0xE9, 0x3F, 0xDD, 0x7F,
+ 0x55, 0x88, 0x8C, 0x27, 0x49, 0x51, 0xE6, 0x29, 0x91, 0x57, 0x53, 0x3C, 0x8D, 0x6E, 0x8C, 0x3F,
+ 0x78, 0x57, 0xB2, 0x1C, 0x8D, 0x5B, 0x5B, 0xA7, 0xA7, 0x17, 0x4C, 0x5A, 0x16, 0xC5, 0x5A, 0xAA,
+ 0x1B, 0x66, 0xA8, 0x68, 0x6A, 0xF6, 0xD6, 0xEB, 0xE7, 0x99, 0x64, 0x12, 0xF9, 0x77, 0xD3, 0xA3,
+ 0x07, 0xB6, 0xDF, 0xBD, 0xE9, 0xF8, 0xCC, 0x75, 0xAF, 0x49, 0x48, 0x8E, 0x23, 0xEE, 0x99, 0xFB,
+ 0xCC, 0x35, 0x81, 0xDD, 0xA4, 0x6F, 0xCB, 0x99, 0xFB, 0x7B, 0x6E, 0xC2, 0x8C, 0x6B, 0xB7, 0x7C,
+ 0x07, 0x7D, 0x01, 0x7D, 0x17, 0x4B, 0xD3, 0xCD, 0xFD, 0x48, 0x3D, 0x13, 0x8F, 0xCA, 0xA0, 0x39,
+ 0x52, 0x2D, 0x4C, 0xF8, 0xE9, 0x09, 0xBF, 0x94, 0x99, 0x11, 0xDE, 0x32, 0x63, 0xFC, 0xB7, 0x19,
+ 0xFF, 0xA7, 0xA7, 0x3F, 0x93, 0xFE, 0xAC, 0xAB, 0x45, 0xCE, 0x81, 0x89, 0x41, 0xBA, 0xE5, 0x9A,
+ 0x32, 0xB9, 0x1C, 0x13, 0xBA, 0x52, 0x33, 0xE3, 0xF2, 0x8F, 0x67, 0x78, 0x7A, 0x8E, 0x3D, 0x47,
+ 0x26, 0x3C, 0xFF, 0xAE, 0xEC, 0x36, 0x86, 0x3D, 0x1A, 0xF1, 0xD2, 0x09, 0x36, 0x62, 0x9D, 0x08,
+ 0x72, 0xDC, 0x84, 0x35, 0xF4, 0x85, 0xF1, 0xF2, 0xF5, 0x7E, 0x5F, 0x30, 0xBC, 0x7F, 0x53, 0x52,
+ 0x17, 0x24, 0x2E, 0x99, 0xEE, 0xE9, 0xBC, 0x20, 0x2B, 0x77, 0x71, 0x79, 0x46, 0xA2, 0x72, 0x56,
+ 0x71, 0x25, 0xDB, 0x96, 0xDF, 0xEE, 0xF4, 0xF3, 0xEC, 0x43, 0xE1, 0xA2, 0x2A, 0xC8, 0xDC, 0xEB,
+ 0x59, 0x5A, 0xAE, 0x4C, 0xC6, 0x32, 0x62, 0xC6, 0x4F, 0x13, 0xF5, 0x8F, 0xA2, 0xAF, 0xF5, 0x47,
+ 0xCF, 0xC4, 0xC2, 0x89, 0xC2, 0xD9, 0x6B, 0x43, 0x82, 0x6D, 0xFB, 0x1A, 0x22, 0x26, 0x92, 0xF7,
+ 0x8B, 0xF3, 0x9C, 0xC6, 0x4F, 0x37, 0x22, 0x1A, 0xAB, 0x64, 0xAC, 0xA0, 0xF1, 0x89, 0xC0, 0xDE,
+ 0x2E, 0xFF, 0x54, 0x36, 0xCD, 0xA9, 0xB7, 0xD0, 0x53, 0x47, 0xEB, 0x6D, 0x71, 0xBC, 0x9D, 0x30,
+ 0x7C, 0x7B, 0x06, 0xC8, 0xE0, 0x39, 0xC2, 0x42, 0x3F, 0x05, 0x6D, 0xD0, 0xEF, 0xFB, 0x1B, 0xB5,
+ 0x18, 0x28, 0x24, 0xA3, 0xE1, 0x82, 0x60, 0x6A, 0x26, 0x92, 0x44, 0xA1, 0xFD, 0x39, 0x0D, 0x23,
+ 0xBF, 0xD8, 0x95, 0x5A, 0x04, 0x5C, 0x6E, 0x7C, 0xE3, 0x19, 0x18, 0x8B, 0x0D, 0xA2, 0xBA, 0x14,
+ 0x26, 0x9D, 0xA8, 0x3B, 0x6A, 0xA6, 0x0B, 0xDB, 0x1E, 0xE0, 0xD9, 0x88, 0xEC, 0xDC, 0x24, 0x90,
+ 0x4C, 0x16, 0x73, 0xB2, 0x65, 0x97, 0x53, 0x9A, 0xD1, 0x31, 0x2A, 0x39, 0x13, 0xC2, 0x44, 0x70,
+ 0x2C, 0x01, 0x39, 0xAB, 0xB2, 0x35, 0x37, 0x55, 0xD3, 0x38, 0x59, 0xB0, 0xEF, 0xF0, 0x07, 0x37,
+ 0x05, 0xFA, 0x99, 0x31, 0x53, 0xF5, 0x8D, 0xD8, 0x0A, 0x41, 0x8E, 0x8F, 0xB7, 0xC6, 0xD0, 0xF7,
+ 0x9D, 0xB9, 0xB1, 0x40, 0xF4, 0xDA, 0xF0, 0xC2, 0x54, 0x77, 0xA2, 0x62, 0xFB, 0xF4, 0x9C, 0x5F,
+ 0x89, 0x28, 0x3B, 0xF6, 0x4C, 0x6C, 0xBD, 0x61, 0x64, 0x21, 0x4F, 0x6B, 0xDA, 0xBE, 0x03, 0x89,
+ 0x3D, 0xED, 0x83, 0x09, 0x2B, 0x75, 0xB0, 0x5C, 0xB3, 0x39, 0x5D, 0xC4, 0xA0, 0x31, 0x8C, 0xD7,
+ 0x3A, 0xB2, 0xFA, 0x1F, 0x68, 0x09, 0x3D, 0x03, 0x3A, 0x58, 0x52, 0x26, 0x1A, 0x79, 0x8C, 0x7D,
+ 0x14, 0x16, 0x64, 0xD2, 0x71, 0x05, 0xFC, 0x4D, 0xD7, 0x34, 0x34, 0x42, 0xFF, 0x58, 0x42, 0x53,
+ 0xFF, 0x32, 0xF1, 0xF5, 0x76, 0x8E, 0x0C, 0x7D, 0x9E, 0x84, 0x03, 0xD4, 0xD0, 0x1B, 0x3A, 0x24,
+ 0x2E, 0xBC, 0xC8, 0x94, 0xEB, 0xB2, 0x58, 0x41, 0xD0, 0xCC, 0x7A, 0xD0, 0xB3, 0x47, 0x28, 0xA8,
+ 0x08, 0x07, 0xD1, 0x19, 0xE4, 0x62, 0x3D, 0xD7, 0x8F, 0xD0, 0xC6, 0xBC, 0xE2, 0xB9, 0x7B, 0x65,
+ 0x72, 0x10, 0xF9, 0x9D, 0x42, 0x68, 0x69, 0x71, 0x72, 0xBC, 0x78, 0xF7, 0x43, 0x5B, 0xEC, 0xAD,
+ 0xCB, 0x57, 0x25, 0x32, 0x95, 0xDA, 0x44, 0x4F, 0x8D, 0x28, 0x5D, 0x4B, 0x3E, 0x60, 0xA3, 0xE2,
+ 0xF6, 0xFD, 0x5B, 0x96, 0x4C, 0x9A, 0x45, 0x50, 0x49, 0xF4, 0x27, 0x36, 0xD7, 0x83, 0xBE, 0xE8,
+ 0x64, 0xA9, 0x92, 0xDF, 0xE2, 0x7B, 0xFF, 0xB5, 0x9B, 0x68, 0x29, 0x99, 0xD1, 0xC7, 0x8E, 0x1D,
+ 0x3D, 0x9A, 0xAB, 0x22, 0x04, 0x91, 0x12, 0x31, 0xC3, 0xFA, 0x21, 0x8E, 0xE4, 0x42, 0x04, 0x45,
+ 0x8B, 0x2C, 0xA3, 0x27, 0xB7, 0x6F, 0x3E, 0xBC, 0x29, 0xDB, 0xD2, 0x0C, 0x4B, 0x20, 0x58, 0x0A,
+ 0x8F, 0x77, 0x65, 0xF5, 0x11, 0x38, 0x83, 0x9E, 0x06, 0x11, 0xB0, 0xAD, 0x9F, 0xB4, 0x54, 0xF0,
+ 0x45, 0x8C, 0x49, 0xDF, 0x6A, 0x30, 0xA1, 0xED, 0xE4, 0x45, 0x03, 0xD8, 0x21, 0xDB, 0x2F, 0x31,
+ 0xBC, 0x1F, 0xF1, 0x12, 0xB3, 0xC2, 0xC0, 0x2F, 0x41, 0xE6, 0xCA, 0x62, 0x81, 0xEE, 0xE0, 0x31,
+ 0xC8, 0xF2, 0xF6, 0xC6, 0x8F, 0x07, 0x1D, 0x65, 0x5C, 0xBC, 0x34, 0x48, 0xE5, 0x19, 0xD5, 0xDD,
+ 0x25, 0x1C, 0x84, 0xB3, 0x99, 0x2C, 0x63, 0x62, 0x0C, 0xA0, 0x5B, 0xF5, 0x16, 0xC4, 0x30, 0xA4,
+ 0x1D, 0x71, 0x3A, 0x36, 0xE6, 0x64, 0x7B, 0xD2, 0x1F, 0x9E, 0xB7, 0xC4, 0x5A, 0x03, 0x43, 0xF7,
+ 0xB9, 0xE6, 0x22, 0x22, 0x49, 0x74, 0x0B, 0x9C, 0x65, 0x1E, 0xF8, 0xEC, 0x01, 0xF7, 0x74, 0x9C,
+ 0x20, 0xF6, 0x5E, 0xFC, 0xAD, 0xBE, 0xFB, 0xE2, 0x45, 0x87, 0x1E, 0x78, 0x19, 0xE1, 0x8F, 0xB0,
+ 0xEC, 0xD2, 0x41, 0xAC, 0xCF, 0xF3, 0x80, 0x07, 0xD2, 0xFB, 0x56, 0x88, 0xF5, 0x8C, 0x82, 0x75,
+ 0xBF, 0x85, 0xC1, 0x53, 0xC5, 0x38, 0xBE, 0x7D, 0x85, 0xCA, 0xE2, 0x1B, 0x47, 0x48, 0xF8, 0xA3,
+ 0xD8, 0x48, 0x36, 0xD8, 0x98, 0xBC, 0x7E, 0x6B, 0x5B, 0x0B, 0xCD, 0xFA, 0xF5, 0xEA, 0xF6, 0x6B,
+ 0x6F, 0x66, 0xF9, 0xB9, 0xE3, 0xB7, 0x7E, 0xE8, 0x55, 0x37, 0xE6, 0x04, 0x66, 0xFC, 0xA6, 0xD7,
+ 0xBF, 0xF7, 0x33, 0xF8, 0xEA, 0xBF, 0x59, 0x7D, 0x04, 0xFC, 0x33, 0x9E, 0x8D, 0x30, 0xD8, 0xDD,
+ 0xCF, 0x12, 0x8F, 0x45, 0xD8, 0x58, 0x44, 0xFF, 0xB2, 0xC1, 0x31, 0x31, 0xFA, 0x4B, 0xCA, 0xDF,
+ 0x5A, 0x0F, 0xD0, 0x3A, 0xA7, 0x70, 0xA2, 0x0F, 0x04, 0x45, 0x14, 0xF4, 0x19, 0x0C, 0xF8, 0xD2,
+ 0x95, 0xEA, 0xF2, 0xC5, 0x33, 0xE2, 0xFE, 0xBB, 0xC9, 0x9F, 0x58, 0x63, 0x3A, 0x83, 0x19, 0x69,
+ 0x3B, 0x6D, 0x77, 0x52, 0x50, 0xD3, 0x3D, 0xF7, 0x02, 0x55, 0xEE, 0xA4, 0xD8, 0xFF, 0xAC, 0x56,
+ 0xC3, 0x91, 0xDD, 0xCE, 0x70, 0x1A, 0x34, 0x3B, 0x35, 0x1E, 0x9C, 0x33, 0x08, 0x74, 0x9F, 0x3B,
+ 0x07, 0x98, 0x03, 0xF6, 0x42, 0x52, 0xDF, 0x0D, 0x31, 0xC9, 0x50, 0xD3, 0x34, 0x89, 0x6E, 0xBC,
+ 0xF8, 0x57, 0xEC, 0xFD, 0x7F, 0xED, 0xCA, 0xA6, 0x1E, 0xE4, 0x91, 0x1F, 0xFD, 0x27, 0x2F, 0x9A,
+ 0x19, 0x20, 0x90, 0x6B, 0xFF, 0x90, 0xD0, 0x8D, 0x6E, 0xD2, 0x00, 0x59, 0x14, 0x4D, 0xFD, 0x3D,
+ 0x89, 0x2D, 0x60, 0xF0, 0x15, 0xAF, 0x70, 0xC1, 0x75, 0xCF, 0x7B, 0xD1, 0xCC, 0xE0, 0xE3, 0xE3,
+ 0x5F, 0x5E, 0x8B, 0x66, 0x9E, 0xFB, 0xD1, 0x3D, 0x83, 0x37, 0x6E, 0x34, 0x93, 0xC4, 0x5C, 0x99,
+ 0x14, 0x60, 0xD2, 0x68, 0x20, 0xFF, 0xA1, 0xD7, 0xBE, 0xF6, 0xD0, 0x5F, 0x1D, 0x80, 0x3C, 0xCC,
+ 0x5D, 0xFC, 0x16, 0x7C, 0x05, 0xF0, 0x66, 0x67, 0x02, 0x15, 0x56, 0x57, 0x00, 0x01, 0x22, 0x7D,
+ 0xDE, 0x8D, 0x98, 0x12, 0xE8, 0x69, 0x08, 0xBE, 0x36, 0x88, 0xC3, 0xAE, 0x71, 0x36, 0xE9, 0x46,
+ 0x76, 0xDD, 0xC8, 0x6B, 0xE1, 0xC2, 0xD7, 0xD0, 0xC8, 0xDF, 0x26, 0xF1, 0xEF, 0x56, 0x51, 0x18,
+ 0x9C, 0x47, 0x9F, 0x5C, 0xCB, 0xEB, 0x25, 0xBE, 0xBE, 0x02, 0xFF, 0xFB, 0x4B, 0xE4, 0xF5, 0x62,
+ 0xCE, 0x3F, 0x5F, 0x7F, 0x72, 0x1F, 0x1A, 0x75, 0x0E, 0xB7, 0xBD, 0x2C, 0xBC, 0x9F, 0xA3, 0x79,
+ 0xF8, 0x2C, 0xB6, 0xA8, 0x1A, 0x7D, 0xBB, 0x96, 0x8F, 0xDB, 0x12, 0xA8, 0x96, 0x2D, 0xBB, 0x63,
+ 0xDC, 0xD1, 0x19, 0xFD, 0x46, 0x24, 0x04, 0x89, 0x20, 0xEB, 0x8D, 0xEA, 0xC5, 0x71, 0xA5, 0x4E,
+ 0xDC, 0x75, 0x12, 0xB8, 0xC2, 0x64, 0x90, 0xFA, 0x5C, 0x1F, 0xBA, 0xF6, 0xA0, 0x9B, 0x9D, 0xEA,
+ 0x25, 0x61, 0xB4, 0x5B, 0x3D, 0x22, 0xBB, 0xD1, 0x63, 0x42, 0x38, 0x68, 0xFE, 0x1E, 0x86, 0x4F,
+ 0x8D, 0x4F, 0xA5, 0xF2, 0x9C, 0x9C, 0x34, 0xF9, 0x56, 0x49, 0x64, 0x0A, 0x11, 0x11, 0x55, 0xD3,
+ 0xCD, 0x88, 0x4C, 0x13, 0xBD, 0xB9, 0xE2, 0x52, 0xB6, 0x2A, 0x99, 0x49, 0x31, 0xD8, 0xF2, 0x19,
+ 0x2A, 0x3B, 0x17, 0xCE, 0x2B, 0xD1, 0x83, 0xF9, 0x72, 0x21, 0x35, 0xBF, 0xD7, 0xF2, 0x6D, 0xE9,
+ 0x87, 0x38, 0x8A, 0xB6, 0x65, 0x32, 0x92, 0xA6, 0x15, 0x19, 0x95, 0x92, 0x21, 0xC8, 0x8C, 0x65,
+ 0xEC, 0x9D, 0x65, 0x5B, 0x42, 0xD8, 0xEA, 0x2C, 0x14, 0x78, 0x61, 0xDC, 0xE7, 0x3F, 0xD3, 0xDD,
+ 0xB4, 0x63, 0xD1, 0x9D, 0xC7, 0x7F, 0xC1, 0x96, 0x75, 0x94, 0xF0, 0x83, 0x71, 0x2C, 0x43, 0x83,
+ 0xED, 0xBC, 0x55, 0xAF, 0x94, 0x4D, 0x2D, 0x63, 0x4E, 0x54, 0xE3, 0x71, 0x24, 0x45, 0x63, 0x48,
+ 0x0A, 0xFD, 0x23, 0x53, 0xBA, 0x14, 0x64, 0x81, 0x6B, 0x29, 0xE0, 0x1B, 0x35, 0xB2, 0x1B, 0x18,
+ 0xB0, 0xBC, 0xC0, 0x00, 0xE3, 0x65, 0x80, 0x13, 0x6E, 0x95, 0x84, 0xE7, 0x08, 0xF1, 0xCC, 0xA8,
+ 0x76, 0xCB, 0xB6, 0x1C, 0x63, 0x2D, 0xE7, 0xDE, 0xB5, 0xB4, 0x86, 0x62, 0xD5, 0xF5, 0x90, 0x21,
+ 0x99, 0x2F, 0x56, 0xE4, 0xE0, 0xB5, 0xE3, 0xED, 0x1D, 0x26, 0x47, 0x10, 0x18, 0x64, 0x70, 0x8A,
+ 0xC0, 0x07, 0xE7, 0x04, 0x31, 0x26, 0xA8, 0xAA, 0x0F, 0xD1, 0x74, 0x62, 0x97, 0xB4, 0xA0, 0xA7,
+ 0x16, 0x47, 0x34, 0x7A, 0x7F, 0x38, 0x36, 0xDB, 0x50, 0x0C, 0xF6, 0x7C, 0x64, 0x2C, 0x2F, 0x3B,
+ 0xB3, 0x3B, 0x46, 0xF7, 0x3C, 0x79, 0x7A, 0x6C, 0x5B, 0x9B, 0x22, 0x15, 0xBD, 0xCE, 0xF2, 0x3E,
+ 0x0E, 0x21, 0x5D, 0xCD, 0x5C, 0x3C, 0xDC, 0xAD, 0x1F, 0x54, 0x0E, 0x6A, 0xF1, 0xE3, 0x93, 0x50,
+ 0x19, 0xD3, 0x17, 0x82, 0xE9, 0x8A, 0x59, 0x19, 0x64, 0x52, 0x3E, 0x07, 0xDF, 0x0B, 0xFF, 0x37,
+ 0x28, 0xB9, 0x31, 0xB1, 0xA4, 0xC9, 0x81, 0x48, 0xE9, 0xCF, 0xCB, 0x05, 0xB3, 0x1C, 0x3C, 0xAF,
+ 0x28, 0xDF, 0x24, 0x4A, 0x2F, 0x15, 0x13, 0x2B, 0xBB, 0x89, 0x80, 0x9E, 0xC0, 0x24, 0x86, 0xF0,
+ 0xD9, 0x4D, 0x60, 0x50, 0x28, 0xCF, 0xCF, 0x07, 0x87, 0xD6, 0x71, 0x1B, 0xBE, 0x79, 0x64, 0x77,
+ 0x6F, 0xFB, 0x6E, 0x85, 0xA7, 0x0B, 0x2B, 0xA3, 0xD3, 0x11, 0x5F, 0xC9, 0x8A, 0xC4, 0x7D, 0x9C,
+ 0xC4, 0x05, 0x89, 0x4E, 0xDA, 0x6F, 0x8B, 0x9A, 0x3D, 0x5D, 0xCA, 0xC5, 0x60, 0x28, 0xB0, 0x33,
+ 0x35, 0x79, 0x67, 0x34, 0x95, 0x54, 0xB2, 0xC7, 0x77, 0x46, 0x2D, 0x55, 0x76, 0x02, 0xC1, 0x80,
+ 0x4E, 0x73, 0x8C, 0x1C, 0x9B, 0x37, 0x05, 0x27, 0xEE, 0xEC, 0xDD, 0x1C, 0x13, 0x11, 0xE7, 0x55,
+ 0x23, 0x62, 0x8B, 0x37, 0x83, 0xFE, 0x33, 0xE8, 0x82, 0x6C, 0x5F, 0xE9, 0x94, 0x8B, 0x99, 0x90,
+ 0x2A, 0xF3, 0xBE, 0xF7, 0x4F, 0x16, 0xBE, 0xC5, 0x2C, 0x0E, 0xBA, 0xB9, 0x51, 0xAC, 0x4F, 0x66,
+ 0xDC, 0xA9, 0xA7, 0x06, 0x19, 0x17, 0x03, 0x9B, 0x1D, 0x7A, 0xAA, 0xDC, 0xB3, 0x6B, 0x99, 0x35,
+ 0xE1, 0x8E, 0x4D, 0x1D, 0x37, 0x7E, 0x89, 0xD9, 0x1B, 0x89, 0x7C, 0xA3, 0x6D, 0xCE, 0x8D, 0x87,
+ 0x77, 0xDD, 0x70, 0x4B, 0x5C, 0x08, 0x70, 0x0C, 0x9F, 0x68, 0x86, 0xB9, 0xE4, 0x08, 0x87, 0x98,
+ 0xA9, 0xE5, 0xE0, 0x99, 0xFD, 0x11, 0x95, 0x7D, 0x50, 0x55, 0x33, 0x5A, 0x90, 0x8B, 0x64, 0xF3,
+ 0x9A, 0x9D, 0x28, 0xEC, 0xF9, 0x92, 0x3D, 0x51, 0xD7, 0xAA, 0xF6, 0xA3, 0xDD, 0x23, 0xB3, 0x1A,
+ 0x9B, 0x6F, 0xE8, 0x59, 0xCD, 0x1C, 0x75, 0xE8, 0x7C, 0x5D, 0x65, 0xB4, 0xA9, 0x85, 0x9C, 0x50,
+ 0x48, 0xFA, 0x74, 0xCD, 0x60, 0x0F, 0x89, 0x92, 0x19, 0x0E, 0xF0, 0x32, 0x2D, 0xAB, 0x0A, 0xC3,
+ 0x4A, 0x76, 0x6F, 0x73, 0xD5, 0xCB, 0xFB, 0x5D, 0xFD, 0x09, 0xFC, 0x10, 0xFC, 0x19, 0x28, 0x63,
+ 0xDE, 0xB1, 0x82, 0x3A, 0x28, 0x3F, 0x56, 0x29, 0x7C, 0xA7, 0x12, 0xCB, 0x64, 0x10, 0xAF, 0x7C,
+ 0x97, 0xFA, 0xA7, 0xF5, 0x0A, 0x91, 0xDE, 0x86, 0x8A, 0xAF, 0xC1, 0xC8, 0x2A, 0xBC, 0xE7, 0x60,
+ 0x43, 0x03, 0x93, 0xC6, 0x4B, 0xBC, 0xF4, 0x92, 0x0D, 0xC8, 0x4B, 0x39, 0x8D, 0xC3, 0xF4, 0xA4,
+ 0x1E, 0x84, 0x1F, 0xD2, 0x3B, 0xB9, 0x66, 0xB8, 0xD2, 0x17, 0x76, 0x4E, 0xDD, 0xB8, 0x2D, 0xD3,
+ 0x9E, 0x92, 0xE2, 0xB1, 0x02, 0x99, 0x2B, 0x49, 0x52, 0x51, 0x14, 0xB7, 0xB1, 0xA1, 0x54, 0xFC,
+ 0xE0, 0x62, 0x32, 0x23, 0x1D, 0x55, 0x9B, 0x51, 0xA7, 0xCA, 0xEF, 0xD9, 0x3F, 0x7E, 0xDB, 0x72,
+ 0xBC, 0x9E, 0x56, 0xE3, 0x09, 0x27, 0x42, 0xF8, 0xC3, 0x1A, 0x97, 0xB6, 0x34, 0xB5, 0x6C, 0x55,
+ 0x72, 0xA5, 0x6D, 0xD7, 0x28, 0xB4, 0x87, 0x2D, 0x5E, 0x80, 0xDF, 0x21, 0x34, 0x8C, 0xB3, 0x8E,
+ 0xF4, 0x6B, 0x05, 0x03, 0x54, 0xB2, 0x06, 0x4B, 0x7E, 0xAF, 0x53, 0x48, 0xDF, 0x35, 0x22, 0xD7,
+ 0x7F, 0x19, 0x41, 0xC9, 0xA8, 0x2C, 0x11, 0x22, 0x6A, 0xA4, 0x53, 0x44, 0x3D, 0x18, 0x40, 0x49,
+ 0x3F, 0x4A, 0xC4, 0x93, 0x9D, 0x4A, 0x7C, 0xE6, 0x2C, 0x2C, 0x5C, 0x01, 0x39, 0x5C, 0x1F, 0xC4,
+ 0x20, 0x3D, 0xDB, 0xF5, 0x23, 0x76, 0x2F, 0x6C, 0xD4, 0xCD, 0x2E, 0x00, 0x2B, 0x78, 0xE5, 0x13,
+ 0xD9, 0xA1, 0xC9, 0xEE, 0x58, 0xAE, 0x33, 0x5F, 0xA1, 0xA2, 0xAE, 0x31, 0xA3, 0xA0, 0x66, 0x96,
+ 0xC8, 0xD2, 0xC9, 0x82, 0x5B, 0x6C, 0x14, 0x25, 0x9A, 0x53, 0xB4, 0xC7, 0x37, 0x8E, 0x0D, 0xBF,
+ 0x13, 0x8D, 0x88, 0x51, 0xC9, 0xA8, 0x49, 0x21, 0x6C, 0x33, 0x38, 0xED, 0xA8, 0xAA, 0xF1, 0x5C,
+ 0x42, 0xB0, 0x9B, 0x24, 0xE2, 0xC9, 0x40, 0xF0, 0x20, 0xE4, 0x50, 0x24, 0xAA, 0xA7, 0x74, 0x6C,
+ 0x77, 0x32, 0xC1, 0xB0, 0xE3, 0xA3, 0xE2, 0xB3, 0xE1, 0x6A, 0x32, 0xC9, 0x59, 0x4A, 0xC1, 0x8F,
+ 0xF9, 0xE4, 0x1F, 0x7C, 0x21, 0x3E, 0xA4, 0x98, 0xD1, 0xE9, 0xA9, 0x6A, 0x4C, 0xC6, 0x52, 0x19,
+ 0x89, 0x42, 0x5E, 0x0C, 0x32, 0xBB, 0xF2, 0x23, 0xD7, 0x24, 0x74, 0x6D, 0x32, 0x6E, 0x42, 0x6D,
+ 0x91, 0x80, 0x41, 0xBF, 0x3F, 0x88, 0xF0, 0x5F, 0xB1, 0x39, 0x31, 0xEF, 0x4F, 0x19, 0x14, 0xED,
+ 0xC8, 0x9C, 0xAB, 0xA7, 0x8D, 0xD5, 0x34, 0x3A, 0x0A, 0x7F, 0x0E, 0xAE, 0x02, 0x33, 0xFD, 0xD0,
+ 0xD6, 0xD9, 0xF1, 0x56, 0x2D, 0x21, 0x92, 0x04, 0xD8, 0xBB, 0x67, 0x97, 0x31, 0xF9, 0xBA, 0x03,
+ 0xCD, 0xFB, 0x0E, 0x2C, 0x28, 0x6D, 0x07, 0x7C, 0x3F, 0xFF, 0x83, 0x81, 0xE3, 0xDC, 0x0B, 0xC5,
+ 0x5E, 0x89, 0x47, 0xBC, 0xA1, 0x1F, 0xA8, 0x79, 0x76, 0x88, 0x6B, 0x8A, 0x0F, 0xB2, 0x84, 0xD6,
+ 0xDC, 0x16, 0x78, 0x51, 0x3C, 0xDB, 0xD4, 0x8D, 0xD6, 0x26, 0xD7, 0xDD, 0x51, 0x5E, 0x8E, 0x5A,
+ 0xDD, 0x5D, 0x6D, 0x97, 0xB4, 0x33, 0x43, 0xAB, 0x16, 0x35, 0xA2, 0x9E, 0x46, 0x47, 0x47, 0x8B,
+ 0xE5, 0x39, 0xDD, 0xF1, 0x91, 0xAA, 0x28, 0x33, 0xC4, 0x44, 0x8A, 0x97, 0x32, 0x71, 0x96, 0xE6,
+ 0x03, 0xD1, 0xDC, 0xA7, 0x95, 0xEB, 0xA6, 0x77, 0x1D, 0x58, 0xDE, 0x15, 0x67, 0x59, 0x3E, 0xE3,
+ 0xE4, 0x6D, 0x7F, 0x72, 0x42, 0x63, 0xE9, 0xDD, 0x12, 0x5B, 0xCA, 0x86, 0xF0, 0xAA, 0x35, 0x2A,
+ 0x8F, 0x67, 0xED, 0x4D, 0x53, 0x8F, 0x6D, 0x69, 0x09, 0x51, 0xD9, 0x29, 0xCF, 0xC1, 0x9F, 0xD7,
+ 0x9B, 0x94, 0x1E, 0x4D, 0x99, 0x0E, 0xA1, 0xF0, 0x92, 0x26, 0x8B, 0xA5, 0x1A, 0xC9, 0x17, 0x03,
+ 0xAA, 0xCA, 0xC9, 0xB6, 0xC8, 0x44, 0xC8, 0xD8, 0x5C, 0x7E, 0xDF, 0xCC, 0x48, 0xC2, 0xC0, 0xB2,
+ 0xC9, 0x17, 0xC0, 0x8B, 0x14, 0xA9, 0x89, 0xA2, 0x2C, 0x36, 0x44, 0x5D, 0xB1, 0x4B, 0x66, 0x3A,
+ 0x21, 0x30, 0x26, 0x4D, 0xE7, 0x46, 0xB3, 0x2B, 0x77, 0xC5, 0xBC, 0x24, 0x1E, 0xB8, 0xFA, 0xC3,
+ 0xD5, 0x67, 0x31, 0x74, 0xD0, 0x30, 0x3F, 0x2F, 0xF6, 0xC3, 0x85, 0x98, 0x4F, 0x23, 0x41, 0xB3,
+ 0x1A, 0x0D, 0xF1, 0x6A, 0xD9, 0xAE, 0x56, 0xCA, 0xC8, 0x31, 0xEC, 0x5C, 0x45, 0x25, 0xE7, 0xD6,
+ 0xB0, 0xAA, 0x57, 0x2B, 0xE5, 0x39, 0x3C, 0x2E, 0x61, 0xD5, 0x0D, 0x1A, 0x65, 0x32, 0xE6, 0xBA,
+ 0x39, 0x08, 0x2F, 0x06, 0x22, 0x13, 0x6E, 0x7E, 0x72, 0xD7, 0x45, 0xE7, 0x83, 0xE0, 0x03, 0xCC,
+ 0x66, 0xB0, 0x3A, 0xC1, 0xD2, 0xD5, 0xCD, 0xE6, 0x0B, 0xC3, 0xB6, 0x2B, 0xB4, 0x30, 0xDF, 0x13,
+ 0x68, 0x3C, 0x1A, 0x49, 0xC4, 0x29, 0x51, 0xF4, 0x85, 0xAC, 0x82, 0xAF, 0x74, 0x43, 0xDA, 0x71,
+ 0xE3, 0xAB, 0x34, 0xA3, 0x59, 0xB2, 0xC5, 0x51, 0x70, 0x53, 0x51, 0xD3, 0xFD, 0x34, 0x53, 0x40,
+ 0x28, 0xD1, 0x49, 0xCF, 0x35, 0x34, 0x5F, 0xD0, 0xE0, 0x69, 0x02, 0xCD, 0x1A, 0x96, 0xED, 0x64,
+ 0xA6, 0x8E, 0x77, 0x66, 0x13, 0x76, 0xE5, 0x91, 0x15, 0x6E, 0x74, 0xFC, 0xAA, 0x77, 0x2C, 0x06,
+ 0xAE, 0xCD, 0xE4, 0x46, 0x79, 0xDA, 0x20, 0xAA, 0x21, 0x41, 0x10, 0x89, 0xB9, 0xC2, 0x7C, 0xFA,
+ 0x87, 0x37, 0xE4, 0x16, 0xF2, 0xBD, 0x44, 0xEF, 0xEA, 0x9D, 0xFD, 0x62, 0xC6, 0xCD, 0x38, 0x79,
+ 0x61, 0xF5, 0x79, 0xF0, 0x3C, 0x7A, 0x1F, 0x90, 0x41, 0xDA, 0x1D, 0x73, 0x50, 0x89, 0x05, 0x1C,
+ 0x42, 0x48, 0x9B, 0x21, 0xD6, 0x02, 0x29, 0x0B, 0xA5, 0x30, 0x42, 0x4F, 0x0B, 0xFF, 0x3F, 0x6D,
+ 0xF1, 0x2C, 0x0C, 0x5E, 0x1E, 0x98, 0x18, 0x64, 0xDE, 0x5C, 0x0E, 0xD2, 0x5D, 0x57, 0x7B, 0x70,
+ 0x98, 0x55, 0xE6, 0xBA, 0xAB, 0x5B, 0x98, 0x14, 0x22, 0xD0, 0xC0, 0x78, 0x2E, 0xD3, 0xCC, 0x8E,
+ 0x6E, 0x74, 0xB8, 0x5B, 0xCE, 0xF3, 0xFB, 0x25, 0x1F, 0x1F, 0xB0, 0x25, 0x3A, 0x57, 0x8E, 0xC9,
+ 0x56, 0x90, 0x59, 0x9C, 0x45, 0x5C, 0x5E, 0xC0, 0xC8, 0xBC, 0x1D, 0xED, 0xFB, 0x38, 0x22, 0xA4,
+ 0x32, 0xE8, 0xE8, 0xAC, 0x40, 0xEB, 0x96, 0x94, 0x8C, 0x99, 0x4A, 0xC0, 0xBC, 0xF0, 0xE3, 0x7C,
+ 0x2B, 0x71, 0x9B, 0xFD, 0x86, 0x1D, 0x34, 0x69, 0x46, 0xAD, 0xB2, 0x4A, 0x27, 0x8A, 0xEF, 0xF0,
+ 0xFA, 0x6F, 0x0F, 0xFB, 0x9F, 0x01, 0xBD, 0xBE, 0x3F, 0x11, 0x54, 0x22, 0x6E, 0xFF, 0x75, 0x56,
+ 0x07, 0x69, 0x43, 0x47, 0x19, 0xDC, 0x79, 0xFD, 0x7F, 0xAE, 0xF5, 0x7D, 0x90, 0x83, 0x39, 0xF0,
+ 0x4B, 0x6D, 0x4C, 0x49, 0xC6, 0xFD, 0xCE, 0xBE, 0xB8, 0xDF, 0xAE, 0x61, 0xA5, 0xAD, 0x2D, 0xD6,
+ 0xA0, 0xF4, 0xCC, 0x4B, 0x48, 0xBC, 0xA2, 0xE7, 0x64, 0x71, 0x3E, 0x4E, 0xEB, 0xBA, 0xC8, 0x72,
+ 0xF2, 0xBB, 0x59, 0x4E, 0xB5, 0x68, 0x8C, 0xA0, 0x2F, 0xEF, 0xFA, 0x6F, 0x7F, 0x2A, 0x45, 0x0D,
+ 0x78, 0xDF, 0x03, 0x5B, 0x22, 0x0C, 0x6B, 0xDC, 0x42, 0xD9, 0xB5, 0xA9, 0x5D, 0x5F, 0x3A, 0xBC,
+ 0xDB, 0x9D, 0xFD, 0x7F, 0xC1, 0xFA, 0x63, 0x81, 0xB0, 0x40, 0x02, 0xCC, 0x83, 0x95, 0x7E, 0xA1,
+ 0xD7, 0x1D, 0x1D, 0xC1, 0x30, 0x20, 0x18, 0x50, 0x89, 0x76, 0x56, 0x11, 0xE7, 0xEF, 0x5F, 0x98,
+ 0x7D, 0xCB, 0x42, 0x1C, 0x24, 0x10, 0x1D, 0x8F, 0x21, 0x3A, 0x82, 0x34, 0xDA, 0xFE, 0xA1, 0x1B,
+ 0x7C, 0x53, 0x2F, 0x77, 0x9E, 0x0E, 0x92, 0xD9, 0x5E, 0x9A, 0x77, 0xDD, 0xB1, 0x2D, 0xA8, 0x54,
+ 0xB1, 0x3D, 0x88, 0xF9, 0xB8, 0x1E, 0xC7, 0x81, 0xC2, 0xF7, 0x68, 0x0F, 0xEB, 0x1F, 0xCB, 0xD1,
+ 0xAD, 0x28, 0x31, 0x74, 0x54, 0x42, 0x2F, 0x28, 0x8C, 0x39, 0x96, 0xC1, 0xAA, 0x68, 0xA0, 0x42,
+ 0xA1, 0x97, 0x34, 0xD3, 0x3E, 0x9F, 0x9E, 0xCE, 0x22, 0x48, 0x88, 0x14, 0x1D, 0x94, 0x74, 0x8E,
+ 0x39, 0x42, 0x07, 0x0C, 0x5D, 0x0C, 0x70, 0x98, 0x34, 0x31, 0x16, 0xC0, 0xCF, 0xB7, 0xEF, 0xE5,
+ 0x6D, 0x21, 0x74, 0x28, 0xA4, 0x76, 0x77, 0x90, 0x92, 0xD1, 0xE7, 0xA6, 0x03, 0x01, 0x27, 0x9C,
+ 0x08, 0x95, 0x0E, 0x5D, 0x5B, 0x2A, 0x68, 0x14, 0xBB, 0xD5, 0x28, 0x44, 0xA6, 0xEE, 0x9B, 0xBA,
+ 0xF3, 0xD6, 0x87, 0x0B, 0x69, 0x9A, 0x54, 0x17, 0x49, 0x43, 0x64, 0xA3, 0x2A, 0x37, 0x32, 0x72,
+ 0xF1, 0x47, 0xFD, 0x42, 0x33, 0x9F, 0x0C, 0xCE, 0xB1, 0xCA, 0x99, 0x84, 0xB5, 0xAD, 0x4F, 0x4A,
+ 0x7E, 0x25, 0x6C, 0xC0, 0xBA, 0x65, 0x13, 0x8C, 0xAE, 0xD9, 0xC1, 0xF4, 0xAE, 0x9B, 0x1A, 0x09,
+ 0x34, 0xF0, 0x9B, 0x3C, 0x0F, 0xBE, 0x81, 0xE7, 0x2A, 0x86, 0xB5, 0x93, 0xA1, 0x20, 0x20, 0x0B,
+ 0x2A, 0x85, 0x02, 0xFE, 0xA0, 0xF5, 0x43, 0xF4, 0x12, 0xF1, 0xC8, 0x8D, 0xC1, 0xBF, 0xB8, 0x1B,
+ 0x8E, 0xA4, 0x7F, 0xD7, 0xF0, 0x8D, 0x28, 0xF1, 0x8D, 0xF9, 0x25, 0x77, 0x6C, 0x24, 0x1D, 0x92,
+ 0xB0, 0x1C, 0xC6, 0x63, 0x33, 0x75, 0xE1, 0xD2, 0xD8, 0xB6, 0xA6, 0x5B, 0x2F, 0xDD, 0xF5, 0xF7,
+ 0xB8, 0x3D, 0xF7, 0xAC, 0x8B, 0x9F, 0x13, 0xEF, 0xC4, 0x98, 0x73, 0x27, 0x68, 0xF5, 0xED, 0x62,
+ 0x2A, 0x99, 0x50, 0xC1, 0x4C, 0xAB, 0x56, 0xC8, 0x05, 0x94, 0x1F, 0xED, 0x5A, 0x9C, 0xFC, 0x46,
+ 0x22, 0x4E, 0xB2, 0x5E, 0x6A, 0x47, 0x77, 0x1D, 0x8B, 0x6D, 0x10, 0x12, 0xBB, 0x8A, 0xAE, 0xAD,
+ 0xA7, 0x20, 0x2F, 0x22, 0xE5, 0xB9, 0xB9, 0x71, 0x27, 0xC9, 0x01, 0xD5, 0xC9, 0x88, 0x49, 0xB6,
+ 0x07, 0xB2, 0xD6, 0x8B, 0xA1, 0xBA, 0xA9, 0x5B, 0xC4, 0xBA, 0xC3, 0x1B, 0x5B, 0xBA, 0x03, 0x99,
+ 0x41, 0x11, 0xEF, 0x6C, 0xB4, 0x78, 0x8E, 0x16, 0xF5, 0x60, 0x44, 0x2F, 0x54, 0xB7, 0xD4, 0x74,
+ 0xC3, 0xCD, 0xE4, 0x45, 0x2C, 0x1D, 0xD0, 0x34, 0xD9, 0x4E, 0x97, 0xAF, 0x89, 0x87, 0xA1, 0x1C,
+ 0x93, 0x04, 0x56, 0xEB, 0xCD, 0xB3, 0xAC, 0xE2, 0x04, 0x19, 0x8C, 0xFF, 0xAB, 0x7B, 0x37, 0x13,
+ 0x92, 0xA6, 0x07, 0x22, 0x36, 0x83, 0xDA, 0xD7, 0xE7, 0xEA, 0x76, 0x42, 0x63, 0x79, 0xCD, 0xCD,
+ 0x3F, 0x58, 0x88, 0xE4, 0x58, 0xB6, 0x7B, 0xFC, 0x86, 0x4D, 0xE1, 0xFA, 0xD1, 0xFD, 0x71, 0x32,
+ 0xD1, 0xA8, 0xAA, 0x71, 0x21, 0xEB, 0x0F, 0xF2, 0x6A, 0x7C, 0xF4, 0xD5, 0xDB, 0xEA, 0x6F, 0x5D,
+ 0xEE, 0x66, 0x24, 0xBB, 0x50, 0xA7, 0x19, 0x44, 0x95, 0xBA, 0xE2, 0x2D, 0x81, 0xC9, 0xE5, 0x59,
+ 0x7C, 0xA5, 0xD6, 0xA1, 0x6D, 0xE1, 0xC5, 0x9B, 0x32, 0xD9, 0x4A, 0xBC, 0x79, 0x34, 0xA0, 0x54,
+ 0xA6, 0x86, 0x6B, 0x86, 0xA6, 0x30, 0xA2, 0x68, 0xBB, 0x95, 0x11, 0x99, 0x88, 0xA5, 0x83, 0x42,
+ 0x38, 0xC0, 0xD5, 0xE2, 0xDF, 0xD5, 0x35, 0x62, 0x71, 0x38, 0x27, 0x97, 0x87, 0xD7, 0xC7, 0x22,
+ 0x1E, 0x90, 0x63, 0xDC, 0x62, 0x3B, 0x57, 0x6A, 0xE2, 0x89, 0xC1, 0xC2, 0xA3, 0x8A, 0x36, 0x14,
+ 0x80, 0x22, 0x4C, 0xAF, 0x83, 0x7C, 0x27, 0x2C, 0x2D, 0xA7, 0x22, 0xAD, 0x1C, 0x32, 0x38, 0x3E,
+ 0x14, 0x30, 0x5B, 0x57, 0x35, 0x74, 0x6C, 0x8B, 0x04, 0x39, 0x01, 0x11, 0x74, 0x4A, 0x12, 0x38,
+ 0xE1, 0x6D, 0x0C, 0xCB, 0x19, 0x06, 0x0F, 0x49, 0x48, 0x9A, 0x46, 0xBB, 0x37, 0x1F, 0x88, 0x04,
+ 0x0D, 0x41, 0xA5, 0xD1, 0x82, 0x9A, 0x48, 0xCA, 0xAF, 0xEC, 0x8D, 0x4C, 0x16, 0x4E, 0xAE, 0xA4,
+ 0x6C, 0x5E, 0x44, 0xA5, 0x37, 0xA3, 0x13, 0xBA, 0x55, 0x60, 0x68, 0xE3, 0x34, 0x25, 0x85, 0xEB,
+ 0x01, 0x7A, 0x4E, 0xCD, 0x07, 0xFD, 0xD3, 0xB3, 0xD3, 0xF3, 0xFB, 0x16, 0x4E, 0x55, 0x0D, 0x2F,
+ 0x1A, 0xF0, 0x1C, 0xFC, 0x5F, 0x18, 0x93, 0x16, 0xDD, 0x7C, 0x8C, 0x74, 0x40, 0x57, 0x78, 0x94,
+ 0x52, 0x92, 0xD1, 0xB6, 0xEF, 0xFD, 0xA5, 0xDC, 0x37, 0xE9, 0x21, 0x26, 0xED, 0x75, 0xCF, 0x6F,
+ 0xF4, 0x36, 0x96, 0xAE, 0x2C, 0xF1, 0x41, 0x6D, 0x66, 0x98, 0xD3, 0x8C, 0x39, 0xCA, 0x2B, 0xA0,
+ 0x49, 0x5E, 0xAA, 0x85, 0x85, 0x5F, 0xB7, 0x6A, 0xEF, 0xD8, 0x35, 0xBF, 0xCB, 0xCE, 0x6C, 0x09,
+ 0x71, 0xA2, 0x14, 0x9E, 0x31, 0x34, 0xB5, 0xC3, 0x0A, 0xD5, 0xBD, 0x75, 0x86, 0xE6, 0x48, 0x8B,
+ 0xC8, 0xED, 0x6B, 0x8F, 0x2C, 0x86, 0xE0, 0xED, 0xF5, 0xF2, 0xC8, 0x35, 0x6F, 0xBE, 0x71, 0x3A,
+ 0x5A, 0x9A, 0xEC, 0xEA, 0x54, 0x3A, 0x17, 0x76, 0x4E, 0xA4, 0x78, 0x66, 0x6B, 0xB2, 0xBD, 0x3C,
+ 0x8E, 0x28, 0x3D, 0x3C, 0xDA, 0xCA, 0x78, 0xF3, 0x9E, 0x43, 0x32, 0xD6, 0xFB, 0xA3, 0xD8, 0x3E,
+ 0x8F, 0xE3, 0xF9, 0x2C, 0xA7, 0xE2, 0x6A, 0xA9, 0x5C, 0x76, 0x82, 0xF4, 0x5F, 0x34, 0x7D, 0x8E,
+ 0x80, 0x90, 0xE9, 0xA0, 0x70, 0xA8, 0x96, 0xFB, 0x7E, 0xF0, 0xC7, 0x6B, 0xDE, 0xFB, 0xDE, 0xDA,
+ 0x76, 0x01, 0x03, 0x68, 0x07, 0x2F, 0x45, 0xD9, 0x86, 0x5C, 0xD4, 0x4C, 0xAF, 0x8D, 0x86, 0x19,
+ 0x46, 0x62, 0x86, 0x29, 0x25, 0xB6, 0x57, 0x7F, 0x7D, 0x49, 0xAF, 0x79, 0x5E, 0x3C, 0x2B, 0x0A,
+ 0x87, 0xA6, 0x03, 0xE6, 0xD4, 0xD9, 0xBB, 0xBA, 0xB2, 0xD1, 0xAA, 0x71, 0xC9, 0x86, 0xE6, 0x64,
+ 0x78, 0x84, 0xF5, 0x72, 0x82, 0x80, 0xB4, 0xED, 0xC8, 0x16, 0xCD, 0x7F, 0x90, 0x16, 0x7C, 0x0A,
+ 0x82, 0x99, 0xD3, 0xF9, 0x28, 0x36, 0x93, 0xE0, 0x2D, 0xF5, 0x74, 0x67, 0x79, 0xC1, 0x32, 0x84,
+ 0x78, 0x37, 0xA7, 0x15, 0xAF, 0x8B, 0x26, 0x46, 0x4B, 0x91, 0x77, 0x57, 0x3E, 0x47, 0x5B, 0xEA,
+ 0x0F, 0xEA, 0x7F, 0xBA, 0x69, 0x87, 0x44, 0x39, 0xA7, 0xA9, 0x8C, 0x1C, 0x89, 0x84, 0xF6, 0xE6,
+ 0xE5, 0x8C, 0x87, 0x59, 0xD3, 0xF0, 0xA7, 0x98, 0xC2, 0xBC, 0x98, 0x53, 0xC0, 0x64, 0xD4, 0x3F,
+ 0x2A, 0xC8, 0xDF, 0x29, 0x70, 0x84, 0x86, 0x62, 0x58, 0x0C, 0xE7, 0x73, 0x04, 0x89, 0xF2, 0x20,
+ 0x15, 0xFB, 0x2E, 0xFC, 0xC1, 0x59, 0x18, 0xB8, 0x52, 0x46, 0x78, 0x09, 0xF9, 0xC3, 0x28, 0xC5,
+ 0xA5, 0x04, 0xB4, 0x42, 0xC0, 0x75, 0x44, 0x18, 0x3D, 0xCF, 0x8D, 0x36, 0x4C, 0xA2, 0x73, 0x18,
+ 0x7A, 0xAD, 0xBA, 0xDC, 0xB3, 0x2E, 0x30, 0xE6, 0x73, 0x11, 0x20, 0xFC, 0xE9, 0x1B, 0xB0, 0xF2,
+ 0x2D, 0xED, 0xA0, 0x17, 0x55, 0x63, 0xB2, 0x46, 0xCB, 0xAC, 0xB4, 0x3B, 0x1F, 0xCA, 0x9A, 0xF5,
+ 0x50, 0xBF, 0xB7, 0xD2, 0x0A, 0xFA, 0xE7, 0x72, 0x6E, 0x14, 0xEA, 0xA3, 0x05, 0x78, 0xF7, 0x75,
+ 0xD7, 0x06, 0xF8, 0x2D, 0xE6, 0x4C, 0x71, 0x27, 0xD2, 0x84, 0xF9, 0xA0, 0x5C, 0xDA, 0x1F, 0x69,
+ 0x1E, 0xEC, 0xF6, 0x7C, 0xB2, 0xC8, 0xEF, 0x7C, 0xF7, 0x37, 0xDB, 0xD3, 0x03, 0x6F, 0xFB, 0xCF,
+ 0xE0, 0x87, 0xE1, 0x33, 0x60, 0xC4, 0xF5, 0x17, 0xC6, 0x08, 0x50, 0x88, 0x86, 0x58, 0xA2, 0x90,
+ 0xCB, 0xE7, 0x15, 0x47, 0x15, 0x15, 0xE4, 0x33, 0x9D, 0x4A, 0xF2, 0xA7, 0xE6, 0xA7, 0x2E, 0x73,
+ 0x94, 0x75, 0x37, 0xC2, 0x8F, 0xB5, 0xBC, 0xA6, 0xB5, 0x05, 0xAB, 0xC7, 0x3C, 0xCC, 0x36, 0xEA,
+ 0x89, 0x3C, 0xAF, 0xC8, 0xC3, 0xB1, 0x14, 0x02, 0x43, 0x90, 0xE6, 0xE5, 0x4A, 0x2D, 0x8A, 0xAC,
+ 0x41, 0xF5, 0xAF, 0x0D, 0x3F, 0x6C, 0x3B, 0x4B, 0xA6, 0xC3, 0x70, 0x7E, 0x8B, 0x82, 0xC1, 0x40,
+ 0x26, 0x0B, 0x65, 0xC3, 0x60, 0x54, 0x5E, 0xF8, 0x53, 0x96, 0x15, 0x74, 0x1A, 0x11, 0xF0, 0x66,
+ 0x36, 0xAE, 0x3A, 0x11, 0x01, 0xDE, 0x67, 0x18, 0x6D, 0x35, 0x6A, 0x93, 0x13, 0x99, 0x74, 0xBC,
+ 0x17, 0x4E, 0x68, 0x86, 0x3F, 0x10, 0x9A, 0x08, 0xEB, 0xD3, 0x8F, 0xB7, 0x19, 0xC6, 0x39, 0x49,
+ 0xC9, 0x8A, 0x2F, 0x42, 0xE6, 0x0F, 0x31, 0xFE, 0x69, 0x13, 0xAF, 0x51, 0x62, 0xF5, 0x79, 0xF8,
+ 0x0E, 0xBC, 0x46, 0xB3, 0x6E, 0x56, 0xF6, 0xE4, 0x68, 0x25, 0x1F, 0x31, 0x08, 0x55, 0xAA, 0x7F,
+ 0x62, 0xAE, 0xF2, 0xB3, 0x14, 0xFF, 0xCC, 0xCC, 0xCC, 0x77, 0x53, 0x8B, 0x1B, 0x6D, 0xBA, 0x8D,
+ 0x41, 0xB4, 0xB9, 0x3C, 0x1E, 0x83, 0xAB, 0x77, 0x31, 0xEE, 0xC4, 0x9D, 0xCE, 0x24, 0x3C, 0x43,
+ 0xC2, 0x05, 0x9D, 0x5E, 0xAB, 0x17, 0x03, 0xF5, 0x82, 0x28, 0xC8, 0xB3, 0x2E, 0xBC, 0x10, 0x0A,
+ 0x91, 0x19, 0x98, 0x20, 0xF0, 0x76, 0x4D, 0x31, 0x7C, 0xBA, 0xC4, 0x5B, 0x7C, 0x39, 0xC9, 0x0A,
+ 0x04, 0xEB, 0x63, 0x28, 0x39, 0xEA, 0x37, 0x96, 0xC5, 0xCE, 0xE8, 0xB5, 0xA5, 0x7A, 0x40, 0x48,
+ 0x64, 0xC3, 0x99, 0x3A, 0xE1, 0x98, 0x8D, 0x52, 0x49, 0x6D, 0xB6, 0x6B, 0x9C, 0x3A, 0x5B, 0x8E,
+ 0x3C, 0xD8, 0x4B, 0xC2, 0x6F, 0xC9, 0xA6, 0x20, 0xDA, 0xBA, 0xC4, 0xD2, 0x52, 0x38, 0x0E, 0x69,
+ 0x9D, 0x63, 0x59, 0xC9, 0xE4, 0x31, 0x0B, 0xA6, 0x32, 0x91, 0x85, 0xED, 0x41, 0x99, 0x32, 0x4B,
+ 0xAA, 0x99, 0x8A, 0x22, 0xC5, 0x29, 0x06, 0x82, 0x5C, 0x3A, 0xC1, 0x73, 0x88, 0x8A, 0x94, 0x63,
+ 0x0D, 0xFF, 0x75, 0x83, 0x75, 0xFC, 0x39, 0x7C, 0x19, 0x3A, 0x09, 0xAA, 0xE0, 0x9A, 0x7E, 0xA9,
+ 0x54, 0x4C, 0xE8, 0x20, 0x93, 0x00, 0x19, 0x3A, 0xA2, 0x3D, 0x57, 0x53, 0x9E, 0xAD, 0x45, 0x23,
+ 0x24, 0x41, 0xDC, 0x5F, 0x4E, 0x97, 0x7E, 0x19, 0x8E, 0xF0, 0x1C, 0x45, 0x92, 0x34, 0x8A, 0x14,
+ 0x9F, 0xF7, 0xB3, 0x30, 0xB1, 0xC1, 0xB8, 0x72, 0xC3, 0xDD, 0x9E, 0x01, 0xE2, 0x74, 0x37, 0x26,
+ 0x21, 0x5D, 0x8A, 0x0A, 0x24, 0x06, 0x7E, 0x50, 0x68, 0x31, 0x21, 0x38, 0x48, 0x81, 0x6C, 0x3B,
+ 0xAE, 0x63, 0x78, 0xE0, 0x31, 0x6C, 0xBB, 0x25, 0xF6, 0x58, 0x81, 0xF7, 0x48, 0x06, 0xC3, 0x6D,
+ 0xF8, 0xB2, 0x78, 0x2B, 0x90, 0x77, 0x31, 0x24, 0xA9, 0xF9, 0x49, 0x86, 0xC7, 0xD0, 0xC5, 0xA4,
+ 0xC3, 0x49, 0x23, 0x1E, 0x26, 0xC9, 0xA8, 0x38, 0x2A, 0xB7, 0x15, 0x39, 0x4A, 0xE4, 0x72, 0xE1,
+ 0x30, 0xD3, 0xD3, 0x4A, 0xF0, 0xC7, 0xE1, 0x56, 0x0C, 0xCA, 0xF3, 0xB5, 0x1C, 0x47, 0x67, 0x22,
+ 0x7E, 0x8C, 0xB5, 0x0C, 0x55, 0x20, 0x55, 0xE3, 0xBA, 0xAB, 0xEF, 0xDE, 0x89, 0x16, 0x4D, 0x93,
+ 0x68, 0x07, 0x03, 0x86, 0xF1, 0x04, 0x89, 0xC7, 0xF9, 0x02, 0xC6, 0xCA, 0x15, 0xF8, 0x2B, 0x8C,
+ 0x95, 0x37, 0xF7, 0x63, 0xA9, 0x48, 0x3C, 0x1C, 0xA0, 0x4A, 0x7F, 0x33, 0x09, 0xBA, 0x13, 0x14,
+ 0x9A, 0x20, 0x51, 0xBB, 0x8E, 0x3A, 0x13, 0xED, 0x17, 0x56, 0x74, 0x72, 0xEE, 0x2C, 0x8C, 0xAC,
+ 0x27, 0xA9, 0xAF, 0x17, 0x89, 0x79, 0x19, 0xDA, 0xE0, 0x12, 0x5E, 0x71, 0xE1, 0x72, 0x64, 0x98,
+ 0xA5, 0xE1, 0x15, 0x60, 0x2A, 0xD4, 0x10, 0x8C, 0xAD, 0xD3, 0xAA, 0xE3, 0x4A, 0x15, 0x84, 0x75,
+ 0xB6, 0x2B, 0x3D, 0x31, 0x4A, 0x99, 0x22, 0xDA, 0x6E, 0xBC, 0xDF, 0x41, 0x95, 0x4C, 0x21, 0x1E,
+ 0xA5, 0x4D, 0x24, 0x68, 0xE9, 0x6C, 0x84, 0x20, 0x52, 0x11, 0x41, 0x09, 0x6B, 0x34, 0x1D, 0xA6,
+ 0x35, 0xBF, 0xC4, 0x32, 0xD4, 0x9B, 0x31, 0xF8, 0xD5, 0x04, 0x56, 0x84, 0x04, 0x45, 0xDB, 0xA2,
+ 0xE4, 0x4F, 0xCF, 0x53, 0xDA, 0xB4, 0x3F, 0x49, 0x10, 0xE4, 0x0E, 0x27, 0x68, 0xFB, 0xA1, 0xE2,
+ 0x47, 0x96, 0xBF, 0x5A, 0x4A, 0x92, 0x28, 0xEA, 0x67, 0x93, 0x7A, 0xF4, 0xC7, 0x8D, 0x30, 0x84,
+ 0xE6, 0x01, 0x0A, 0x2A, 0xFC, 0xED, 0xA3, 0xFB, 0x28, 0x85, 0xD5, 0x18, 0x35, 0x75, 0x64, 0x33,
+ 0x25, 0xD5, 0x54, 0x23, 0xBA, 0x58, 0x39, 0x7B, 0xE3, 0x30, 0x8A, 0x83, 0xC6, 0xE1, 0x0F, 0x41,
+ 0x01, 0x64, 0xFA, 0x72, 0x3A, 0xAE, 0x10, 0x72, 0xF8, 0x17, 0xC5, 0xBC, 0xFE, 0x4B, 0x9A, 0xD9,
+ 0xB7, 0x56, 0x61, 0x70, 0xC9, 0x3B, 0x51, 0x54, 0x86, 0x54, 0xAC, 0xA0, 0x0A, 0x95, 0x1C, 0x86,
+ 0x39, 0x5C, 0x5F, 0x35, 0xE9, 0x05, 0x3F, 0xAB, 0xC8, 0x4B, 0xC4, 0x0B, 0x68, 0xF2, 0x43, 0x1F,
+ 0x8A, 0x18, 0xF1, 0xC9, 0x6A, 0x26, 0x65, 0x0B, 0xAF, 0x64, 0x59, 0xA3, 0x9C, 0xB1, 0x9C, 0x30,
+ 0x03, 0x25, 0x48, 0x37, 0xC2, 0x7A, 0x2B, 0x69, 0x26, 0x0B, 0x95, 0x40, 0x08, 0x7E, 0x1E, 0x8F,
+ 0x26, 0xFA, 0x27, 0xCF, 0xA2, 0xFA, 0xF6, 0x07, 0xF7, 0xD7, 0x6C, 0x6B, 0x96, 0x6C, 0xCC, 0x66,
+ 0x4B, 0x93, 0x26, 0x91, 0xA1, 0x94, 0xA5, 0x91, 0x0C, 0x36, 0xEC, 0x05, 0xD2, 0x1F, 0x4F, 0x0D,
+ 0x22, 0x36, 0xC4, 0xBB, 0xE0, 0x73, 0x60, 0x0B, 0xA8, 0xF4, 0x8D, 0x4D, 0x33, 0xBD, 0xD4, 0xDC,
+ 0x68, 0x32, 0x3E, 0x91, 0xDB, 0x9A, 0xFD, 0x55, 0x30, 0x40, 0x11, 0xAE, 0xD2, 0x1A, 0x38, 0xC2,
+ 0x2E, 0xF3, 0xB1, 0x6F, 0x4D, 0x0D, 0xCB, 0xDA, 0x14, 0x88, 0x61, 0x88, 0x5B, 0xE3, 0x49, 0x7B,
+ 0xCB, 0x81, 0x01, 0x0A, 0xB9, 0x21, 0x46, 0xE3, 0x5A, 0x76, 0x9E, 0xD4, 0x70, 0xC7, 0xE1, 0x78,
+ 0xA0, 0x11, 0xE3, 0xE6, 0xB6, 0x67, 0x0B, 0xD2, 0xC4, 0x1B, 0xF2, 0xCB, 0xC9, 0x43, 0x82, 0x5F,
+ 0x26, 0x0B, 0x82, 0x22, 0x84, 0x32, 0x7E, 0x7F, 0x5E, 0x4E, 0x71, 0xBA, 0xA2, 0x89, 0x58, 0x3D,
+ 0x0B, 0xB1, 0x46, 0xB5, 0x64, 0xF2, 0x1C, 0xF7, 0x88, 0xC4, 0xF9, 0x67, 0xC6, 0x09, 0xD5, 0x66,
+ 0x03, 0xD5, 0x34, 0x1D, 0x75, 0x92, 0xD3, 0x5A, 0x22, 0xA9, 0x45, 0xCC, 0x30, 0xB7, 0x57, 0xAE,
+ 0x75, 0x8C, 0x48, 0xA1, 0xC4, 0xC1, 0x07, 0xBA, 0x0F, 0x34, 0xDE, 0xA0, 0xC2, 0x08, 0x7B, 0xD8,
+ 0x1F, 0xB1, 0xCB, 0x8D, 0x86, 0xD2, 0xD3, 0x13, 0xB1, 0x74, 0x58, 0xD4, 0x50, 0xFE, 0xBA, 0xFB,
+ 0x0F, 0x56, 0x48, 0xDF, 0x3E, 0xF6, 0xD4, 0x6B, 0xE9, 0x28, 0x86, 0x27, 0x4B, 0x13, 0x6C, 0xEE,
+ 0x64, 0xA4, 0xBB, 0xA9, 0x52, 0x8A, 0x94, 0xE3, 0x72, 0x2D, 0x48, 0xB6, 0x4A, 0xB4, 0xA0, 0xEB,
+ 0x16, 0x6D, 0x78, 0x79, 0x45, 0xCF, 0xA1, 0x04, 0xFC, 0x25, 0x98, 0x03, 0x3B, 0xFB, 0x49, 0x3C,
+ 0xBF, 0x31, 0xBF, 0xA9, 0x81, 0x52, 0x3E, 0x9D, 0xA2, 0x1B, 0x63, 0x75, 0xF1, 0x67, 0xF3, 0x73,
+ 0x7F, 0x34, 0x3F, 0x73, 0xD7, 0x7C, 0x1D, 0x8D, 0x35, 0xFE, 0xD5, 0x2A, 0xC1, 0xCC, 0x8B, 0x43,
+ 0xB8, 0x2F, 0x32, 0xEF, 0x06, 0x21, 0xFE, 0xCC, 0x30, 0xC9, 0x96, 0x66, 0x68, 0x37, 0x10, 0x43,
+ 0x58, 0x66, 0x14, 0x6B, 0x47, 0x57, 0x4B, 0x78, 0x81, 0xAB, 0xAC, 0x5B, 0xFD, 0x3C, 0x74, 0xA1,
+ 0x79, 0x6E, 0x90, 0x6C, 0xDB, 0x2B, 0x13, 0x54, 0x88, 0x41, 0x04, 0x07, 0x25, 0xFC, 0xA1, 0xB4,
+ 0x8F, 0xD6, 0x35, 0xDD, 0x6C, 0x18, 0x05, 0xDE, 0xF6, 0xCB, 0x2D, 0xF3, 0x78, 0x3A, 0x53, 0xD4,
+ 0x7D, 0x99, 0xB8, 0xBC, 0xA9, 0x56, 0x8F, 0x65, 0x82, 0xF2, 0xEB, 0x04, 0x4E, 0x0F, 0x1E, 0x93,
+ 0x5A, 0x4D, 0xF1, 0x06, 0x8D, 0xD3, 0x5B, 0x6A, 0x72, 0xD3, 0xD8, 0xD6, 0x48, 0x30, 0xC4, 0x08,
+ 0xCA, 0x0E, 0x49, 0x0F, 0x1A, 0x14, 0x42, 0x62, 0x68, 0xD1, 0xDF, 0xA5, 0x55, 0xCB, 0x62, 0xB1,
+ 0x5C, 0xDD, 0xCD, 0xB1, 0x61, 0x55, 0xD1, 0x8C, 0x88, 0x8F, 0x1F, 0x9F, 0x5F, 0x0C, 0xD8, 0x3B,
+ 0xE8, 0xEC, 0x9B, 0x98, 0x82, 0x6D, 0x87, 0xC9, 0x25, 0x86, 0x64, 0xC2, 0xB6, 0x24, 0x85, 0x27,
+ 0x2A, 0x27, 0x2A, 0x3E, 0x92, 0x1A, 0xC8, 0xAA, 0x30, 0x0A, 0xE3, 0x79, 0x19, 0x71, 0xFD, 0x03,
+ 0xB5, 0x00, 0xAC, 0xF9, 0x9D, 0xDC, 0xAF, 0xEB, 0xE2, 0xBF, 0xD5, 0xC1, 0x08, 0x85, 0x46, 0x10,
+ 0x1A, 0x89, 0xFF, 0x2B, 0xFC, 0xCD, 0x15, 0x8A, 0xF3, 0x82, 0x7A, 0xE1, 0x92, 0xC2, 0x5C, 0xD7,
+ 0x35, 0x9E, 0xCE, 0x74, 0x53, 0x64, 0x31, 0xB1, 0x20, 0x8F, 0x71, 0x89, 0x61, 0x81, 0x30, 0x31,
+ 0x08, 0x53, 0x22, 0xB7, 0xBC, 0xD0, 0xDD, 0x0B, 0x08, 0x85, 0x5F, 0x83, 0xB8, 0xC4, 0x5E, 0x5E,
+ 0x74, 0x02, 0x46, 0xCC, 0x92, 0x39, 0x41, 0xA6, 0x14, 0x41, 0x35, 0xB1, 0xB8, 0x35, 0x4D, 0xB3,
+ 0xE1, 0x04, 0x78, 0xD9, 0x20, 0x4A, 0xBC, 0x68, 0x8B, 0x69, 0x27, 0x37, 0x16, 0x0D, 0x24, 0xD1,
+ 0xC7, 0x6B, 0xF7, 0xCC, 0xFE, 0x42, 0xAA, 0xDE, 0x24, 0xCA, 0x8E, 0x55, 0xE9, 0xE6, 0x6A, 0x8B,
+ 0xDA, 0x78, 0x22, 0xA0, 0x5A, 0xAA, 0x24, 0x27, 0x64, 0x41, 0xE6, 0xBF, 0x9F, 0xCE, 0x44, 0x7C,
+ 0x8D, 0xEB, 0xBA, 0x2D, 0x78, 0x71, 0xD7, 0xC0, 0x8B, 0xF5, 0x1F, 0xF0, 0xD3, 0x88, 0x00, 0x0D,
+ 0x3C, 0xA6, 0x70, 0xD1, 0x52, 0x44, 0x10, 0x57, 0x12, 0x11, 0x05, 0xFC, 0x62, 0xB4, 0xE2, 0x1F,
+ 0xAD, 0x3D, 0x3E, 0xAA, 0xA9, 0xFF, 0xEE, 0x8F, 0x04, 0x2E, 0x90, 0xEE, 0xBE, 0x3C, 0x98, 0xFC,
+ 0x3D, 0x83, 0x70, 0x43, 0x06, 0xC7, 0x86, 0xB4, 0x60, 0x6B, 0xB8, 0xBA, 0x05, 0xC8, 0x78, 0x5A,
+ 0xA6, 0xE7, 0xAE, 0x2D, 0x1A, 0x56, 0xC8, 0x34, 0xB0, 0x80, 0x55, 0x48, 0x19, 0x0D, 0x0A, 0x55,
+ 0xDD, 0x8A, 0xC2, 0x4F, 0x87, 0xA7, 0xB3, 0xA9, 0xE0, 0x88, 0x1D, 0x8B, 0x8B, 0xE3, 0xC5, 0x0F,
+ 0xFE, 0xA1, 0xA1, 0xDA, 0x9A, 0x14, 0x8C, 0xF4, 0x90, 0x60, 0x25, 0xF6, 0xCB, 0xBB, 0x29, 0x81,
+ 0x21, 0x0F, 0x85, 0x63, 0xFE, 0x60, 0x4C, 0xCD, 0x53, 0x66, 0xB1, 0xF6, 0x9A, 0xC4, 0x7C, 0x86,
+ 0x80, 0x14, 0x61, 0xC5, 0xA3, 0xCD, 0x6F, 0x30, 0x90, 0x10, 0x34, 0x49, 0x95, 0x82, 0xBE, 0x0A,
+ 0xE7, 0x13, 0x48, 0xC8, 0x98, 0x0A, 0x47, 0x9D, 0x4A, 0xE6, 0xE2, 0x45, 0xC5, 0x10, 0x08, 0x2C,
+ 0xBA, 0xF1, 0xB8, 0xE8, 0xD5, 0x57, 0xC1, 0x26, 0x7A, 0x1A, 0xDB, 0x8A, 0xCB, 0x7D, 0xAC, 0x55,
+ 0x34, 0x10, 0xC0, 0x7A, 0x69, 0x99, 0x5B, 0x35, 0xF4, 0x11, 0x35, 0x11, 0x1F, 0x01, 0x91, 0xB0,
+ 0x43, 0xD8, 0x48, 0x12, 0x29, 0x82, 0x0C, 0x20, 0x8E, 0xD5, 0x54, 0x3C, 0xC0, 0x8B, 0x90, 0xBD,
+ 0x7C, 0x37, 0xA8, 0x81, 0x7B, 0x6B, 0x58, 0xFE, 0xD4, 0xF3, 0x86, 0xBC, 0xC6, 0xF8, 0x49, 0x16,
+ 0x2F, 0x61, 0x32, 0x91, 0x99, 0x84, 0xA3, 0x99, 0x64, 0xB3, 0xDE, 0xC2, 0xAF, 0xAD, 0x0E, 0xB4,
+ 0xB0, 0x2E, 0x71, 0x73, 0x23, 0x19, 0x37, 0x49, 0xCE, 0xB4, 0x3B, 0x10, 0x36, 0xAF, 0xCB, 0x6F,
+ 0x9B, 0x88, 0xC5, 0x26, 0xB6, 0x16, 0xAE, 0x6B, 0x46, 0xEC, 0x6E, 0xAA, 0x51, 0x0E, 0xF9, 0x9A,
+ 0x67, 0x96, 0xA6, 0xDE, 0x5C, 0x1C, 0xDD, 0xDE, 0x28, 0xBD, 0x79, 0x6A, 0x69, 0xA9, 0x9C, 0x78,
+ 0xFD, 0x44, 0x8B, 0xD7, 0x27, 0xCB, 0xAF, 0x2F, 0x25, 0xBD, 0x68, 0xC3, 0xEA, 0xB3, 0xE0, 0x9D,
+ 0xE8, 0x3B, 0x80, 0x00, 0xD1, 0xBE, 0x80, 0xAD, 0x63, 0x02, 0x10, 0xE8, 0x76, 0x88, 0x99, 0x71,
+ 0x7D, 0x8F, 0x2A, 0x30, 0x0C, 0x01, 0x38, 0x49, 0xAD, 0xF1, 0xCE, 0x43, 0x87, 0x74, 0xF4, 0x0C,
+ 0xB8, 0x72, 0xC4, 0x01, 0x3F, 0x1E, 0x53, 0x02, 0x80, 0xE5, 0xC4, 0xAA, 0xDF, 0x37, 0x12, 0xE0,
+ 0xB9, 0x11, 0xC6, 0xD5, 0xFF, 0x12, 0xF2, 0x34, 0xAA, 0x86, 0x12, 0x20, 0x18, 0x60, 0x58, 0xE6,
+ 0xFF, 0xE9, 0x88, 0xE1, 0x60, 0x78, 0x45, 0xD8, 0x6C, 0x0C, 0x86, 0xDC, 0xAE, 0x40, 0x77, 0x06,
+ 0xBC, 0x06, 0xDB, 0x1D, 0x72, 0x03, 0x36, 0xAF, 0x18, 0xAC, 0x37, 0x01, 0x90, 0x7A, 0xF1, 0x60,
+ 0x97, 0xBC, 0x59, 0xC0, 0x3D, 0x9F, 0x07, 0xEF, 0x45, 0x06, 0xDC, 0x0B, 0x1C, 0xD0, 0xEC, 0xAB,
+ 0xA2, 0x49, 0x00, 0x93, 0x60, 0x2D, 0x65, 0xD5, 0xB4, 0x9C, 0xD5, 0x95, 0xB3, 0xE0, 0xCC, 0x39,
+ 0x20, 0x40, 0x30, 0x2C, 0x66, 0x25, 0xA0, 0x17, 0xF4, 0x19, 0x46, 0x7C, 0x71, 0xAF, 0x7C, 0xA2,
+ 0xA7, 0xDC, 0x5D, 0x60, 0xE3, 0x55, 0xB5, 0x0F, 0x92, 0x60, 0x3C, 0xBF, 0x99, 0x61, 0x4E, 0x54,
+ 0xC3, 0xD5, 0xAB, 0xC3, 0x5A, 0x20, 0x67, 0xA7, 0x36, 0x9C, 0x43, 0x98, 0xAD, 0x2A, 0x45, 0x3E,
+ 0x93, 0xDC, 0x33, 0x7C, 0x05, 0xAB, 0xAB, 0x83, 0x5A, 0x22, 0xE2, 0x34, 0xC8, 0x00, 0x77, 0xF7,
+ 0x41, 0x06, 0x3C, 0x01, 0xBE, 0x09, 0xBE, 0xB8, 0xDE, 0xFE, 0xF0, 0x7A, 0xFB, 0xF7, 0xC0, 0x3F,
+ 0x81, 0x27, 0x3D, 0x0B, 0x67, 0x93, 0x57, 0x89, 0x32, 0x0D, 0xEE, 0xEF, 0x8F, 0x4C, 0x8C, 0x97,
+ 0xA3, 0x7E, 0xD0, 0x92, 0x69, 0x91, 0xE6, 0x7C, 0x0A, 0x27, 0xFB, 0x74, 0x8A, 0xA4, 0x95, 0x57,
+ 0xCC, 0x4C, 0x97, 0x67, 0x7A, 0xF7, 0xCF, 0x34, 0xEE, 0xCD, 0x8B, 0xA2, 0x8C, 0x38, 0x1F, 0xE2,
+ 0x2C, 0xC4, 0xE5, 0x1F, 0x58, 0xCB, 0xE6, 0x3A, 0x07, 0x44, 0xC8, 0xF4, 0x86, 0x32, 0x02, 0x8B,
+ 0xCE, 0x73, 0x40, 0x87, 0xC4, 0x05, 0xD5, 0xDD, 0xE4, 0x82, 0xBC, 0xB0, 0x96, 0x0B, 0x33, 0xA8,
+ 0xCC, 0xBA, 0x54, 0xBB, 0xB0, 0xD1, 0x62, 0x9A, 0x89, 0x0E, 0x21, 0x40, 0x92, 0xF1, 0xB2, 0x72,
+ 0x93, 0x89, 0xEC, 0x20, 0xDD, 0xDE, 0x75, 0x21, 0xB7, 0x2B, 0xE4, 0x4B, 0xD7, 0xBA, 0xD0, 0x8C,
+ 0xB3, 0xB1, 0xD4, 0x25, 0xA8, 0x86, 0x73, 0xF5, 0x6C, 0xB3, 0xE4, 0x57, 0x63, 0xA6, 0xA4, 0x67,
+ 0xEC, 0xC8, 0xB6, 0x47, 0x7E, 0x67, 0xD9, 0x0B, 0x8B, 0xA4, 0xF6, 0x7A, 0xDD, 0x4B, 0x09, 0x9B,
+ 0x15, 0x85, 0xAC, 0x29, 0x49, 0x3A, 0x66, 0xC6, 0x5D, 0xCC, 0xFE, 0x23, 0xBF, 0xAB, 0x06, 0x66,
+ 0x71, 0x93, 0x9A, 0x7B, 0xD7, 0xA2, 0xE0, 0xCE, 0xB2, 0x57, 0x13, 0x42, 0xDC, 0x8F, 0x67, 0x33,
+ 0xE7, 0xCD, 0xE6, 0x6B, 0xC1, 0xDB, 0xBC, 0x59, 0xF6, 0xF2, 0x20, 0x89, 0x7B, 0x70, 0xFB, 0x88,
+ 0xD7, 0xFE, 0x6D, 0x70, 0xC1, 0x6D, 0x1F, 0x64, 0xFC, 0x79, 0xAB, 0x52, 0xDF, 0xB8, 0x2A, 0x83,
+ 0x4C, 0x16, 0xAF, 0x7D, 0x6C, 0xD8, 0xFE, 0x2B, 0xAF, 0xDD, 0x8B, 0x67, 0xA1, 0x4F, 0xE2, 0xF6,
+ 0x39, 0x6F, 0xF7, 0xC2, 0xD7, 0xDE, 0x01, 0x5E, 0xD4, 0xCA, 0x60, 0x64, 0xFD, 0x66, 0x70, 0xA9,
+ 0xFD, 0xC9, 0xF5, 0xF6, 0x6F, 0x81, 0xD7, 0x6C, 0x68, 0xFF, 0xC0, 0x7A, 0xFB, 0x13, 0x97, 0x7D,
+ 0xFF, 0xA3, 0xEB, 0xED, 0xDF, 0x06, 0xAF, 0xDA, 0xD0, 0xFE, 0xCF, 0xEB, 0xED, 0xDF, 0x73, 0xDB,
+ 0xBD, 0xC8, 0xCC, 0x26, 0x2F, 0x32, 0x33, 0x03, 0xCE, 0xF4, 0xCB, 0xF9, 0x08, 0x18, 0x15, 0x49,
+ 0x9E, 0x64, 0x6C, 0x87, 0xB1, 0x25, 0x46, 0x74, 0xA4, 0x2F, 0xD9, 0xEA, 0xCC, 0x9F, 0xCF, 0xF6,
+ 0xCD, 0xD9, 0xDA, 0xF9, 0x14, 0xCF, 0xD7, 0xC6, 0x6D, 0xC4, 0x18, 0x88, 0x49, 0x7D, 0x73, 0x0D,
+ 0x00, 0x9E, 0x03, 0xFC, 0x3A, 0x7D, 0xB8, 0xE9, 0x9C, 0xE7, 0x80, 0x3A, 0xA0, 0x0F, 0xF2, 0x12,
+ 0x7D, 0x9C, 0xEF, 0x5D, 0x51, 0xDB, 0xB2, 0x9E, 0x3F, 0x34, 0x3B, 0x70, 0x0D, 0x28, 0xF0, 0x25,
+ 0x48, 0x23, 0xE1, 0xD1, 0xC6, 0xA5, 0xB8, 0xCF, 0xE8, 0x8B, 0x02, 0x3F, 0xBD, 0x86, 0x7C, 0x39,
+ 0x59, 0x04, 0xD3, 0xB3, 0xD5, 0x17, 0x47, 0x82, 0x94, 0xEA, 0x15, 0x91, 0xA0, 0x1A, 0x9F, 0xDD,
+ 0x48, 0x16, 0x9B, 0x47, 0x66, 0x5F, 0x2A, 0x32, 0x24, 0x47, 0xC7, 0x36, 0x84, 0x86, 0xF0, 0x0C,
+ 0x7A, 0xB1, 0x14, 0x6F, 0x85, 0x96, 0x06, 0xEB, 0x76, 0x2B, 0x78, 0x51, 0xEB, 0xA5, 0x75, 0x73,
+ 0xDB, 0x9F, 0xF2, 0xD6, 0x6D, 0xE9, 0xB2, 0x75, 0x1B, 0x7C, 0xFF, 0x03, 0xEB, 0x57, 0x79, 0xC2,
+ 0x5D, 0x7D, 0xD7, 0x67, 0x0B, 0x25, 0xEF, 0x2A, 0xDF, 0x1C, 0x5C, 0xFB, 0x5F, 0x87, 0xAD, 0xE0,
+ 0x97, 0x1B, 0x5A, 0x67, 0x23, 0x6B, 0xDF, 0xCD, 0x7B, 0x57, 0x1E, 0xB4, 0x7E, 0x8B, 0x72, 0x5B,
+ 0xFF, 0xFF, 0xB8, 0xB5, 0xEA, 0x5D, 0x77, 0xD0, 0xFA, 0xC4, 0x7F, 0xB8, 0xAD, 0x9E, 0xB7, 0xC6,
+ 0xA3, 0x86, 0x5D, 0x43, 0x6A, 0x78, 0x9B, 0xD7, 0x0B, 0xCF, 0xF7, 0xE1, 0x5D, 0x79, 0xF7, 0xE0,
+ 0x7E, 0xFB, 0x5E, 0xDC, 0x7A, 0x69, 0x2C, 0x83, 0xF6, 0x27, 0xD7, 0xDB, 0xBF, 0xE5, 0xEE, 0xF9,
+ 0xB9, 0xDE, 0xFE, 0x81, 0xF5, 0xAB, 0x3C, 0x71, 0xF6, 0x52, 0xEB, 0x47, 0xD7, 0x5B, 0xBF, 0x7D,
+ 0xEB, 0xA0, 0xD7, 0xD8, 0xB6, 0xF0, 0xAE, 0x7D, 0x60, 0xC8, 0x55, 0x6F, 0x00, 0x2F, 0xD5, 0x3E,
+ 0x8B, 0x49, 0xEA, 0x52, 0xFB, 0x93, 0xEB, 0xED, 0xDF, 0xC2, 0x12, 0xED, 0x52, 0xFB, 0x07, 0xD6,
+ 0xDB, 0x9F, 0x00, 0xEF, 0xF2, 0xF6, 0x0C, 0x0D, 0xAE, 0x3E, 0x06, 0x3F, 0x89, 0x76, 0x82, 0x1A,
+ 0xE8, 0x80, 0x07, 0xFB, 0xA5, 0xB0, 0xA5, 0x50, 0xA0, 0x5E, 0xCE, 0x18, 0x76, 0xC6, 0xB6, 0xBA,
+ 0xDD, 0x92, 0xD5, 0x0D, 0x7C, 0xA3, 0x55, 0x37, 0x0D, 0x8E, 0x25, 0x19, 0x54, 0xB0, 0x8D, 0x3A,
+ 0x22, 0x47, 0x50, 0x21, 0x4B, 0xAE, 0xAC, 0xB9, 0x19, 0xCF, 0x01, 0x06, 0xDA, 0x3D, 0x2C, 0xC7,
+ 0x2D, 0x68, 0x79, 0x16, 0xCD, 0x20, 0x76, 0xD4, 0x1D, 0x5A, 0x6E, 0xE7, 0x40, 0x12, 0x6A, 0x2E,
+ 0x31, 0x9F, 0x03, 0x35, 0xA8, 0xBB, 0x2F, 0x1D, 0x68, 0xAC, 0x6F, 0xC7, 0xB5, 0x01, 0x62, 0x74,
+ 0xD7, 0x4A, 0xF9, 0x1C, 0x05, 0x6B, 0x9D, 0x4C, 0x76, 0x98, 0x10, 0x98, 0x6D, 0x33, 0xC3, 0x18,
+ 0x1A, 0x36, 0xE9, 0x18, 0x77, 0x77, 0x09, 0x6C, 0xBB, 0x63, 0xDD, 0x5B, 0xC7, 0xAC, 0x03, 0x33,
+ 0x83, 0xF0, 0xB4, 0x03, 0xDF, 0x1D, 0xAF, 0x96, 0x03, 0x74, 0x4E, 0x99, 0x6A, 0xB2, 0xDA, 0xE8,
+ 0x8E, 0x9D, 0x49, 0xD4, 0x84, 0xA4, 0xA2, 0xCA, 0xA5, 0x4D, 0xC9, 0x04, 0xA9, 0x5B, 0xBC, 0xDF,
+ 0x44, 0x30, 0x55, 0x12, 0x59, 0xD9, 0xFE, 0x18, 0x69, 0x25, 0x02, 0xB4, 0x94, 0x0D, 0x5C, 0x15,
+ 0x48, 0x84, 0xF8, 0xF9, 0x38, 0x97, 0xDE, 0x24, 0xD6, 0x69, 0x73, 0xF3, 0xEC, 0xD4, 0xCB, 0x5A,
+ 0xCE, 0xCE, 0xC4, 0x09, 0x48, 0xA0, 0x91, 0x70, 0x30, 0xE0, 0x43, 0x92, 0xE0, 0x4F, 0xA9, 0xFD,
+ 0xE6, 0x8D, 0x0D, 0x0B, 0x91, 0x1F, 0x79, 0x8C, 0xD0, 0x8B, 0xB6, 0x14, 0xAF, 0x2D, 0x4A, 0x83,
+ 0x48, 0xE7, 0xBF, 0xA1, 0x9B, 0xD1, 0x57, 0xF0, 0x8C, 0x9F, 0xEE, 0x8F, 0x4D, 0x34, 0xE2, 0xAA,
+ 0x22, 0x0B, 0x40, 0xE0, 0x19, 0xBE, 0xEA, 0xEB, 0x4D, 0x4E, 0x29, 0x19, 0x0D, 0xBC, 0x6E, 0x6E,
+ 0x72, 0x66, 0x2B, 0x31, 0x3E, 0xA6, 0x12, 0xCA, 0xA3, 0x0D, 0xCB, 0x34, 0x74, 0x8D, 0xAE, 0x1D,
+ 0x99, 0xAC, 0x55, 0x91, 0x63, 0xFB, 0x42, 0x6F, 0x22, 0x1E, 0x5E, 0xF3, 0x5A, 0xF7, 0xD6, 0x63,
+ 0x26, 0xBD, 0x61, 0xAC, 0xCD, 0x8B, 0x53, 0xBB, 0x09, 0xA3, 0xF0, 0x25, 0xF2, 0xE0, 0xE7, 0x54,
+ 0xCF, 0x3F, 0x8A, 0xF1, 0xA4, 0xBB, 0x6F, 0xDC, 0x14, 0x9E, 0xA6, 0x64, 0xDB, 0xE9, 0xA0, 0x76,
+ 0xB3, 0x3D, 0xBA, 0x71, 0x8B, 0x94, 0x81, 0xFB, 0x14, 0x63, 0x94, 0x7A, 0xAB, 0xC1, 0x78, 0xB8,
+ 0x9B, 0x71, 0x1D, 0x6D, 0x58, 0x3E, 0xF4, 0x20, 0xBA, 0xB9, 0x58, 0xCD, 0xB5, 0xB7, 0x24, 0x59,
+ 0x73, 0x61, 0x24, 0x25, 0x71, 0xEF, 0x3E, 0x25, 0x49, 0x9A, 0x82, 0xE0, 0xD5, 0x6F, 0x6A, 0xAB,
+ 0xD3, 0x75, 0xC9, 0x97, 0x09, 0xA5, 0x68, 0x4E, 0x8D, 0xC4, 0x4A, 0x31, 0x39, 0xFF, 0xFE, 0xE2,
+ 0xCB, 0x2C, 0x3B, 0xE3, 0x0B, 0x61, 0xF3, 0x28, 0xA0, 0x8E, 0x5E, 0x5D, 0xD8, 0x7C, 0xFF, 0x78,
+ 0x31, 0x41, 0xBA, 0x99, 0xA5, 0x68, 0xF4, 0xD8, 0xCD, 0x95, 0x53, 0x30, 0x20, 0x56, 0x42, 0x27,
+ 0xF6, 0x32, 0x71, 0x47, 0xD4, 0x8C, 0x80, 0xA6, 0x69, 0x56, 0x38, 0x39, 0x39, 0xD9, 0xE8, 0xA0,
+ 0x97, 0xE1, 0x2F, 0xD5, 0xAA, 0x9D, 0x18, 0x42, 0x90, 0x74, 0x3D, 0xFB, 0x4F, 0xAF, 0xE6, 0x90,
+ 0x88, 0xFE, 0x1D, 0x4B, 0xF3, 0x05, 0x3C, 0x63, 0xB9, 0x5A, 0x50, 0x07, 0x91, 0x39, 0x2B, 0x03,
+ 0xAD, 0xCC, 0x14, 0xDB, 0x88, 0xB0, 0x8D, 0xC5, 0x56, 0xFC, 0x4E, 0x5F, 0x6B, 0x1A, 0x95, 0x59,
+ 0xD4, 0xC8, 0x20, 0x6B, 0x1C, 0x29, 0xBE, 0x1F, 0xAF, 0x87, 0x29, 0xCE, 0x81, 0x16, 0x0C, 0xAE,
+ 0x15, 0x38, 0x57, 0x3D, 0x45, 0x4A, 0x42, 0xDF, 0x80, 0xA0, 0x20, 0xF4, 0xBB, 0x2F, 0x73, 0x30,
+ 0xB0, 0xA1, 0xA8, 0xFF, 0xB2, 0xF4, 0xD2, 0xC5, 0xA0, 0x9B, 0x27, 0x86, 0x05, 0x20, 0x3D, 0xF4,
+ 0x36, 0x7A, 0xFE, 0x13, 0xC6, 0x7B, 0x76, 0x8B, 0x43, 0xD6, 0xEA, 0xFF, 0xD6, 0x13, 0x90, 0x9B,
+ 0x1E, 0xEA, 0x19, 0x94, 0x3C, 0x13, 0x5E, 0xC5, 0x88, 0x4B, 0x62, 0xA4, 0x33, 0x05, 0x91, 0xF8,
+ 0x40, 0x6B, 0x2C, 0x19, 0x8D, 0x58, 0xD3, 0x73, 0x37, 0x34, 0xC7, 0x5B, 0x71, 0x8A, 0x3E, 0x77,
+ 0xCB, 0xF6, 0x9B, 0x24, 0xED, 0x0C, 0x52, 0xAE, 0x4B, 0xD6, 0xE2, 0xBA, 0x91, 0x6B, 0x3F, 0x3A,
+ 0xDF, 0x9E, 0x29, 0xC9, 0xD2, 0x67, 0x6F, 0x9D, 0xEA, 0x6E, 0x4B, 0xD5, 0x1F, 0x9A, 0xC5, 0x98,
+ 0x89, 0x4F, 0x48, 0x06, 0xFA, 0xC8, 0xCE, 0x66, 0x50, 0x55, 0x8C, 0x78, 0xB9, 0x9E, 0x6E, 0x87,
+ 0x16, 0x9B, 0x8D, 0x43, 0x21, 0x35, 0x1B, 0x38, 0xF8, 0x78, 0x79, 0xCC, 0x3C, 0x88, 0xCA, 0x5B,
+ 0xFC, 0x92, 0x9E, 0x8E, 0xB7, 0xF4, 0x8A, 0x6F, 0x4F, 0xAD, 0x73, 0x34, 0xAA, 0x55, 0xFD, 0x57,
+ 0xDF, 0x99, 0xBE, 0x48, 0x86, 0xED, 0xC0, 0xFC, 0x84, 0x92, 0xF3, 0x37, 0xEE, 0x0F, 0xE9, 0x59,
+ 0x97, 0xEA, 0x16, 0xC0, 0xC7, 0xE1, 0x87, 0x51, 0x10, 0x08, 0x20, 0xD4, 0x47, 0x34, 0xF0, 0xE0,
+ 0x52, 0xA4, 0xE7, 0x96, 0x3E, 0x87, 0xD7, 0x76, 0x6D, 0x12, 0xE9, 0xF5, 0xE2, 0x6E, 0x6F, 0x00,
+ 0xF0, 0xC3, 0x37, 0x6D, 0xD9, 0x7C, 0xE3, 0x8D, 0x9B, 0xB7, 0xDC, 0x04, 0x8F, 0x6F, 0xBE, 0xE9,
+ 0xC6, 0x2D, 0x5B, 0x6E, 0x3C, 0xB1, 0x96, 0x9B, 0xFE, 0x76, 0x42, 0x03, 0xC7, 0xC0, 0x6D, 0xFD,
+ 0xD6, 0x35, 0x07, 0xA6, 0x7D, 0xBA, 0x84, 0xE6, 0xA7, 0xF2, 0xF6, 0x27, 0x6E, 0xD0, 0x7F, 0xC6,
+ 0x4E, 0x77, 0xEF, 0x5A, 0xDA, 0xF4, 0xCB, 0x4C, 0x2D, 0x5E, 0x6F, 0xA2, 0x89, 0x4A, 0x15, 0x6D,
+ 0xDE, 0xD4, 0x25, 0x3A, 0xF5, 0x11, 0x34, 0x51, 0x43, 0xE3, 0x63, 0x13, 0xBB, 0x2B, 0x63, 0xEC,
+ 0x22, 0x9C, 0xBE, 0x3C, 0xE4, 0x37, 0x0C, 0x15, 0x0F, 0x49, 0x77, 0x58, 0xAB, 0x79, 0x59, 0xB6,
+ 0xBE, 0xDB, 0xB9, 0x1B, 0xA6, 0xD7, 0x2A, 0xF2, 0x7E, 0x87, 0x9F, 0x6A, 0x2D, 0x3A, 0x2E, 0xBB,
+ 0x4E, 0xED, 0xDF, 0x19, 0x46, 0x1E, 0xEC, 0x61, 0x34, 0xF4, 0x7B, 0xD9, 0xE8, 0x96, 0xDA, 0xEF,
+ 0xF0, 0x5F, 0xCD, 0x6D, 0xC9, 0x2A, 0xD7, 0x84, 0xB2, 0x96, 0x44, 0x42, 0xE2, 0xF7, 0x87, 0x97,
+ 0x53, 0x9B, 0x4F, 0x05, 0xD7, 0x3C, 0x62, 0x50, 0x09, 0xFF, 0x9F, 0x7C, 0x5B, 0xF1, 0x5D, 0xC5,
+ 0xC8, 0xE8, 0xE2, 0x49, 0x63, 0x6C, 0xAA, 0x1A, 0x3B, 0xFD, 0x7B, 0x63, 0xCF, 0xE6, 0xE9, 0x69,
+ 0xF9, 0xF5, 0xCC, 0x25, 0xB7, 0x99, 0xBB, 0x1B, 0xF3, 0x5A, 0xC5, 0xBF, 0x80, 0x31, 0x71, 0x1A,
+ 0x54, 0x30, 0x7E, 0x68, 0xFA, 0x03, 0xC8, 0x97, 0x4E, 0xFB, 0xC2, 0x21, 0x3F, 0xE1, 0xB3, 0xD2,
+ 0x79, 0x6B, 0x99, 0x50, 0x96, 0xB9, 0x60, 0x20, 0x52, 0x2A, 0xE4, 0x23, 0x51, 0x11, 0x01, 0x1D,
+ 0xD1, 0xC5, 0x42, 0x88, 0x08, 0xA2, 0x48, 0x38, 0x83, 0x12, 0xDC, 0xED, 0xC4, 0xE9, 0xF5, 0x3D,
+ 0x37, 0x3C, 0xDE, 0x70, 0x85, 0xC7, 0x70, 0xA7, 0xCA, 0x88, 0xB7, 0x3D, 0x4F, 0xF7, 0x1C, 0x28,
+ 0xC2, 0x99, 0xB5, 0xA5, 0x70, 0xD7, 0x65, 0xB8, 0xCF, 0xEA, 0x20, 0x4F, 0xA9, 0x7A, 0x05, 0xA5,
+ 0x30, 0x1B, 0xAA, 0xFB, 0x99, 0x64, 0x36, 0x69, 0x61, 0xE3, 0x63, 0x00, 0x2D, 0xDA, 0x2E, 0xFE,
+ 0xB7, 0xBC, 0xA2, 0xFF, 0xEF, 0xFC, 0xE1, 0x5B, 0xBF, 0xFB, 0xDD, 0xB7, 0xFE, 0xE1, 0x77, 0xF6,
+ 0xBE, 0xF7, 0x9E, 0x7B, 0xDE, 0xEB, 0x1E, 0xF7, 0xED, 0x3D, 0x52, 0xDF, 0xFE, 0x91, 0xB1, 0xAD,
+ 0x63, 0xB5, 0x40, 0x29, 0x3B, 0xB7, 0x54, 0x48, 0xC3, 0xE3, 0xEF, 0xF9, 0xDA, 0xD7, 0xDE, 0xF3,
+ 0x9E, 0xAF, 0x3D, 0xFD, 0xE4, 0xBD, 0x1F, 0xF8, 0xC0, 0xBD, 0xF8, 0xD8, 0xFB, 0x89, 0x4F, 0xC0,
+ 0x77, 0x34, 0xA6, 0xC6, 0x27, 0x4E, 0x47, 0x7C, 0xB7, 0xFB, 0xB0, 0xD5, 0xB3, 0x71, 0xEC, 0x23,
+ 0x60, 0x5B, 0x3F, 0x3D, 0xE2, 0x4B, 0xA7, 0x06, 0xC3, 0xAD, 0x2C, 0x07, 0x73, 0xCB, 0xF1, 0x85,
+ 0x94, 0xE8, 0x13, 0x8B, 0x28, 0x82, 0x47, 0x8C, 0xC7, 0xFD, 0xE2, 0x91, 0xAE, 0x6D, 0x73, 0xD0,
+ 0xBB, 0xB0, 0xB6, 0xD1, 0xC1, 0x79, 0x77, 0xBB, 0xB8, 0xFA, 0xFF, 0x61, 0x40, 0xD9, 0x8D, 0x3B,
+ 0x1D, 0x24, 0x3D, 0x94, 0x3C, 0xDC, 0xE0, 0xE0, 0xD2, 0x98, 0xB6, 0x7F, 0xF0, 0x65, 0x2F, 0xFB,
+ 0xA0, 0x7B, 0x9C, 0x14, 0x8F, 0xCC, 0x1E, 0x3C, 0x7D, 0xEB, 0xB5, 0xF3, 0x87, 0xF8, 0xAD, 0x74,
+ 0x3B, 0xD3, 0xEA, 0x76, 0x5B, 0x85, 0x26, 0x79, 0x69, 0x60, 0x83, 0x6F, 0x7D, 0xB0, 0xB3, 0x69,
+ 0xDF, 0x03, 0xD7, 0x5D, 0x7F, 0xDF, 0xCE, 0xCD, 0xC9, 0xFC, 0xF6, 0xFE, 0xD4, 0x9E, 0x42, 0x06,
+ 0x6B, 0xD2, 0x29, 0x58, 0x27, 0xDE, 0x85, 0x6D, 0x34, 0x11, 0x98, 0xE0, 0xAD, 0xFD, 0x19, 0x5E,
+ 0x40, 0x04, 0x42, 0xEE, 0x16, 0x78, 0x6E, 0x4A, 0x19, 0x40, 0xF7, 0xB3, 0xBA, 0x86, 0x8D, 0xB4,
+ 0x65, 0xD6, 0x94, 0x64, 0x45, 0x46, 0x9A, 0xCA, 0x32, 0xC8, 0x0D, 0x90, 0x02, 0x43, 0x67, 0x44,
+ 0x40, 0x99, 0x86, 0x28, 0x70, 0x14, 0xCB, 0xA8, 0x0A, 0x43, 0x93, 0x04, 0x64, 0xD6, 0x12, 0xE3,
+ 0xB0, 0x56, 0xF7, 0xB6, 0xC5, 0xC3, 0x0F, 0x38, 0xDC, 0x2A, 0x6F, 0x50, 0x09, 0x3D, 0x08, 0xDF,
+ 0xBA, 0xE6, 0x9C, 0xE7, 0x1A, 0x75, 0x01, 0x65, 0xE3, 0xC2, 0x70, 0x7B, 0x8D, 0x9F, 0xDC, 0xFB,
+ 0x79, 0x47, 0x58, 0xDB, 0x6B, 0xC3, 0x7E, 0xD4, 0x7D, 0xE3, 0x6E, 0x86, 0xE7, 0x66, 0x9D, 0x27,
+ 0x35, 0xC2, 0x4D, 0x50, 0xD3, 0x1A, 0x41, 0xD8, 0xA0, 0x92, 0x1A, 0xFE, 0x6F, 0xC6, 0x89, 0x77,
+ 0x1D, 0xBC, 0x7D, 0xFE, 0x36, 0x74, 0xF0, 0xF1, 0xE3, 0xC7, 0x1F, 0xBB, 0xF0, 0xEC, 0xD9, 0x43,
+ 0x67, 0xE1, 0x4E, 0x58, 0x87, 0xB5, 0x8B, 0x5F, 0xF7, 0x8E, 0xB7, 0x5F, 0x7C, 0x16, 0xEA, 0xDB,
+ 0x2F, 0x7E, 0x0C, 0x6E, 0xDF, 0x8E, 0xE5, 0xD0, 0x08, 0xF2, 0x41, 0xC7, 0xCB, 0x45, 0x8B, 0xF4,
+ 0x69, 0x2F, 0x17, 0xCD, 0xB3, 0xE2, 0xB0, 0x31, 0x7C, 0x45, 0x3A, 0x9A, 0x1B, 0x1B, 0x81, 0xCE,
+ 0x47, 0xDA, 0x6F, 0x40, 0x0F, 0xDC, 0xE0, 0x3C, 0x86, 0xF5, 0xC0, 0x33, 0xA8, 0x00, 0x47, 0x31,
+ 0x02, 0x11, 0x81, 0x1F, 0x4C, 0xF7, 0x2D, 0x1E, 0xD0, 0x8E, 0x64, 0x48, 0xC8, 0xC0, 0x57, 0x71,
+ 0x56, 0x54, 0x19, 0x12, 0x6B, 0x5B, 0x79, 0xBA, 0xA2, 0xAD, 0x85, 0xC7, 0x7B, 0xC6, 0x1D, 0x93,
+ 0x30, 0xD8, 0x4D, 0x71, 0xB8, 0xC7, 0xDD, 0xC0, 0x2E, 0x0C, 0x18, 0x5E, 0xFA, 0xFC, 0x20, 0x7B,
+ 0x08, 0x2B, 0x55, 0xAF, 0xBE, 0x74, 0x78, 0x0E, 0x47, 0x17, 0x59, 0xCA, 0x0A, 0x62, 0x45, 0x4B,
+ 0x69, 0xEF, 0xBA, 0x74, 0x8A, 0xAE, 0xA9, 0xA1, 0x9C, 0x62, 0xAA, 0xBA, 0x21, 0x95, 0xAC, 0x4B,
+ 0xA7, 0x03, 0xDC, 0xF5, 0x4B, 0xD4, 0x25, 0x4E, 0x62, 0x64, 0x94, 0x19, 0x22, 0xA6, 0x73, 0xE0,
+ 0x8B, 0xB8, 0xBF, 0x3F, 0x5C, 0x7D, 0x81, 0x0C, 0xA3, 0xCF, 0x83, 0xBD, 0x18, 0x31, 0xBD, 0xAF,
+ 0xBF, 0x7D, 0x76, 0x2C, 0x19, 0x92, 0xC0, 0x62, 0xB3, 0x3E, 0x52, 0x2A, 0x64, 0x93, 0xD9, 0xFE,
+ 0xBE, 0x42, 0x7F, 0xDF, 0xE2, 0xE4, 0xBE, 0x78, 0x02, 0xED, 0xDF, 0xB7, 0x6F, 0x7F, 0x7F, 0x12,
+ 0xBC, 0x62, 0x99, 0xFD, 0x83, 0xE5, 0xBD, 0x7B, 0x1E, 0x23, 0x29, 0x38, 0xB9, 0x54, 0xED, 0xA6,
+ 0xAB, 0x5F, 0x3F, 0x70, 0x97, 0x7E, 0x95, 0x69, 0x68, 0xDB, 0x26, 0xFB, 0xDA, 0x01, 0xD4, 0x57,
+ 0xF7, 0xA1, 0xCD, 0xFD, 0xB1, 0x27, 0x42, 0x33, 0x67, 0x61, 0xE8, 0x8A, 0x92, 0x1F, 0x75, 0xB0,
+ 0x94, 0xAE, 0x91, 0xE8, 0x6D, 0x64, 0xE1, 0x66, 0xC4, 0xBA, 0x31, 0xB4, 0x35, 0xF6, 0x5D, 0xDF,
+ 0xE0, 0x78, 0x83, 0x8E, 0xAB, 0x5C, 0x19, 0x3E, 0x5D, 0x0E, 0xAD, 0xD7, 0xB9, 0xBB, 0x26, 0x01,
+ 0x9D, 0xF1, 0xC2, 0x85, 0xF0, 0xD2, 0x9E, 0x17, 0x44, 0x0F, 0x7A, 0x25, 0xEF, 0x75, 0xBB, 0xE1,
+ 0xED, 0x74, 0x52, 0x6F, 0xBB, 0xD5, 0xDB, 0x2E, 0x4A, 0x70, 0x0B, 0xBC, 0x4D, 0xDA, 0x2D, 0x78,
+ 0x97, 0x51, 0x92, 0x36, 0xDD, 0x40, 0x56, 0xC4, 0xAB, 0x03, 0x6C, 0x43, 0xC2, 0x69, 0x93, 0x61,
+ 0xAF, 0x06, 0x3E, 0xF7, 0x69, 0xCE, 0x2F, 0xF8, 0x15, 0x9E, 0x25, 0xDE, 0xFC, 0x5A, 0x95, 0xF4,
+ 0x51, 0xBE, 0x97, 0x2B, 0x23, 0x46, 0x70, 0xE1, 0xCE, 0x8F, 0xED, 0x9F, 0xBE, 0xCA, 0x2D, 0x89,
+ 0x57, 0xFB, 0x22, 0xC9, 0xD2, 0x31, 0x5E, 0x12, 0x9C, 0xC2, 0xA3, 0xAC, 0x54, 0x97, 0xDC, 0xE2,
+ 0xF8, 0x1D, 0x64, 0xE3, 0xB3, 0x92, 0xDE, 0x3F, 0xB8, 0x13, 0x22, 0x4A, 0x60, 0x8A, 0x6F, 0xA2,
+ 0x66, 0x2F, 0x6E, 0xFB, 0xCE, 0xF2, 0xBD, 0x83, 0x02, 0x79, 0x2C, 0x9C, 0xF3, 0xA3, 0x5C, 0x88,
+ 0x73, 0xF7, 0xCF, 0xA0, 0x63, 0xDC, 0x60, 0xFF, 0x8C, 0xE9, 0x47, 0xBE, 0x7A, 0x74, 0x97, 0x57,
+ 0x2C, 0x8F, 0xF9, 0x83, 0xA4, 0xDD, 0x72, 0x79, 0x22, 0x72, 0x16, 0x52, 0xC1, 0xF9, 0x10, 0x2D,
+ 0x91, 0x6C, 0x4E, 0xAA, 0x56, 0x64, 0x0A, 0xC1, 0x37, 0xAC, 0x02, 0x44, 0x78, 0xF5, 0xA5, 0xFF,
+ 0x82, 0xFE, 0x07, 0xFA, 0x02, 0xB6, 0xCE, 0xF6, 0x62, 0x79, 0x12, 0xDA, 0xBD, 0x79, 0xAC, 0x92,
+ 0x49, 0x85, 0x1D, 0x9B, 0x21, 0xC0, 0x52, 0x23, 0x09, 0xE2, 0xED, 0xBD, 0xDB, 0xDF, 0xBF, 0x6F,
+ 0x9F, 0x42, 0xEE, 0x9B, 0xFC, 0x33, 0x3C, 0xBF, 0x36, 0xEC, 0x0C, 0xC2, 0x2B, 0xE7, 0x80, 0x06,
+ 0xC7, 0xBD, 0xF2, 0xC8, 0x17, 0xA5, 0x09, 0xB8, 0x73, 0xB9, 0xCF, 0xAB, 0x8E, 0x40, 0x11, 0xB8,
+ 0x5E, 0x5F, 0x96, 0xF5, 0xCA, 0xE0, 0xD7, 0x0C, 0xEF, 0x56, 0x63, 0x98, 0xB3, 0x36, 0x85, 0xDA,
+ 0xDE, 0x0E, 0x4D, 0x97, 0xF2, 0x39, 0xDC, 0x8C, 0x7D, 0xC2, 0x2D, 0x55, 0x84, 0x6B, 0xF9, 0x6C,
+ 0x19, 0xF4, 0x3F, 0xA2, 0x45, 0x63, 0x4C, 0x18, 0x16, 0x9F, 0x5D, 0x3D, 0xAB, 0x3B, 0xFE, 0xAC,
+ 0x79, 0x90, 0xE1, 0x06, 0x45, 0x68, 0x1C, 0x65, 0x96, 0x13, 0x12, 0xB9, 0xF5, 0x50, 0xBA, 0xE8,
+ 0xEB, 0xB4, 0x2F, 0x2F, 0x40, 0x5B, 0x30, 0x2A, 0x76, 0xFE, 0x4F, 0x28, 0x4D, 0x7D, 0xE4, 0x4C,
+ 0xAC, 0x31, 0x28, 0x53, 0x43, 0x7F, 0x99, 0xAE, 0x9A, 0x73, 0xA7, 0xD7, 0xCB, 0xD2, 0xC6, 0xED,
+ 0x30, 0xC3, 0x1C, 0xE5, 0x84, 0xCB, 0xAA, 0xD3, 0xB6, 0x3A, 0xF4, 0xDE, 0x9B, 0x0B, 0x8D, 0xC4,
+ 0x88, 0x75, 0xA9, 0x30, 0xAD, 0xA0, 0xB5, 0x69, 0xE6, 0xE2, 0x9B, 0xD3, 0xCD, 0xC8, 0x9B, 0x1E,
+ 0x4F, 0xA7, 0x07, 0xB5, 0x6B, 0x03, 0x0B, 0xF7, 0x39, 0xF8, 0x5E, 0xCF, 0x62, 0x58, 0x18, 0xD8,
+ 0x45, 0x9E, 0x5D, 0xED, 0x55, 0xDD, 0x7B, 0x5C, 0x51, 0x18, 0x72, 0xC5, 0x37, 0x3C, 0x2B, 0xDC,
+ 0xCB, 0xA3, 0xF2, 0xBE, 0xBD, 0x79, 0xD8, 0xFE, 0x06, 0x30, 0x88, 0x02, 0x7C, 0x0E, 0xDD, 0x8D,
+ 0x7E, 0x8A, 0x51, 0xF1, 0xAB, 0xFB, 0xD3, 0xBD, 0x6E, 0x39, 0x9D, 0x4A, 0x86, 0x43, 0x41, 0x5D,
+ 0x53, 0x64, 0x89, 0x63, 0x19, 0xD0, 0xAE, 0x95, 0x0A, 0x46, 0xBB, 0xAD, 0x06, 0x1C, 0xDB, 0x56,
+ 0x03, 0xC9, 0x04, 0x4F, 0x70, 0x13, 0xE9, 0x14, 0x4B, 0x30, 0x47, 0xC2, 0x21, 0x2C, 0x15, 0x27,
+ 0xDC, 0x44, 0x0F, 0x25, 0x1A, 0x08, 0x20, 0x75, 0xF6, 0x73, 0xB0, 0xBC, 0x26, 0x07, 0x6C, 0xD8,
+ 0x5D, 0x4B, 0xB1, 0xDB, 0xB8, 0x63, 0x38, 0x5C, 0xDB, 0x4D, 0x55, 0xED, 0xBE, 0x78, 0xF5, 0x2E,
+ 0xC1, 0xE5, 0xF2, 0x20, 0x34, 0x44, 0x36, 0xAC, 0x24, 0x43, 0x33, 0xF8, 0x79, 0xB0, 0xA5, 0x2A,
+ 0x5E, 0x10, 0x77, 0x57, 0xD1, 0x4C, 0x13, 0x2F, 0x12, 0x7E, 0x1D, 0x94, 0x65, 0x6F, 0xC8, 0x99,
+ 0x27, 0x06, 0x39, 0xF3, 0xE8, 0x6E, 0x55, 0x1B, 0x91, 0x95, 0xAA, 0x70, 0xC7, 0x5B, 0xA8, 0x3C,
+ 0xF5, 0xE5, 0xAF, 0xC0, 0xA0, 0x59, 0xF3, 0x53, 0x1F, 0xFB, 0x10, 0x49, 0xFB, 0xEC, 0x3B, 0xB7,
+ 0x59, 0xF6, 0x58, 0x52, 0x66, 0x05, 0x4E, 0x5F, 0xD1, 0xAD, 0xAE, 0x59, 0x2A, 0xE6, 0x54, 0x67,
+ 0x44, 0xC3, 0x12, 0xBF, 0x52, 0x2E, 0x96, 0xD1, 0xF7, 0xAD, 0xC8, 0xA1, 0x40, 0xF4, 0x5A, 0x7B,
+ 0x96, 0xDF, 0x5E, 0x9B, 0xDD, 0x65, 0xFB, 0xD4, 0x92, 0xD3, 0x4D, 0x9D, 0xA4, 0x66, 0x35, 0xCA,
+ 0x6A, 0x65, 0x67, 0x93, 0x89, 0xED, 0xD9, 0x41, 0xFE, 0xFC, 0xE2, 0xF6, 0x1D, 0x89, 0xEC, 0xAD,
+ 0xA5, 0x8A, 0x4F, 0x90, 0x25, 0x2F, 0x7D, 0xDE, 0x8B, 0x25, 0xF9, 0xBD, 0x58, 0xD2, 0x34, 0xB8,
+ 0xB6, 0x9F, 0xCD, 0x25, 0xFC, 0xB6, 0xA9, 0xA6, 0x93, 0xF1, 0x08, 0x35, 0xF2, 0x37, 0x33, 0xE4,
+ 0xB5, 0x33, 0x65, 0x0A, 0x4C, 0xF7, 0x28, 0xD4, 0x23, 0x51, 0xB7, 0x8D, 0xFA, 0xBD, 0xEE, 0x0B,
+ 0x2B, 0x67, 0xD7, 0xC2, 0x65, 0x67, 0xDC, 0xE9, 0x9A, 0xEC, 0x5D, 0x1E, 0x56, 0xDA, 0xE0, 0x9E,
+ 0xBE, 0xAC, 0x7E, 0x22, 0x71, 0x79, 0x7C, 0x29, 0x4A, 0xB8, 0x39, 0x21, 0xCD, 0x0D, 0x11, 0xA6,
+ 0x41, 0xDC, 0xDA, 0x45, 0x5B, 0xBF, 0x37, 0xC6, 0x44, 0xBB, 0x1B, 0x5D, 0xCC, 0x2F, 0x69, 0x84,
+ 0xBA, 0x16, 0x65, 0x92, 0x59, 0x37, 0xCA, 0x44, 0xD3, 0xDC, 0xEF, 0x0B, 0x32, 0xD1, 0xC9, 0x7C,
+ 0x32, 0x97, 0x6E, 0xE5, 0x9F, 0x8A, 0xBE, 0xF9, 0xE1, 0x41, 0xA8, 0xE9, 0xFF, 0xA2, 0xEE, 0xCB,
+ 0xE3, 0xE4, 0x2A, 0xCA, 0x76, 0xDF, 0xAA, 0xD3, 0x67, 0xDF, 0x7B, 0x9D, 0xE9, 0xD9, 0xF7, 0xC9,
+ 0x64, 0x9B, 0x25, 0x99, 0xC9, 0x3E, 0x93, 0x7D, 0x21, 0x84, 0x09, 0x21, 0x3B, 0x43, 0x86, 0x24,
+ 0x06, 0x0C, 0x04, 0x48, 0x08, 0x18, 0x64, 0x5F, 0x8C, 0x88, 0x80, 0x88, 0x8A, 0x44, 0x81, 0x0F,
+ 0x90, 0x25, 0x0A, 0x22, 0x28, 0x2E, 0xEC, 0x88, 0xC8, 0x26, 0xAB, 0x22, 0x84, 0x45, 0xE4, 0x13,
+ 0xAE, 0xEC, 0x08, 0x08, 0x5C, 0xF4, 0x23, 0xF4, 0x7D, 0xAA, 0x4E, 0x77, 0x4F, 0x27, 0x99, 0x28,
+ 0xF7, 0xFE, 0xBE, 0xFB, 0xC7, 0x77, 0xA6, 0x6B, 0xBA, 0xBB, 0xBA, 0x4E, 0x55, 0x3D, 0x55, 0x6F,
+ 0x3D, 0xEF, 0x5B, 0xCB, 0xA9, 0x8A, 0x89, 0x99, 0xA6, 0xFA, 0x46, 0xDF, 0x09, 0xF6, 0x9E, 0x6A,
+ 0x82, 0xEC, 0xC9, 0xDD, 0x12, 0xA4, 0x4C, 0x8E, 0xCC, 0xCB, 0xDE, 0x5B, 0x72, 0x84, 0xA9, 0xB0,
+ 0x56, 0xAD, 0x99, 0x0E, 0x88, 0xFC, 0x99, 0x29, 0xFB, 0xD9, 0x7A, 0xAE, 0x8E, 0x4D, 0x95, 0xE1,
+ 0x47, 0xE7, 0xC3, 0x97, 0x4B, 0x66, 0xFF, 0x20, 0x97, 0x96, 0x23, 0x01, 0x19, 0xAA, 0xA6, 0x65,
+ 0x7D, 0x35, 0x95, 0x09, 0xF2, 0x8D, 0x6C, 0x5A, 0xA9, 0xAC, 0x80, 0xF9, 0xD5, 0x52, 0x55, 0xE5,
+ 0x28, 0x65, 0xE9, 0x4C, 0x9A, 0xC7, 0x94, 0x6A, 0xE5, 0x2F, 0xCC, 0x29, 0x76, 0x44, 0x60, 0xCD,
+ 0xE7, 0xC7, 0x68, 0xE5, 0x4E, 0xED, 0xA2, 0x2B, 0x92, 0x65, 0x7D, 0xBB, 0x83, 0xBC, 0x40, 0x0E,
+ 0x2D, 0xB2, 0xA9, 0x71, 0xD4, 0x91, 0x99, 0xFD, 0xAC, 0x98, 0x4A, 0x34, 0xB4, 0xE8, 0x0D, 0x3D,
+ 0x5D, 0xBB, 0x86, 0x59, 0x29, 0xB5, 0xE4, 0x84, 0xF6, 0xA9, 0xFD, 0x47, 0x6C, 0xB8, 0x61, 0xB8,
+ 0x15, 0x52, 0xFC, 0xA2, 0x95, 0x2B, 0xB7, 0x01, 0x91, 0x7C, 0xF6, 0x4E, 0x22, 0xEA, 0xCE, 0x23,
+ 0xFA, 0x11, 0x10, 0x31, 0x72, 0xD9, 0x99, 0x6C, 0x80, 0x3F, 0x86, 0x5E, 0xFC, 0xDC, 0xBE, 0x74,
+ 0x6B, 0x3D, 0x35, 0x85, 0xBE, 0x11, 0xC6, 0xB3, 0x4E, 0x4B, 0x4B, 0x3C, 0x1B, 0xE7, 0x59, 0x56,
+ 0x98, 0xB7, 0x10, 0x32, 0x02, 0xB3, 0x50, 0x58, 0x87, 0xD3, 0x7B, 0x0B, 0x1B, 0xC7, 0xCA, 0xA6,
+ 0x54, 0xBA, 0xBE, 0xA1, 0x23, 0x2B, 0xD5, 0xB7, 0x98, 0xE5, 0xF2, 0xF2, 0x8B, 0x9E, 0x32, 0xFA,
+ 0xD0, 0xD2, 0x8D, 0x5E, 0xA5, 0xA5, 0xB9, 0xE4, 0xA9, 0x1A, 0x36, 0x30, 0xDF, 0x4D, 0xD4, 0x8D,
+ 0x48, 0xC6, 0x0D, 0xBD, 0x3C, 0x50, 0xED, 0x6E, 0xAB, 0x3C, 0xAE, 0x57, 0xA5, 0x6B, 0x12, 0xE6,
+ 0xC8, 0xD6, 0xF2, 0xEE, 0xF2, 0xC0, 0x70, 0x52, 0x7A, 0x5D, 0xB5, 0xE9, 0xA8, 0x23, 0x1A, 0x82,
+ 0x44, 0x6F, 0x5B, 0x59, 0x86, 0xDD, 0xD6, 0xD3, 0x30, 0x72, 0x44, 0x52, 0x55, 0x62, 0x81, 0x5F,
+ 0x6F, 0xDA, 0x56, 0x55, 0x59, 0x5C, 0x6B, 0x2C, 0x0F, 0x3A, 0x1B, 0x6D, 0x95, 0xC5, 0x54, 0xB7,
+ 0x47, 0xD7, 0x9B, 0x6A, 0x57, 0x2C, 0xEC, 0x68, 0x17, 0xBD, 0x9E, 0x80, 0x9D, 0xC0, 0x1A, 0xF8,
+ 0xDD, 0xC0, 0xDB, 0xD2, 0xA7, 0xD7, 0x96, 0x05, 0xAE, 0xA9, 0xB8, 0x72, 0xA7, 0xE0, 0x59, 0x72,
+ 0x64, 0x61, 0x66, 0x2F, 0x95, 0x8E, 0x99, 0xB6, 0x98, 0x85, 0x29, 0xF2, 0xC8, 0xE0, 0xEB, 0x65,
+ 0x7B, 0x2C, 0x32, 0x29, 0xAD, 0x0C, 0xF4, 0x1D, 0xEC, 0x93, 0xDB, 0xDB, 0xA6, 0xA5, 0x1B, 0x6B,
+ 0x75, 0x23, 0xDE, 0xE2, 0x98, 0x56, 0xA3, 0xAA, 0xB7, 0x4F, 0xB5, 0x54, 0x97, 0x97, 0x75, 0x34,
+ 0x54, 0xB7, 0x85, 0xFC, 0x38, 0xAD, 0x35, 0x9C, 0x76, 0xDA, 0x8A, 0x91, 0x55, 0xCD, 0x35, 0x65,
+ 0x65, 0x65, 0x29, 0x7F, 0x56, 0x46, 0x8F, 0x75, 0x64, 0x1A, 0xD6, 0x30, 0xC5, 0x49, 0xD4, 0x35,
+ 0x94, 0x0B, 0xF9, 0x92, 0xB3, 0xF9, 0x92, 0x0B, 0x97, 0x45, 0xCC, 0xB9, 0x26, 0x1A, 0x19, 0x7C,
+ 0x43, 0x51, 0xD9, 0xBB, 0xB4, 0x56, 0x3C, 0xF7, 0xBD, 0x70, 0xE6, 0xF8, 0x66, 0x74, 0x78, 0xA7,
+ 0x8C, 0xEB, 0xAC, 0x9B, 0xB2, 0x7C, 0x4C, 0x76, 0xF9, 0x98, 0x85, 0x87, 0xAC, 0xDD, 0xBE, 0x6E,
+ 0x4D, 0x66, 0x5D, 0x36, 0xBD, 0x6E, 0xE0, 0xF9, 0x75, 0x65, 0xC7, 0xAF, 0xAB, 0x8D, 0xAD, 0x6B,
+ 0x98, 0xBD, 0x6E, 0xF1, 0xF2, 0xE5, 0x7C, 0x4C, 0xDF, 0xC4, 0xDF, 0xAB, 0x2F, 0x0E, 0xCD, 0xB9,
+ 0x4D, 0x19, 0x5A, 0x5C, 0x3C, 0xF4, 0x37, 0xF6, 0x19, 0x56, 0x62, 0x01, 0x94, 0x74, 0xB0, 0xD6,
+ 0x35, 0x0F, 0x2D, 0x3C, 0x6E, 0xC1, 0x4B, 0xFF, 0xBC, 0x6B, 0xF7, 0x41, 0x79, 0x25, 0xAB, 0x94,
+ 0x3B, 0x4B, 0x56, 0x29, 0xCB, 0x99, 0xAA, 0x1E, 0x61, 0x28, 0xAB, 0x85, 0x85, 0xCA, 0x9D, 0xF1,
+ 0x8A, 0x39, 0x8D, 0xE5, 0x13, 0xE2, 0x9F, 0x6F, 0x81, 0xFF, 0x82, 0xC6, 0x9A, 0xA5, 0xA5, 0xEB,
+ 0x9A, 0x63, 0xE3, 0xA2, 0x75, 0xCD, 0x41, 0x22, 0x3B, 0x6D, 0x6E, 0x43, 0xB3, 0xA2, 0xC5, 0xF2,
+ 0x6B, 0x9B, 0xC7, 0x8F, 0xAD, 0xA9, 0x35, 0x15, 0xA6, 0xFC, 0xBB, 0x47, 0x00, 0x0E, 0xEF, 0x6A,
+ 0x9B, 0x57, 0xBA, 0x04, 0x7A, 0x4C, 0x7E, 0x05, 0xF4, 0xC8, 0xD6, 0x86, 0xDA, 0x5E, 0x3F, 0xC6,
+ 0xC5, 0x78, 0xC3, 0x27, 0xB9, 0x47, 0x18, 0x5A, 0x09, 0xF5, 0x40, 0x9F, 0x9D, 0xDB, 0x37, 0xAD,
+ 0xB1, 0x26, 0x11, 0x37, 0x68, 0xDC, 0x98, 0x96, 0xCE, 0xA9, 0x63, 0x3B, 0xA7, 0x2A, 0x9D, 0x53,
+ 0x2B, 0x7B, 0x33, 0x63, 0xEA, 0x32, 0x5E, 0x5D, 0xA6, 0x72, 0xE4, 0x88, 0x9E, 0xC6, 0x77, 0xE6,
+ 0xCE, 0xDC, 0x3A, 0x77, 0xF6, 0xCE, 0xB9, 0x73, 0x9D, 0x1D, 0x73, 0xA7, 0xFE, 0x57, 0xE7, 0xB3,
+ 0x13, 0x7A, 0x61, 0x45, 0xD6, 0xF1, 0x0C, 0xAD, 0x8A, 0x1F, 0x54, 0xB0, 0xC1, 0x7B, 0x8B, 0x73,
+ 0x7D, 0xBD, 0xD1, 0xC8, 0x83, 0xC7, 0xE6, 0xE6, 0xAB, 0xA3, 0x77, 0xCA, 0xBE, 0xFB, 0x0F, 0xED,
+ 0xBD, 0x99, 0xE5, 0xDC, 0xB8, 0x34, 0x26, 0xA2, 0x6D, 0x51, 0x51, 0xEE, 0xA2, 0x6A, 0x1A, 0x7A,
+ 0x5A, 0x4A, 0xD6, 0x41, 0x65, 0x60, 0x70, 0xC1, 0xAA, 0x68, 0x6E, 0x10, 0x0F, 0xAC, 0x47, 0xB3,
+ 0xE2, 0xD2, 0x8C, 0x18, 0x87, 0x7A, 0x94, 0x76, 0x04, 0xEA, 0x81, 0xBD, 0x57, 0xDE, 0xD0, 0xA8,
+ 0xA4, 0x2A, 0xEB, 0xDA, 0x2F, 0x5F, 0xDC, 0x39, 0xAA, 0x26, 0xD3, 0x92, 0x5C, 0xAC, 0xA4, 0xF2,
+ 0x2B, 0xA4, 0x4C, 0xBD, 0x65, 0x7C, 0x66, 0x6C, 0x6F, 0x68, 0xC4, 0x7C, 0xAE, 0xB4, 0x2E, 0xED,
+ 0xAE, 0xA8, 0x98, 0x9C, 0x6A, 0x39, 0xC6, 0xAE, 0x54, 0x6D, 0xFE, 0xA5, 0x54, 0x9B, 0x19, 0x0B,
+ 0x83, 0xC9, 0xFC, 0xC0, 0xA6, 0xB1, 0x5D, 0x3C, 0x68, 0x3E, 0x48, 0xAC, 0x99, 0x6A, 0x99, 0xA6,
+ 0xEB, 0xC7, 0x29, 0x15, 0x25, 0x2B, 0xA7, 0x6A, 0x95, 0x90, 0x77, 0x1F, 0xD8, 0x30, 0x52, 0x2E,
+ 0x9C, 0x72, 0xD6, 0xC2, 0x50, 0x58, 0x0A, 0x9A, 0x32, 0x3D, 0xE5, 0xC6, 0xCA, 0x32, 0x4D, 0x87,
+ 0x9D, 0xE5, 0xE7, 0xA6, 0xB0, 0x3F, 0xF0, 0x2A, 0x0A, 0xA8, 0x93, 0xFA, 0xFB, 0xCA, 0x9A, 0x42,
+ 0x5D, 0xE7, 0x76, 0x23, 0xB7, 0xBB, 0x3A, 0x97, 0x75, 0xD9, 0x9C, 0xB7, 0xF1, 0x2A, 0x67, 0x80,
+ 0x55, 0x15, 0x58, 0x26, 0xC9, 0x16, 0x88, 0x31, 0x41, 0x8F, 0xCD, 0x2F, 0x9A, 0xEF, 0xB2, 0xE0,
+ 0xC6, 0xB0, 0xB2, 0xA1, 0x1D, 0xF9, 0xF2, 0x1B, 0xF2, 0x55, 0x45, 0x03, 0x03, 0x72, 0x35, 0x79,
+ 0xA4, 0x79, 0x12, 0x25, 0xFB, 0x79, 0xF5, 0x2A, 0x72, 0xFF, 0x98, 0xFC, 0x73, 0x5D, 0xAC, 0x87,
+ 0xAD, 0x8D, 0xE7, 0xB7, 0xDA, 0xCB, 0xCA, 0x8D, 0xF7, 0x4E, 0x3E, 0x66, 0xC4, 0x64, 0xD7, 0x75,
+ 0x5B, 0x5B, 0x67, 0xB6, 0x1B, 0xFB, 0xEE, 0xD3, 0xC7, 0x29, 0x5B, 0xDC, 0x6C, 0xCF, 0x9F, 0xC9,
+ 0xBD, 0xDD, 0xD7, 0xAD, 0xA8, 0x53, 0x74, 0x6F, 0xCC, 0xEC, 0xF1, 0xC3, 0xED, 0xD2, 0x27, 0xC6,
+ 0x43, 0x67, 0xE7, 0xC6, 0xD3, 0x6E, 0x9E, 0x20, 0x0F, 0xBA, 0x62, 0x56, 0x5F, 0x32, 0x61, 0xA5,
+ 0x75, 0x1D, 0x9D, 0x05, 0x3F, 0xC9, 0xC5, 0xCB, 0xDE, 0x56, 0x58, 0xFA, 0x0F, 0x74, 0x09, 0xB6,
+ 0xB0, 0xB7, 0xEC, 0x36, 0x70, 0xEF, 0x01, 0x85, 0xA6, 0xBA, 0xF7, 0x66, 0x83, 0x59, 0x2B, 0xDA,
+ 0xB2, 0x1E, 0xD8, 0x9A, 0x25, 0xB4, 0x84, 0xAF, 0xF4, 0xF2, 0x1A, 0xFE, 0x66, 0x22, 0xDA, 0x93,
+ 0xBB, 0x4B, 0xEC, 0xCF, 0xDD, 0x30, 0xA2, 0xAD, 0x6D, 0x44, 0x74, 0x14, 0x0C, 0xFB, 0x38, 0x5B,
+ 0xD8, 0xA2, 0xBB, 0x72, 0x26, 0xDF, 0xBD, 0xA3, 0xAA, 0xAA, 0xBA, 0x26, 0x3A, 0x0C, 0x06, 0x39,
+ 0xAB, 0x46, 0xF6, 0x9E, 0xE7, 0x77, 0xCA, 0x3D, 0x1D, 0xE7, 0xF4, 0x41, 0x65, 0xE8, 0x24, 0x4E,
+ 0xBC, 0x21, 0x5D, 0x28, 0x60, 0x85, 0xA1, 0x0B, 0xC6, 0x0A, 0x03, 0x33, 0xB7, 0x11, 0x67, 0x8B,
+ 0xF6, 0x38, 0xF4, 0x46, 0x0C, 0x9B, 0x1D, 0x08, 0xCD, 0x75, 0x1B, 0xA9, 0xE2, 0x3D, 0xBF, 0xCB,
+ 0xE3, 0x08, 0x16, 0xD6, 0x29, 0x61, 0x5D, 0xC8, 0x9F, 0xDF, 0x3D, 0x8B, 0xDF, 0x59, 0xBE, 0xFB,
+ 0x44, 0x7E, 0xE7, 0xEE, 0x01, 0x7E, 0xDE, 0xEE, 0x13, 0xA9, 0x38, 0x0F, 0xB3, 0xAC, 0x38, 0x0F,
+ 0xF3, 0x02, 0x33, 0xE8, 0xB2, 0xE2, 0x48, 0xF2, 0xED, 0xC5, 0x91, 0xE4, 0x17, 0xE8, 0x6A, 0x79,
+ 0xE2, 0xD4, 0x48, 0xE8, 0xA6, 0xB7, 0xE4, 0x6E, 0xE5, 0x15, 0x34, 0x82, 0x96, 0xF4, 0x35, 0x8B,
+ 0x8D, 0x42, 0xBD, 0x64, 0x4B, 0x65, 0x7D, 0x25, 0xAF, 0x47, 0x27, 0x8F, 0xBC, 0xFA, 0xA4, 0xC7,
+ 0x93, 0x2D, 0xE5, 0xF6, 0xE4, 0x81, 0x9A, 0xAA, 0xD0, 0x67, 0xAA, 0x32, 0xB4, 0xD6, 0x27, 0x23,
+ 0xCE, 0xAE, 0x91, 0xA2, 0x22, 0x95, 0xAB, 0x34, 0x5A, 0x86, 0x1A, 0x96, 0x58, 0x8A, 0x56, 0x9F,
+ 0x7F, 0xAC, 0x25, 0xBF, 0x47, 0x67, 0xB1, 0xCF, 0xB7, 0xD7, 0x67, 0xFE, 0x56, 0xC9, 0x9E, 0xE7,
+ 0x4F, 0xED, 0xE7, 0x73, 0xE9, 0x5E, 0xE8, 0x95, 0xFB, 0xF9, 0x5C, 0x9C, 0x1F, 0x3C, 0xB5, 0x38,
+ 0x3F, 0x38, 0x33, 0x9A, 0x89, 0xCA, 0xFB, 0x9F, 0x54, 0xF4, 0x7F, 0x8E, 0x9E, 0x2C, 0x99, 0xD1,
+ 0x3A, 0xA9, 0x38, 0xA3, 0xF5, 0x1C, 0x3D, 0x20, 0xB5, 0x33, 0xFC, 0x63, 0x35, 0xE8, 0xA3, 0xAC,
+ 0xA3, 0x1F, 0xF4, 0xF5, 0x0F, 0xAC, 0x5E, 0xBA, 0x70, 0x52, 0x5D, 0x4D, 0x99, 0x45, 0xF3, 0x67,
+ 0xCE, 0x18, 0x5F, 0x6D, 0xCC, 0x5C, 0x3D, 0xDA, 0x58, 0x3D, 0x7A, 0xCE, 0xA1, 0xA3, 0xD7, 0xAC,
+ 0x74, 0xD5, 0xCA, 0x89, 0x87, 0xD0, 0xB9, 0xEB, 0x5B, 0x77, 0xAE, 0x5F, 0x7C, 0xC6, 0x9C, 0x55,
+ 0x2B, 0x4F, 0x3F, 0xB8, 0x7F, 0xF4, 0xAA, 0xD5, 0xDB, 0x0F, 0x5E, 0xB7, 0x76, 0xBB, 0x65, 0xC6,
+ 0xA0, 0x54, 0x5C, 0xC7, 0x56, 0x46, 0xF3, 0x35, 0x87, 0x1D, 0xBC, 0x38, 0x76, 0xE8, 0xC2, 0xDE,
+ 0x1F, 0xC6, 0x8D, 0xA1, 0xE3, 0x63, 0x0A, 0xDB, 0xE9, 0xCB, 0xA1, 0x64, 0x31, 0x3E, 0x70, 0x1B,
+ 0xCD, 0xC9, 0xEF, 0x93, 0x96, 0x67, 0x2A, 0xB9, 0xBC, 0x6F, 0x9F, 0x1E, 0xE4, 0x9E, 0x0F, 0x37,
+ 0xAC, 0x2F, 0xDB, 0x6B, 0xAF, 0xB4, 0xF1, 0x43, 0x7B, 0x6B, 0x14, 0x3A, 0x3D, 0x62, 0x73, 0x0D,
+ 0xB1, 0x91, 0xA0, 0x5A, 0xD2, 0xED, 0x49, 0x67, 0xF2, 0x7B, 0x81, 0x15, 0x7A, 0x93, 0xC5, 0xAD,
+ 0xD4, 0x6A, 0x58, 0xB4, 0x91, 0x5A, 0xAC, 0xA6, 0x74, 0x23, 0x35, 0xC5, 0x5F, 0x3E, 0xB4, 0x0B,
+ 0x87, 0xE8, 0x00, 0x15, 0xB6, 0xE1, 0xC8, 0xFA, 0x46, 0xD0, 0xBD, 0xD7, 0x36, 0x1C, 0x73, 0xEA,
+ 0xAB, 0xA2, 0xED, 0xD6, 0xF2, 0x7D, 0xCA, 0xD2, 0x0D, 0xD7, 0x94, 0x7D, 0xF6, 0x5B, 0x2B, 0x53,
+ 0xDC, 0x19, 0xC3, 0xEE, 0xD5, 0x31, 0x7B, 0x46, 0x5D, 0x6A, 0x52, 0xD3, 0xE1, 0xA5, 0x7B, 0x75,
+ 0x24, 0x2A, 0xF6, 0xD9, 0x90, 0xED, 0x3C, 0xB9, 0x1D, 0x9B, 0x98, 0x03, 0x7E, 0x83, 0x7F, 0xCA,
+ 0xDE, 0xA1, 0x35, 0x74, 0x78, 0xDF, 0xD8, 0xA5, 0x07, 0xCE, 0xEB, 0x6D, 0x47, 0x8F, 0x26, 0x9B,
+ 0x89, 0xD3, 0x84, 0xAE, 0xB1, 0xF3, 0x46, 0x65, 0xFA, 0x47, 0xB5, 0xF5, 0xAC, 0xD9, 0x3E, 0x78,
+ 0x68, 0x66, 0x70, 0xD5, 0xF3, 0x83, 0xD6, 0x09, 0x83, 0x35, 0x5B, 0x07, 0xEB, 0x76, 0x0E, 0x7A,
+ 0x3B, 0x06, 0xA7, 0xBC, 0xA0, 0xBE, 0x38, 0xB4, 0x84, 0x2F, 0x28, 0xAA, 0x89, 0x29, 0x62, 0xD4,
+ 0x6A, 0x98, 0x9E, 0xE6, 0x60, 0xBC, 0x44, 0x6D, 0xD7, 0xEF, 0xB5, 0x3E, 0x36, 0x62, 0xFE, 0x1E,
+ 0xB1, 0x4B, 0x13, 0x2F, 0xD5, 0x0D, 0x51, 0x2F, 0x73, 0x18, 0xA5, 0x2D, 0xF7, 0x3A, 0x8C, 0x2C,
+ 0x36, 0x31, 0x4B, 0xFE, 0x69, 0x41, 0x6D, 0xD7, 0xF9, 0x5C, 0x3F, 0xAA, 0x64, 0x45, 0xED, 0x3C,
+ 0xA9, 0x13, 0x0C, 0xE6, 0x8E, 0x3A, 0xA4, 0x33, 0x34, 0x23, 0xAD, 0xD1, 0xD3, 0xD1, 0x19, 0x4F,
+ 0x5B, 0x0D, 0x23, 0xF7, 0x55, 0xD8, 0x99, 0x3A, 0x4D, 0x0F, 0x0F, 0xDF, 0x43, 0x61, 0xD7, 0x67,
+ 0x8D, 0x23, 0xF6, 0x58, 0x79, 0xDB, 0xAA, 0xE9, 0x0B, 0xE3, 0xF1, 0x54, 0xEB, 0xC1, 0xD1, 0xDA,
+ 0xDB, 0x66, 0xBF, 0x3C, 0x55, 0xD7, 0xB8, 0xAF, 0xAA, 0xAE, 0x69, 0x8A, 0xC7, 0x6A, 0xAB, 0x3A,
+ 0xD6, 0x49, 0x5D, 0x2D, 0xCE, 0xA1, 0xFB, 0x88, 0x8D, 0x62, 0x87, 0x81, 0x3D, 0x1A, 0xFB, 0x34,
+ 0xF9, 0x44, 0x24, 0x93, 0x23, 0x5E, 0x87, 0x44, 0x1C, 0xB6, 0x64, 0xAF, 0xE7, 0x22, 0x9B, 0xEA,
+ 0xC6, 0xD7, 0xB1, 0x51, 0x9F, 0x3D, 0xCD, 0x46, 0x7D, 0xF4, 0xC5, 0xE8, 0x6E, 0xBE, 0xE2, 0xFF,
+ 0xEE, 0x6E, 0xBE, 0x62, 0xF7, 0x4E, 0xBE, 0x02, 0x77, 0x73, 0x98, 0x8F, 0x6F, 0xB0, 0x3B, 0x60,
+ 0x33, 0x27, 0xD1, 0x9B, 0xE8, 0xEC, 0x73, 0x46, 0x34, 0x57, 0xC7, 0x7D, 0xD2, 0x53, 0x4D, 0x03,
+ 0xE5, 0x72, 0x44, 0x4B, 0x61, 0xCB, 0x7A, 0xA7, 0x48, 0x1D, 0x36, 0x5D, 0xEA, 0xB0, 0x67, 0xA8,
+ 0x64, 0x39, 0x73, 0x75, 0xB4, 0x7F, 0x83, 0x5C, 0x02, 0xA3, 0xCA, 0x67, 0x7C, 0xA2, 0xE7, 0xF9,
+ 0xC7, 0xC8, 0xCD, 0xA9, 0xF3, 0x5E, 0x69, 0x76, 0x87, 0x37, 0x6A, 0x8C, 0xE9, 0xF4, 0x55, 0x14,
+ 0xCF, 0x9B, 0x78, 0xD8, 0x4B, 0x8C, 0xC9, 0x9A, 0x96, 0xDD, 0x2D, 0xBC, 0x9C, 0x1E, 0x78, 0x75,
+ 0xF1, 0x0E, 0xB7, 0x29, 0xAD, 0xEA, 0xE3, 0xEA, 0x33, 0x55, 0x4E, 0x2C, 0x61, 0x34, 0xC4, 0xED,
+ 0xAA, 0x74, 0x45, 0xB3, 0x2D, 0x76, 0x0E, 0x56, 0x75, 0xAB, 0xAD, 0xA1, 0x3C, 0xEB, 0xC5, 0x42,
+ 0xA3, 0x21, 0xB4, 0xAA, 0x53, 0x95, 0x6D, 0xF2, 0xD4, 0x2E, 0xF6, 0x5A, 0x69, 0xBE, 0xDB, 0xAA,
+ 0x2B, 0x1C, 0x53, 0x4B, 0xD4, 0x35, 0x0D, 0xA8, 0x32, 0xDF, 0x59, 0xB6, 0x5C, 0xE6, 0xDB, 0x1F,
+ 0x2E, 0xDF, 0x8E, 0x38, 0xFE, 0xA5, 0xB8, 0xB9, 0x71, 0x77, 0x8F, 0x30, 0x49, 0x32, 0x79, 0x8F,
+ 0xE6, 0x96, 0x68, 0x3F, 0x44, 0x31, 0x6D, 0x5C, 0x7A, 0x42, 0x86, 0x84, 0x70, 0x6F, 0x31, 0xBF,
+ 0x5E, 0x01, 0x02, 0xEF, 0x29, 0xCD, 0x6F, 0x01, 0x44, 0x4D, 0x49, 0x6E, 0x8D, 0x21, 0x10, 0xF2,
+ 0x9C, 0x95, 0x37, 0xE8, 0x65, 0xE4, 0x3B, 0x4D, 0x4D, 0x7D, 0x5A, 0x32, 0x34, 0x29, 0x1A, 0x39,
+ 0x8C, 0xA1, 0x9C, 0x4F, 0x14, 0xD3, 0xDF, 0xD3, 0x4B, 0xCE, 0xED, 0xC8, 0x98, 0xE2, 0x19, 0x94,
+ 0x7D, 0x0A, 0xF4, 0xE5, 0xE1, 0x8A, 0x6F, 0x7F, 0x25, 0x35, 0x94, 0x62, 0x52, 0xA4, 0x28, 0xCE,
+ 0x08, 0x89, 0x52, 0x54, 0xA3, 0x14, 0xFD, 0x3D, 0x52, 0x4C, 0x0D, 0x57, 0x34, 0xFB, 0x14, 0xC3,
+ 0xF0, 0x98, 0x65, 0x5A, 0xA8, 0x9A, 0x4F, 0xF8, 0xB3, 0xA5, 0xCF, 0xF6, 0x5E, 0x2E, 0x4E, 0x44,
+ 0xD8, 0xE7, 0xD9, 0x5E, 0xA1, 0x73, 0xF9, 0x27, 0xBB, 0x47, 0xF2, 0x3F, 0xF2, 0x67, 0xC5, 0xAA,
+ 0x09, 0xB1, 0xEE, 0x4C, 0xCE, 0xCB, 0x1E, 0x9A, 0x9F, 0x97, 0x95, 0x33, 0xCD, 0xD1, 0x3E, 0x01,
+ 0x72, 0x15, 0xC4, 0x94, 0xA1, 0x55, 0x10, 0xC4, 0x72, 0x4B, 0x72, 0xAF, 0xB2, 0x6E, 0x7E, 0x13,
+ 0xD2, 0x69, 0xEB, 0x33, 0x8B, 0xDB, 0x2E, 0x93, 0x18, 0x81, 0x5D, 0x25, 0xC4, 0x9E, 0xD8, 0x4A,
+ 0x24, 0x58, 0x32, 0xD6, 0x2F, 0xC6, 0x62, 0x4D, 0xD6, 0xC0, 0x58, 0xF7, 0x67, 0xC7, 0x1E, 0xCC,
+ 0xBE, 0xC9, 0x6F, 0xDA, 0xDD, 0xCD, 0x1F, 0x21, 0x79, 0x52, 0xE5, 0x3C, 0xDC, 0xBF, 0x00, 0x39,
+ 0x1F, 0x4B, 0xDB, 0xFA, 0x46, 0x57, 0x86, 0xB6, 0x95, 0x4D, 0xC6, 0x33, 0x2D, 0x34, 0x5A, 0x6D,
+ 0x40, 0x5F, 0xBC, 0xB6, 0xD1, 0x6C, 0xF3, 0xF8, 0xC2, 0xF6, 0x96, 0x54, 0x66, 0xCE, 0xE8, 0x14,
+ 0x6F, 0xE4, 0xB5, 0xC9, 0x36, 0xEE, 0x55, 0x0C, 0x98, 0xA5, 0x26, 0x10, 0x13, 0x9B, 0x76, 0x49,
+ 0x53, 0x68, 0x75, 0xFE, 0xD4, 0x1B, 0xBC, 0x48, 0x14, 0xF1, 0xA1, 0xBD, 0x72, 0x0C, 0x93, 0x0D,
+ 0x6D, 0x34, 0xB9, 0xA7, 0x65, 0x2C, 0xD6, 0xEE, 0xCA, 0x47, 0x25, 0xA3, 0xE1, 0xF9, 0x16, 0x74,
+ 0x46, 0xA2, 0xDE, 0x49, 0x4B, 0x4F, 0x46, 0x52, 0x5B, 0x06, 0x7D, 0xCE, 0x68, 0xBA, 0xAE, 0xA5,
+ 0x64, 0x30, 0x9F, 0x2B, 0x3D, 0x13, 0xB2, 0x8B, 0x46, 0xB4, 0x1D, 0x50, 0x39, 0xA1, 0x07, 0xFD,
+ 0x81, 0xB2, 0xF2, 0x89, 0x7B, 0x7D, 0x1F, 0xBF, 0x74, 0xEA, 0x94, 0x65, 0xC2, 0x9D, 0xDE, 0x33,
+ 0x31, 0x0D, 0x55, 0x3E, 0xB1, 0x67, 0x52, 0xD9, 0xA2, 0xB6, 0xD1, 0x0B, 0xCA, 0x27, 0xED, 0xF5,
+ 0xFD, 0xA2, 0xA9, 0xAB, 0x57, 0x4D, 0x83, 0x13, 0xE7, 0xAC, 0xB0, 0x34, 0xBD, 0xC2, 0x1E, 0x82,
+ 0xE5, 0xD2, 0xDE, 0x67, 0x47, 0xE7, 0xAC, 0x0C, 0xB0, 0xC2, 0xBC, 0x83, 0x60, 0x82, 0xC3, 0x24,
+ 0x48, 0x9B, 0x0D, 0xEC, 0x73, 0xDA, 0x4A, 0x62, 0x3F, 0xA7, 0xAD, 0xB0, 0xD5, 0xA5, 0xC7, 0xAD,
+ 0x14, 0x6D, 0x86, 0x4D, 0x45, 0x9B, 0x61, 0x17, 0xBD, 0x28, 0x6D, 0x89, 0x68, 0xD5, 0xCC, 0xA6,
+ 0xE2, 0xAA, 0x19, 0x39, 0xFA, 0x3C, 0x8C, 0xED, 0x71, 0x01, 0x6A, 0x7F, 0x28, 0xFC, 0x96, 0x62,
+ 0xF8, 0x0B, 0xE9, 0x27, 0x25, 0xFE, 0x43, 0xAB, 0x6F, 0x66, 0x46, 0xE1, 0xC5, 0xEE, 0x85, 0x2C,
+ 0x2E, 0xFD, 0x47, 0x45, 0xF1, 0xE4, 0xFE, 0x4B, 0xFA, 0x33, 0xF8, 0x77, 0xC9, 0x74, 0x47, 0xE5,
+ 0xD3, 0xF5, 0x65, 0x3C, 0xEF, 0xC3, 0x7F, 0xA2, 0x8C, 0x7F, 0x54, 0x3E, 0x7E, 0xB5, 0x18, 0x8F,
+ 0x51, 0x12, 0xCF, 0x4C, 0xD8, 0x38, 0x43, 0x36, 0xCF, 0xA9, 0x45, 0x9B, 0xE7, 0x02, 0xBA, 0xB5,
+ 0xC4, 0x7F, 0x53, 0xD1, 0x7F, 0x97, 0xC8, 0xCF, 0xFF, 0x7B, 0x3B, 0xD9, 0x27, 0x9D, 0x99, 0xD1,
+ 0xD8, 0x4F, 0xDE, 0x4A, 0x3D, 0xB5, 0x68, 0xA5, 0x5E, 0x40, 0xEF, 0x95, 0xF8, 0x6F, 0x2A, 0xFA,
+ 0x8B, 0x31, 0xA1, 0xE1, 0xC2, 0xCF, 0x64, 0x2D, 0xB2, 0x5D, 0x89, 0x35, 0x23, 0xAF, 0xB0, 0xBF,
+ 0x83, 0x9D, 0x7A, 0xFA, 0xE2, 0x0E, 0xD9, 0x86, 0xC6, 0x53, 0x5C, 0xE5, 0xE9, 0x01, 0xF1, 0x48,
+ 0x95, 0x53, 0xDC, 0x8A, 0x4D, 0x8C, 0x1B, 0xAF, 0xE9, 0xCD, 0x4B, 0xFA, 0xD0, 0x76, 0x09, 0x19,
+ 0x27, 0x7A, 0xAE, 0x6A, 0xDF, 0x87, 0xFB, 0x5E, 0xD9, 0xF7, 0x69, 0xBE, 0xFE, 0x61, 0x1E, 0xDF,
+ 0x13, 0x39, 0xE0, 0xA3, 0x59, 0x23, 0xBF, 0x16, 0xE2, 0x37, 0xAA, 0xCF, 0x88, 0x91, 0xAA, 0xC9,
+ 0x9D, 0x07, 0x44, 0x8B, 0x1E, 0x84, 0x4D, 0x27, 0xDA, 0x94, 0xD5, 0x2B, 0x2D, 0x79, 0xCE, 0xFA,
+ 0x76, 0x47, 0xC9, 0x46, 0xFB, 0x0D, 0xC8, 0x11, 0x25, 0xD6, 0x18, 0x0D, 0x1F, 0xF1, 0xD1, 0x2B,
+ 0x57, 0x6E, 0x43, 0x6C, 0x4F, 0xF3, 0x2E, 0x36, 0x87, 0xDF, 0x02, 0xEE, 0xEB, 0xE9, 0x0B, 0xC8,
+ 0xD3, 0xED, 0x30, 0xA6, 0x1F, 0xE5, 0x85, 0x47, 0xC5, 0xBC, 0x81, 0x98, 0x64, 0x41, 0x4B, 0x4C,
+ 0x14, 0x9E, 0x28, 0xBA, 0x6A, 0x8E, 0x38, 0x35, 0xB2, 0x64, 0xAF, 0x15, 0xC1, 0x86, 0xB6, 0xDC,
+ 0xDA, 0x53, 0xC8, 0x76, 0x71, 0xE5, 0x9D, 0x9C, 0x32, 0x63, 0x73, 0x32, 0x99, 0xEA, 0xD6, 0xD4,
+ 0x39, 0x61, 0xA2, 0xDC, 0xAD, 0xA8, 0x68, 0x6F, 0x4C, 0x9D, 0x56, 0x11, 0xAF, 0x74, 0xF9, 0x95,
+ 0x0D, 0x0D, 0xCD, 0xAD, 0xA9, 0x64, 0xB2, 0xB3, 0xA7, 0x15, 0x26, 0x12, 0xCB, 0x3D, 0xC5, 0xE7,
+ 0xB1, 0xD9, 0x7C, 0x07, 0x7A, 0x51, 0x6D, 0x7D, 0xE8, 0x57, 0x39, 0x1D, 0xAA, 0x61, 0x99, 0xBB,
+ 0x06, 0x24, 0x33, 0xAC, 0x13, 0xA5, 0x48, 0x6C, 0x2D, 0xC8, 0xB7, 0x37, 0x7A, 0x6E, 0x1A, 0x09,
+ 0xFA, 0x62, 0x01, 0xA2, 0x3C, 0xF0, 0xAE, 0x21, 0xB2, 0x24, 0xD9, 0x6C, 0x2F, 0x3B, 0x62, 0x4D,
+ 0x75, 0xDD, 0x96, 0x44, 0x7D, 0x7C, 0x70, 0xC2, 0xE8, 0x95, 0x7C, 0xC7, 0xD8, 0xCA, 0x18, 0xD7,
+ 0xE6, 0x70, 0xF9, 0x74, 0xEA, 0xCB, 0xBC, 0x0E, 0x2C, 0x78, 0x3B, 0xD9, 0xD4, 0xDC, 0xA7, 0xAB,
+ 0x64, 0xAC, 0x54, 0xEC, 0x01, 0xD9, 0x52, 0xD7, 0x8B, 0xC8, 0x35, 0x18, 0xBE, 0x12, 0x52, 0x7E,
+ 0x5E, 0x5C, 0xCD, 0x2F, 0x23, 0x6C, 0x89, 0xB6, 0x8B, 0x60, 0xDD, 0xC9, 0x55, 0x53, 0xCF, 0x1A,
+ 0x51, 0xDF, 0xB6, 0x7E, 0xD4, 0xFC, 0x80, 0x5F, 0x39, 0x75, 0xC6, 0xE9, 0xD9, 0x03, 0x9A, 0x9B,
+ 0x20, 0x83, 0x2B, 0x78, 0x1B, 0xBD, 0x28, 0x67, 0xA8, 0xC0, 0x03, 0xD6, 0x30, 0x3C, 0xD0, 0xDD,
+ 0x5B, 0x98, 0x94, 0x2A, 0xE5, 0x01, 0xB7, 0x94, 0x07, 0x78, 0x26, 0xFD, 0xE2, 0xF0, 0xD3, 0x4E,
+ 0x82, 0x73, 0x6D, 0x9E, 0x64, 0x36, 0x7F, 0x49, 0xCE, 0x7F, 0x76, 0xF5, 0xF9, 0xFE, 0x46, 0x33,
+ 0xB5, 0x51, 0x89, 0xE6, 0x3A, 0x4B, 0xD3, 0xD9, 0x20, 0x27, 0xF6, 0xDD, 0x92, 0x6D, 0xEC, 0xC5,
+ 0x6A, 0xC8, 0x7F, 0x31, 0xC7, 0xC9, 0xEC, 0xF9, 0x3D, 0xDD, 0x0B, 0xE6, 0xF7, 0x4C, 0x98, 0x37,
+ 0xAF, 0xAC, 0xB6, 0x3A, 0x2B, 0x1C, 0x3F, 0xA9, 0x63, 0xDC, 0xF8, 0xF6, 0xAE, 0xCE, 0xCE, 0xAE,
+ 0xDA, 0x86, 0xC6, 0x1A, 0x38, 0x21, 0x63, 0x9F, 0xE4, 0x5A, 0xE9, 0x35, 0x00, 0x4B, 0xD0, 0xDC,
+ 0xBE, 0xCA, 0x40, 0x0D, 0xC9, 0xF3, 0x8C, 0x64, 0x88, 0x8E, 0xD8, 0x03, 0x8A, 0x27, 0x72, 0x47,
+ 0x81, 0x4F, 0xCA, 0x5F, 0x8B, 0xA7, 0x74, 0x45, 0xFD, 0xDA, 0xFC, 0xCA, 0x6F, 0x51, 0xAE, 0x47,
+ 0xE4, 0xF7, 0x5B, 0x8E, 0x0A, 0x36, 0x89, 0x82, 0xCD, 0x44, 0xEB, 0xCF, 0xD2, 0x85, 0xE5, 0x67,
+ 0x5D, 0x7A, 0x67, 0xFA, 0xB5, 0xD9, 0x1D, 0x33, 0xBB, 0x6B, 0xEA, 0xBB, 0xC2, 0x74, 0x4B, 0x63,
+ 0x7B, 0x47, 0x45, 0xE3, 0xF8, 0x33, 0x1B, 0xC6, 0xB5, 0x57, 0x54, 0x04, 0x6E, 0x90, 0x3A, 0x7A,
+ 0x4A, 0x8B, 0x18, 0xA3, 0x79, 0x8C, 0x27, 0xD8, 0xC9, 0x72, 0x16, 0x51, 0xA7, 0x8E, 0x3E, 0x5F,
+ 0xE3, 0xE8, 0xC9, 0x0A, 0x4D, 0xA6, 0x2B, 0x4F, 0xE6, 0xCD, 0x18, 0xC6, 0xBE, 0x98, 0x3F, 0xCF,
+ 0xB4, 0xE4, 0x74, 0xCF, 0x8E, 0xFC, 0xA9, 0xA6, 0x50, 0x16, 0xA2, 0x8D, 0xB1, 0x93, 0xEF, 0x6E,
+ 0xFD, 0xE6, 0xF1, 0x70, 0xFC, 0xB4, 0xA3, 0x2A, 0xB7, 0xF7, 0xC0, 0x91, 0xEC, 0x6D, 0xB5, 0xD2,
+ 0x5F, 0x80, 0x31, 0x14, 0xCF, 0xA7, 0x99, 0xE4, 0xF3, 0xF0, 0x92, 0xB8, 0xFF, 0x00, 0x77, 0xB8,
+ 0x6A, 0x1A, 0xC4, 0xFF, 0x9A, 0x47, 0x55, 0x14, 0xF8, 0xE8, 0x94, 0x2E, 0x81, 0x24, 0x5F, 0xB4,
+ 0x62, 0xDF, 0x7B, 0x59, 0xAA, 0x3D, 0x7F, 0x19, 0xD9, 0xD9, 0x3A, 0x75, 0x46, 0xC7, 0xD8, 0xB6,
+ 0xC6, 0xB2, 0x54, 0x55, 0xD9, 0xDD, 0xD9, 0x8E, 0xD6, 0xC6, 0xB9, 0xD9, 0xD6, 0xB1, 0xD5, 0xC9,
+ 0xA6, 0x70, 0xEF, 0xF6, 0xAA, 0xA0, 0xFE, 0x62, 0x4A, 0x5E, 0x11, 0x0F, 0x46, 0x8A, 0xD8, 0x12,
+ 0x27, 0x9D, 0xCA, 0x1E, 0xF7, 0xC6, 0x42, 0x7B, 0x55, 0xE4, 0xC1, 0xA4, 0x2D, 0x5D, 0x99, 0x1E,
+ 0xD6, 0xB8, 0xE6, 0xE8, 0x23, 0x4E, 0x68, 0xEF, 0xE0, 0xD7, 0x6E, 0xDB, 0xB6, 0x64, 0x09, 0x15,
+ 0xAF, 0xF5, 0x7B, 0xB9, 0x7F, 0x46, 0x67, 0x60, 0xF3, 0x2F, 0x13, 0xC5, 0xAA, 0x89, 0x54, 0xA8,
+ 0x6E, 0xBD, 0x0C, 0x6E, 0x11, 0xDC, 0xE3, 0x44, 0x06, 0xDE, 0xCD, 0xF3, 0x89, 0xAC, 0x18, 0xDC,
+ 0x46, 0xB8, 0xD7, 0x89, 0xEC, 0x59, 0x70, 0x57, 0x12, 0x39, 0x87, 0xC0, 0x3D, 0x49, 0xE4, 0x7E,
+ 0x0F, 0x7D, 0xEF, 0x55, 0x44, 0x3E, 0xFA, 0xEB, 0x41, 0x00, 0xB7, 0x8B, 0x28, 0xBC, 0x88, 0x28,
+ 0x7E, 0x23, 0x51, 0xE2, 0x68, 0x02, 0x45, 0xC0, 0xFD, 0x82, 0x28, 0x55, 0x0F, 0x77, 0x1A, 0xDC,
+ 0x9B, 0x44, 0xE9, 0x47, 0x89, 0x32, 0xAF, 0x12, 0x95, 0xDD, 0x4D, 0x54, 0xFE, 0x0C, 0x51, 0xF6,
+ 0x62, 0xA2, 0x8A, 0xB3, 0x88, 0x2A, 0xF1, 0xB9, 0xEA, 0x5D, 0xA2, 0xEA, 0x47, 0xC4, 0xB1, 0xDC,
+ 0x70, 0x9F, 0x10, 0xD5, 0x21, 0x9E, 0x7A, 0x84, 0x6D, 0xB8, 0x8E, 0xA8, 0x11, 0xAE, 0xE9, 0x69,
+ 0xA2, 0xE6, 0xAB, 0x89, 0x5A, 0x8E, 0x23, 0x6A, 0x5D, 0x4B, 0x34, 0x02, 0x71, 0xB6, 0x6D, 0x21,
+ 0x1A, 0x89, 0x84, 0x46, 0x3E, 0x44, 0x34, 0xEA, 0x0C, 0xA2, 0xD1, 0x37, 0x83, 0x3C, 0xEF, 0x24,
+ 0x1A, 0x7B, 0x19, 0x51, 0x3B, 0xF2, 0xDF, 0x01, 0x2B, 0xA7, 0x03, 0xF9, 0xEC, 0x5C, 0x08, 0xF7,
+ 0x2B, 0xB8, 0xF7, 0x88, 0xBA, 0x9A, 0x89, 0xC6, 0x21, 0x6F, 0xE3, 0x90, 0x9F, 0xF1, 0xDF, 0x26,
+ 0xEA, 0x46, 0x5C, 0x90, 0x4A, 0x9A, 0x00, 0xCF, 0x89, 0x28, 0x9B, 0x49, 0xCB, 0x88, 0x26, 0xA7,
+ 0xE1, 0x90, 0xDE, 0x54, 0x84, 0x9B, 0x8A, 0xFB, 0xA7, 0xDD, 0x4A, 0xD4, 0x8B, 0xF4, 0xFA, 0xD0,
+ 0xDC, 0xA6, 0xE3, 0xB7, 0xE9, 0x2F, 0x13, 0xCD, 0xB8, 0x9D, 0x68, 0xE6, 0x4E, 0xA2, 0x59, 0xC0,
+ 0x3C, 0xFB, 0x42, 0xA2, 0x39, 0xD0, 0x20, 0x73, 0x91, 0xDE, 0x3C, 0x94, 0xCF, 0x7C, 0x68, 0x4B,
+ 0x31, 0x91, 0xB5, 0x00, 0x61, 0x16, 0x7C, 0x40, 0x74, 0x00, 0xB0, 0x2C, 0x6C, 0x87, 0x43, 0x99,
+ 0x2F, 0x1C, 0x24, 0x3A, 0xF0, 0x12, 0xB8, 0x9B, 0xE0, 0x1E, 0x80, 0x7B, 0x09, 0xEE, 0x63, 0xA2,
+ 0x45, 0x0E, 0x1C, 0x9A, 0xD3, 0x22, 0xC4, 0xB1, 0x08, 0x71, 0x2C, 0x42, 0x19, 0x2E, 0x3A, 0x87,
+ 0xE8, 0x20, 0x84, 0x3B, 0xE8, 0x7E, 0xB8, 0x17, 0xE1, 0x3E, 0x24, 0xEA, 0xB7, 0xE0, 0x6A, 0xE1,
+ 0xBA, 0xE1, 0x80, 0xAB, 0x1F, 0xF9, 0xEF, 0x47, 0x3D, 0xF6, 0x23, 0x1F, 0xFD, 0xC8, 0x4F, 0xFF,
+ 0xBD, 0x70, 0x28, 0xCF, 0xFE, 0xB7, 0x89, 0x16, 0xA3, 0xFE, 0x16, 0x57, 0xC2, 0x01, 0xDB, 0xE2,
+ 0x85, 0x43, 0xEE, 0x60, 0x60, 0x59, 0x82, 0x78, 0x0F, 0x41, 0x7C, 0x4B, 0xA7, 0x45, 0x6E, 0x19,
+ 0xEA, 0x64, 0x39, 0xF2, 0xBB, 0x02, 0x79, 0x5B, 0x79, 0x0A, 0x1C, 0xEA, 0x6E, 0x15, 0xE4, 0x60,
+ 0xD5, 0x06, 0xA2, 0x43, 0x91, 0xB7, 0x01, 0x7C, 0x1E, 0x58, 0x9F, 0x77, 0xF8, 0x7D, 0x00, 0x65,
+ 0x77, 0x18, 0xF2, 0xB4, 0x06, 0x75, 0x35, 0x88, 0xFA, 0x1F, 0x04, 0xE6, 0xC1, 0x3E, 0x38, 0xC8,
+ 0xD6, 0xE1, 0x71, 0x38, 0x94, 0xEF, 0xDA, 0x73, 0xE1, 0xAE, 0x80, 0xC8, 0x41, 0xC6, 0xBE, 0xB0,
+ 0x95, 0x68, 0x03, 0xAC, 0xD1, 0x0D, 0x1F, 0x47, 0xEE, 0x88, 0x0D, 0x79, 0x87, 0xBC, 0x1C, 0x71,
+ 0xC9, 0x90, 0x3B, 0xF2, 0xC8, 0xBC, 0x43, 0x7D, 0x1E, 0x79, 0x29, 0x1C, 0xEA, 0x74, 0x23, 0xD2,
+ 0x3C, 0x0A, 0xB2, 0x71, 0xB4, 0x01, 0x37, 0x07, 0xEE, 0x33, 0xA2, 0x4D, 0xC8, 0xDF, 0x31, 0x48,
+ 0xF3, 0x98, 0x6F, 0xE7, 0x1D, 0x64, 0xEB, 0x18, 0xC8, 0xCB, 0x31, 0x9F, 0x12, 0x1D, 0x8B, 0x30,
+ 0xC7, 0xF5, 0xEF, 0xC7, 0xDD, 0xBA, 0x97, 0xC3, 0x7D, 0xC7, 0xE1, 0xBE, 0xE3, 0x70, 0xDF, 0x66,
+ 0xC8, 0xD2, 0x66, 0xD4, 0xF1, 0x66, 0xC8, 0xFA, 0x66, 0xE4, 0x75, 0x33, 0xF2, 0xBC, 0x19, 0x72,
+ 0xB4, 0xF9, 0x1A, 0x38, 0xC8, 0xD5, 0x66, 0x94, 0xD7, 0x16, 0x94, 0xC5, 0x16, 0xD4, 0xD3, 0x16,
+ 0xD4, 0xD3, 0x16, 0xD4, 0xD3, 0x16, 0x94, 0xF5, 0xF1, 0xF8, 0x7E, 0x3C, 0x64, 0x73, 0x2B, 0xBA,
+ 0x9F, 0x5B, 0xD1, 0x1E, 0xB6, 0xA2, 0x1C, 0x4F, 0x98, 0x04, 0x77, 0x1F, 0xD1, 0x89, 0xC0, 0x7E,
+ 0xE2, 0x76, 0x71, 0x9E, 0xFD, 0xFF, 0x17, 0x97, 0x3F, 0x13, 0x3E, 0x37, 0x41, 0x36, 0xB8, 0x7D,
+ 0xAF, 0xFF, 0x2D, 0xD7, 0x15, 0x0B, 0xBB, 0x1C, 0xCA, 0x1F, 0xAC, 0xA2, 0x93, 0x41, 0x26, 0x59,
+ 0xD0, 0x15, 0x0E, 0x2C, 0x53, 0x0F, 0xF6, 0x59, 0x00, 0x4E, 0x8B, 0x83, 0xBB, 0x93, 0x94, 0x82,
+ 0x9D, 0x92, 0xA1, 0x32, 0x2A, 0xA7, 0x2C, 0x55, 0x50, 0x25, 0x55, 0x51, 0x35, 0xD5, 0x50, 0x2D,
+ 0xD5, 0x51, 0x3D, 0x2C, 0xAC, 0x46, 0x6A, 0x12, 0x33, 0x26, 0xB0, 0x04, 0x47, 0x50, 0x1B, 0x7A,
+ 0x89, 0xA3, 0x68, 0x34, 0x8D, 0x81, 0x95, 0xDF, 0x4E, 0x1D, 0xB0, 0x9E, 0xBA, 0xD0, 0xA8, 0xC6,
+ 0x53, 0x37, 0xF5, 0xC0, 0x02, 0x9A, 0x48, 0x93, 0x68, 0x32, 0x7A, 0x18, 0x53, 0x69, 0x1A, 0xF5,
+ 0x52, 0x1F, 0x4D, 0xA7, 0x19, 0xB0, 0xAC, 0x66, 0xD1, 0x6C, 0x9A, 0x43, 0x73, 0x69, 0x1E, 0xCD,
+ 0x47, 0xE3, 0x38, 0x80, 0x16, 0xD2, 0x81, 0xB4, 0x88, 0x0E, 0xA2, 0x7E, 0x5A, 0x4C, 0x07, 0xD3,
+ 0x12, 0x3A, 0x84, 0x96, 0xD2, 0x32, 0x5A, 0x4E, 0x2B, 0x68, 0x25, 0xAD, 0xA2, 0xD5, 0xE8, 0xB9,
+ 0x0C, 0xD0, 0x61, 0xB4, 0x86, 0x06, 0xE9, 0x70, 0x5A, 0x4B, 0xEB, 0xC0, 0x5B, 0x5F, 0xA0, 0x0D,
+ 0x74, 0x04, 0x1D, 0x49, 0x5F, 0xA4, 0x8D, 0x74, 0x14, 0x1D, 0x4D, 0x9B, 0xE8, 0x18, 0x3A, 0x96,
+ 0x8E, 0xA3, 0xCD, 0xB4, 0x85, 0x8E, 0xA7, 0xAD, 0x74, 0x02, 0x9D, 0x48, 0x5F, 0xA2, 0x6D, 0x74,
+ 0x12, 0x7D, 0x99, 0x4E, 0xA6, 0x53, 0xE8, 0x54, 0x3A, 0x8D, 0x4E, 0xA7, 0x33, 0xE8, 0x4C, 0x3A,
+ 0x8B, 0xCE, 0xA6, 0x73, 0xE8, 0x2B, 0xB4, 0x9D, 0xBE, 0x4A, 0xE7, 0xD2, 0xD7, 0xE8, 0x3C, 0xFA,
+ 0x3A, 0x9D, 0x0F, 0xAB, 0xEE, 0x42, 0xFA, 0x06, 0x5D, 0x44, 0xDF, 0xA4, 0x8B, 0xE9, 0x5B, 0xF4,
+ 0x6D, 0xFA, 0x0E, 0x5D, 0x42, 0xDF, 0xA5, 0x4B, 0x69, 0x07, 0x7D, 0x0F, 0xFD, 0xA5, 0xCB, 0xE8,
+ 0x72, 0xBA, 0x82, 0xFE, 0x83, 0xAE, 0xA4, 0xAB, 0xE8, 0x6A, 0xFA, 0x01, 0x5D, 0x43, 0xD7, 0xD2,
+ 0x75, 0x74, 0x3D, 0xED, 0xA4, 0x1F, 0xD2, 0x8F, 0xE8, 0x06, 0xBA, 0x91, 0x7E, 0x4C, 0x37, 0xC1,
+ 0x4E, 0xBE, 0x99, 0x6E, 0xA1, 0x9F, 0xD2, 0xCF, 0x60, 0xA1, 0xFE, 0x9C, 0x7E, 0x41, 0xBF, 0xA4,
+ 0x5F, 0x81, 0xAD, 0x6F, 0xA7, 0x3B, 0xE8, 0x4E, 0xBA, 0x8B, 0xEE, 0xA6, 0x7B, 0xE8, 0x5E, 0xFA,
+ 0x35, 0xDD, 0x47, 0xBF, 0xA1, 0xFB, 0xE9, 0xB7, 0xF4, 0x00, 0x3D, 0x08, 0xBB, 0xF0, 0x61, 0x7A,
+ 0x84, 0x7E, 0x47, 0x8F, 0xD2, 0x63, 0xF4, 0x38, 0x3D, 0x41, 0x4F, 0xD2, 0x53, 0xF4, 0x7B, 0xFA,
+ 0x03, 0x3D, 0x4D, 0x7F, 0xA4, 0x67, 0xE8, 0x59, 0xD8, 0xB4, 0xCF, 0xD1, 0xF3, 0xF4, 0x02, 0x2C,
+ 0xF9, 0x3F, 0xD1, 0x4B, 0xF4, 0x67, 0x7A, 0x99, 0xFE, 0x13, 0x9A, 0xE7, 0x15, 0x7A, 0x95, 0xFE,
+ 0x17, 0xFD, 0x15, 0x7A, 0xF6, 0x75, 0x7A, 0x03, 0x56, 0xEA, 0x5B, 0xF4, 0x36, 0xBD, 0x43, 0xEF,
+ 0xD2, 0xDF, 0x60, 0x99, 0xBE, 0x4F, 0x1F, 0xD0, 0xDF, 0xE9, 0x43, 0xF4, 0xE5, 0x3E, 0x96, 0x63,
+ 0xA6, 0xF2, 0x62, 0x8D, 0xF9, 0x13, 0xF9, 0x2B, 0xC5, 0x29, 0xFA, 0xF2, 0x3B, 0xB4, 0x09, 0x15,
+ 0x8F, 0xFB, 0x67, 0x8A, 0x5C, 0xA9, 0xBB, 0xE7, 0x85, 0x1F, 0x95, 0x98, 0xAA, 0xE9, 0x06, 0xBA,
+ 0xC3, 0xE2, 0x88, 0x8D, 0x20, 0x8C, 0x27, 0x92, 0xA9, 0x74, 0xA6, 0xAC, 0x3C, 0x5B, 0x51, 0x59,
+ 0x55, 0x5D, 0x53, 0x2B, 0x36, 0x17, 0x6E, 0x6A, 0x6E, 0x69, 0x1D, 0xD1, 0x36, 0x72, 0xD4, 0xE8,
+ 0x31, 0x63, 0xDB, 0x3B, 0x3A, 0xBB, 0xC6, 0x8D, 0xEF, 0xEE, 0x99, 0x30, 0x71, 0xD2, 0xE4, 0x29,
+ 0x53, 0xA7, 0xF5, 0xF6, 0x4D, 0x9F, 0x31, 0x73, 0xD6, 0xEC, 0x39, 0x73, 0xE7, 0xCD, 0x5F, 0x70,
+ 0xC0, 0xC2, 0x03, 0x17, 0x1D, 0xD4, 0xBF, 0xF8, 0xE0, 0x25, 0x87, 0x2C, 0x5D, 0xB6, 0x7C, 0xC5,
+ 0xCA, 0x55, 0xAB, 0x0F, 0x1D, 0x38, 0x6C, 0xCD, 0x20, 0xAA, 0x72, 0xDD, 0xFA, 0x2F, 0x6C, 0x38,
+ 0xE2, 0xC8, 0x2F, 0x6E, 0x3C, 0xEA, 0xE8, 0x4D, 0xC7, 0x1C, 0x7B, 0xDC, 0xE6, 0x2D, 0xC7, 0x6F,
+ 0x3D, 0xE1, 0xC4, 0x2F, 0x6D, 0x3B, 0xE9, 0xCB, 0x27, 0x9F, 0x72, 0xEA, 0x69, 0xA7, 0x9F, 0x71,
+ 0xE6, 0x59, 0x67, 0x9F, 0xF3, 0x95, 0xED, 0x5F, 0x3D, 0xF7, 0x6B, 0xE7, 0x7D, 0xFD, 0xFC, 0x0B,
+ 0x2E, 0xFC, 0xC6, 0x45, 0xDF, 0xBC, 0xF8, 0x5B, 0xDF, 0xFE, 0xCE, 0x25, 0xDF, 0xBD, 0x74, 0xC7,
+ 0xF7, 0xBE, 0x7F, 0xD9, 0xE5, 0x57, 0xFC, 0xC7, 0x95, 0x57, 0x5D, 0xFD, 0x83, 0x6B, 0xAE, 0xBD,
+ 0xEE, 0xFA, 0x9D, 0x3F, 0xFC, 0xD1, 0x0D, 0x37, 0xFE, 0xF8, 0xA6, 0x9F, 0xDC, 0x7C, 0xCB, 0x4F,
+ 0x7F, 0x76, 0xEB, 0xCF, 0x7F, 0xF1, 0xCB, 0x5F, 0xDD, 0x76, 0xFB, 0x1D, 0x77, 0xDE, 0x75, 0xF7,
+ 0x3D, 0xF7, 0xFE, 0xFA, 0xBE, 0xDF, 0xDC, 0xFF, 0xDB, 0x07, 0x1E, 0x7C, 0xE8, 0xE1, 0x47, 0x7E,
+ 0xF7, 0xE8, 0x63, 0x8F, 0x3F, 0xF1, 0xE4, 0x53, 0xBF, 0xFF, 0xC3, 0xD3, 0x7F, 0x7C, 0xE6, 0xD9,
+ 0x5D, 0xCF, 0x3D, 0xFF, 0xC2, 0x8B, 0x7F, 0x7A, 0xE9, 0xCF, 0x2F, 0xFF, 0x27, 0x50, 0xC6, 0x14,
+ 0x61, 0xA5, 0x2F, 0x82, 0x64, 0xAA, 0x68, 0x01, 0xA7, 0x51, 0x8E, 0x75, 0xB0, 0x19, 0x6C, 0x09,
+ 0x3B, 0x9C, 0x6D, 0x63, 0xA7, 0xB2, 0xD3, 0xD9, 0xC5, 0xFC, 0x76, 0xFE, 0x20, 0x7F, 0x98, 0xBF,
+ 0xA8, 0xFC, 0x40, 0xF9, 0xA1, 0x72, 0x6F, 0x6D, 0xB2, 0x36, 0x5B, 0x5B, 0x5D, 0x5B, 0x5F, 0xDB,
+ 0x5C, 0xDB, 0x5E, 0x3B, 0xA9, 0xAE, 0xBE, 0x9E, 0xD7, 0x6B, 0xF5, 0x7E, 0x7D, 0xBC, 0x3E, 0x55,
+ 0x9F, 0xAD, 0xAF, 0xAE, 0x1F, 0x59, 0x3F, 0xAF, 0x7E, 0xB0, 0xFE, 0x0B, 0x4D, 0x8F, 0xBC, 0xC7,
+ 0x45, 0x4F, 0x00, 0xED, 0xE5, 0x4A, 0xC4, 0x37, 0x9D, 0x1D, 0xCC, 0x06, 0x4B, 0xE2, 0x7B, 0x00,
+ 0xF1, 0xED, 0xCA, 0xC7, 0x97, 0xA8, 0x2D, 0xAB, 0xAD, 0xAC, 0xAD, 0x95, 0xF1, 0x4D, 0xDC, 0x23,
+ 0xBE, 0xF2, 0x62, 0x7C, 0xEB, 0x11, 0x9F, 0x1C, 0x2F, 0xFF, 0x6F, 0xBC, 0x18, 0x2D, 0x62, 0x16,
+ 0x7B, 0x08, 0x7F, 0x8F, 0xB0, 0x47, 0xD9, 0xE3, 0x25, 0x7F, 0x4F, 0xE2, 0x6F, 0x57, 0xFE, 0xEF,
+ 0x79, 0xF6, 0x12, 0xFB, 0x0B, 0xFB, 0xAB, 0xFC, 0x7B, 0x7D, 0x8F, 0xBF, 0x37, 0x8B, 0x7F, 0x6F,
+ 0xB3, 0xB7, 0xA5, 0xA4, 0xFD, 0x4F, 0xE6, 0x94, 0x1B, 0xD1, 0xA6, 0x05, 0x27, 0xDC, 0x85, 0x56,
+ 0xFF, 0x3A, 0x98, 0xE1, 0x42, 0x70, 0xC2, 0xE5, 0x68, 0xDB, 0xD7, 0x20, 0xF7, 0xE7, 0xA1, 0x05,
+ 0x9E, 0x0D, 0x4E, 0x10, 0xED, 0xEA, 0x02, 0x70, 0xC2, 0xB9, 0x68, 0xBF, 0x2F, 0xA1, 0x9D, 0x5D,
+ 0x81, 0x96, 0xFF, 0x11, 0x5A, 0xDA, 0xC7, 0x60, 0x84, 0x1F, 0xA3, 0x1D, 0x3F, 0x08, 0x06, 0x10,
+ 0xDC, 0x74, 0x11, 0xD8, 0xE9, 0x77, 0xE0, 0xA7, 0x87, 0xD0, 0xB2, 0x9F, 0xC8, 0xB7, 0xEC, 0x37,
+ 0xC0, 0x56, 0x7F, 0x90, 0xAD, 0xFB, 0x27, 0x60, 0xAD, 0xF7, 0xC0, 0x32, 0xCF, 0xC8, 0x36, 0x7E,
+ 0x24, 0xDA, 0xEE, 0x3B, 0xE0, 0xA0, 0x8D, 0xE0, 0xB1, 0xA3, 0xC0, 0x61, 0x47, 0x83, 0xC5, 0xAE,
+ 0x04, 0x8F, 0x6D, 0x06, 0x93, 0x09, 0x1E, 0x3B, 0x01, 0x4C, 0x26, 0x78, 0xEC, 0x4D, 0x30, 0xD9,
+ 0x97, 0xC1, 0x65, 0x27, 0x83, 0xC7, 0x4E, 0x01, 0xAB, 0x5C, 0x05, 0x2E, 0x3B, 0x4D, 0xB2, 0xD9,
+ 0xDB, 0x68, 0xF7, 0xB7, 0x83, 0x29, 0x04, 0x2B, 0x08, 0xF6, 0x11, 0xCC, 0x70, 0x87, 0xE4, 0x86,
+ 0xEB, 0xC0, 0x17, 0xBB, 0xC0, 0x17, 0x05, 0xFE, 0x78, 0x19, 0x5C, 0xB2, 0x03, 0x1C, 0xF6, 0x7D,
+ 0xC9, 0x50, 0x82, 0x9D, 0xEE, 0x97, 0x3C, 0xF5, 0x5B, 0x30, 0xE2, 0x7D, 0xE0, 0xC2, 0x1B, 0xC0,
+ 0x48, 0x82, 0xA3, 0xCE, 0x07, 0xEB, 0xED, 0x04, 0xEB, 0xFD, 0x0D, 0xAC, 0xF5, 0x1B, 0xF0, 0xDC,
+ 0xC5, 0x60, 0xBF, 0xEB, 0xC1, 0x8D, 0x82, 0x13, 0x6F, 0x03, 0x3B, 0x81, 0xC3, 0xCE, 0xFE, 0x54,
+ 0xA9, 0x95, 0xBD, 0x64, 0x62, 0xD9, 0xBC, 0x9B, 0x85, 0x7E, 0xEE, 0x77, 0x68, 0x0A, 0x9F, 0x47,
+ 0x0D, 0x7C, 0x1B, 0xD5, 0x2A, 0x4F, 0x53, 0x83, 0x62, 0xD0, 0x08, 0x30, 0xCB, 0x3C, 0x36, 0x92,
+ 0x26, 0xC2, 0x11, 0x3B, 0x09, 0xBF, 0xAD, 0xA0, 0xB1, 0xF0, 0x6B, 0x60, 0x37, 0xA3, 0xFE, 0x3F,
+ 0xA3, 0x91, 0x7C, 0x29, 0xE9, 0x3C, 0xA4, 0x14, 0x6B, 0x23, 0x83, 0xFD, 0x06, 0x5D, 0xDF, 0x23,
+ 0xD0, 0x47, 0x70, 0x29, 0xCE, 0xAE, 0x47, 0x27, 0xE8, 0x49, 0xCA, 0xB0, 0xAB, 0xE0, 0xFF, 0x30,
+ 0x25, 0xD8, 0x9F, 0x29, 0xCB, 0x12, 0x34, 0x19, 0x69, 0x75, 0x8B, 0x38, 0x0A, 0x8E, 0x7D, 0x44,
+ 0x29, 0xE4, 0xA5, 0x8A, 0xBF, 0x96, 0x7B, 0x83, 0x9F, 0x92, 0x7B, 0x86, 0x2F, 0xA3, 0x0A, 0xFE,
+ 0x10, 0xDE, 0x07, 0x73, 0x6F, 0xF1, 0x4E, 0xB8, 0x9D, 0xF8, 0xED, 0x43, 0x9A, 0xC3, 0xC6, 0x91,
+ 0xC7, 0x26, 0x21, 0xAD, 0x6B, 0xC8, 0xE3, 0xAD, 0xE4, 0xC5, 0x42, 0x6A, 0x53, 0x3A, 0x10, 0xEE,
+ 0x39, 0xAA, 0xE5, 0x13, 0x73, 0x7F, 0x42, 0x4F, 0xAF, 0x82, 0x5F, 0x8D, 0xF7, 0x8D, 0x54, 0xC3,
+ 0xAF, 0xCA, 0xBD, 0xA5, 0x34, 0x81, 0x10, 0xDF, 0xCF, 0xBD, 0x1A, 0x7B, 0x26, 0xF7, 0x2A, 0x7F,
+ 0x14, 0xF7, 0x7D, 0x80, 0xDF, 0x96, 0x53, 0x35, 0x9B, 0x4C, 0x03, 0xEC, 0x89, 0xDC, 0x5B, 0x6C,
+ 0x72, 0xEE, 0x1F, 0x48, 0xBF, 0x97, 0x37, 0xE4, 0xFE, 0xC1, 0xD2, 0xB9, 0x1C, 0x9F, 0x4D, 0x29,
+ 0x3E, 0x2E, 0xF7, 0x3A, 0xFB, 0x15, 0xDE, 0x27, 0x03, 0xEB, 0x7D, 0x54, 0xC9, 0x56, 0xE3, 0x9E,
+ 0xAD, 0x94, 0xE0, 0xEB, 0x72, 0xAF, 0xB0, 0x8A, 0xDC, 0x07, 0xC2, 0xF1, 0xF6, 0xDC, 0xEB, 0xF4,
+ 0x69, 0xEE, 0x55, 0xE5, 0x49, 0xE4, 0x4D, 0x8C, 0xB4, 0x7D, 0x8A, 0x74, 0x9B, 0x90, 0x46, 0x25,
+ 0xC2, 0x7F, 0x1D, 0xF1, 0xDE, 0x46, 0xF5, 0xAC, 0x0B, 0xBF, 0x6D, 0x40, 0xD8, 0x51, 0x08, 0xF7,
+ 0x2D, 0xFC, 0x36, 0x16, 0x79, 0x5E, 0x8A, 0xDF, 0xEE, 0x47, 0x98, 0xC9, 0x68, 0x63, 0x2F, 0x51,
+ 0xAF, 0x78, 0x47, 0xFA, 0xB3, 0x25, 0x6E, 0xE1, 0x04, 0x6E, 0x60, 0x2E, 0x60, 0x92, 0xF9, 0x17,
+ 0x79, 0x1A, 0xC6, 0x89, 0x3C, 0xCA, 0xFC, 0x95, 0xBA, 0x7C, 0xFE, 0xF2, 0xEE, 0xB5, 0x42, 0xDE,
+ 0xF6, 0x76, 0x32, 0x5F, 0x25, 0xAE, 0x48, 0x27, 0xF7, 0xE1, 0xB7, 0x33, 0x90, 0xA6, 0x9E, 0x7B,
+ 0x9C, 0x7D, 0x28, 0xD7, 0x79, 0x11, 0xBF, 0x39, 0xF7, 0x27, 0x51, 0x37, 0xD2, 0xBD, 0x44, 0xD3,
+ 0x58, 0x1A, 0x2D, 0xF9, 0xB3, 0xDC, 0xDB, 0x22, 0xAF, 0xB1, 0xC6, 0xDC, 0x2B, 0xC8, 0xA7, 0x27,
+ 0xF2, 0x22, 0xC3, 0x8A, 0x7A, 0x12, 0x65, 0xB5, 0x1A, 0x78, 0x45, 0xDC, 0x88, 0x43, 0x96, 0x1B,
+ 0xEA, 0x4C, 0x96, 0x1B, 0xEA, 0x85, 0x0D, 0x90, 0xCB, 0x3A, 0x28, 0x60, 0xDF, 0xA7, 0x7A, 0xA5,
+ 0x0C, 0x18, 0x3E, 0xCD, 0x7D, 0x82, 0xFA, 0xF7, 0x99, 0x68, 0xF9, 0x22, 0x8E, 0x4F, 0xC4, 0x0C,
+ 0x26, 0xA8, 0x48, 0x60, 0x2F, 0xC9, 0x9B, 0xE2, 0xD0, 0x48, 0x21, 0xA3, 0xC5, 0xB2, 0x42, 0xF9,
+ 0xC4, 0x5A, 0x51, 0x46, 0x69, 0x60, 0x12, 0x9D, 0x66, 0x58, 0x69, 0xEC, 0x19, 0xC8, 0xA4, 0x70,
+ 0x4A, 0xE4, 0xE4, 0x7D, 0x15, 0x90, 0x57, 0x94, 0xBB, 0xA8, 0x7B, 0xBA, 0x3E, 0xB7, 0x84, 0x6B,
+ 0x05, 0x7D, 0xBA, 0xD7, 0xF5, 0x99, 0x5C, 0x2D, 0x54, 0xBC, 0x64, 0x1A, 0x42, 0xFE, 0x0A, 0xEF,
+ 0x70, 0x52, 0xFE, 0xC6, 0xA1, 0xE7, 0x36, 0x2E, 0xF7, 0xBE, 0xF8, 0x2C, 0xE5, 0x4E, 0xD4, 0x93,
+ 0x48, 0x23, 0x5F, 0x5F, 0x05, 0x27, 0xEB, 0x20, 0x2D, 0xDD, 0xD3, 0x70, 0x4F, 0xC1, 0xBD, 0x8C,
+ 0x34, 0x56, 0xA0, 0xFC, 0x6C, 0x7C, 0xFE, 0x04, 0xEE, 0x31, 0x7C, 0xAE, 0x15, 0x61, 0xFE, 0x1B,
+ 0x35, 0x42, 0xC9, 0x05, 0x5D, 0x73, 0x15, 0xB0, 0x06, 0x60, 0xB6, 0x5B, 0xF9, 0xE3, 0xB9, 0xF7,
+ 0xD8, 0xA3, 0xA8, 0xD1, 0xEB, 0x69, 0x16, 0xBF, 0x0B, 0x8C, 0xF7, 0x29, 0xB8, 0xB5, 0x1F, 0x5C,
+ 0xBA, 0x1C, 0x1C, 0x3A, 0x08, 0xD6, 0x3A, 0x0E, 0x61, 0x4F, 0x03, 0xAB, 0xFD, 0x52, 0x19, 0x93,
+ 0x3B, 0x4B, 0xB2, 0x72, 0x2F, 0xDA, 0xE6, 0x3D, 0xD2, 0x36, 0xDB, 0x0C, 0x06, 0xDB, 0x06, 0xE6,
+ 0x58, 0x47, 0x1B, 0xF9, 0x15, 0xB9, 0xBF, 0xD1, 0x97, 0x94, 0x30, 0xF7, 0x35, 0xB0, 0xF6, 0x3C,
+ 0x70, 0xAB, 0x98, 0xAD, 0x3C, 0x86, 0x3F, 0xC2, 0xBE, 0x4B, 0x8F, 0xB1, 0x7F, 0x82, 0xBF, 0xAF,
+ 0xCE, 0xDD, 0x25, 0x38, 0x0F, 0x2C, 0xF1, 0x0F, 0xF2, 0x50, 0xE3, 0x73, 0x73, 0xEF, 0xA2, 0x6B,
+ 0x3D, 0x27, 0xF7, 0x3E, 0x38, 0x30, 0xB2, 0xD6, 0xCE, 0xE4, 0x0B, 0xA9, 0x3B, 0xF7, 0x08, 0x38,
+ 0x72, 0x0B, 0xB4, 0xC9, 0x8D, 0x7C, 0x55, 0xEE, 0x6D, 0xEA, 0xC9, 0x3D, 0x0C, 0x26, 0x5A, 0xC4,
+ 0x0F, 0x04, 0x47, 0x0B, 0x8B, 0x2C, 0x4E, 0xDF, 0x60, 0x6F, 0x91, 0xC1, 0x39, 0xBB, 0x14, 0x6C,
+ 0xFC, 0x20, 0x7F, 0x0A, 0x5A, 0xE0, 0x20, 0xF0, 0x58, 0x3D, 0xF8, 0x7F, 0x15, 0x18, 0x6C, 0x01,
+ 0x58, 0xFF, 0x2C, 0xFE, 0x7C, 0xEE, 0xC3, 0x02, 0xFF, 0xF3, 0x27, 0xC0, 0x7A, 0x3A, 0xBF, 0x0F,
+ 0xCC, 0xE8, 0xD0, 0xD1, 0xFC, 0x21, 0xC9, 0xB2, 0x36, 0xFF, 0x75, 0xEE, 0x23, 0x69, 0x53, 0x9E,
+ 0x08, 0xDE, 0x3D, 0x05, 0x08, 0x2E, 0x05, 0x33, 0xC2, 0x76, 0xE3, 0xF7, 0x83, 0x81, 0xCF, 0xC8,
+ 0x5B, 0x87, 0xDF, 0x07, 0x33, 0x7C, 0x17, 0xDC, 0x3D, 0x11, 0x1A, 0x6E, 0x1D, 0x1D, 0xCB, 0x77,
+ 0xF1, 0x67, 0x73, 0x75, 0xD0, 0x7E, 0x29, 0xFA, 0x02, 0xFF, 0x23, 0xF4, 0xC9, 0x04, 0xE8, 0xF9,
+ 0x57, 0xF8, 0xCB, 0xB4, 0x4C, 0xEE, 0x65, 0x3E, 0x1D, 0x9C, 0xBB, 0x9E, 0xFF, 0x2E, 0xD7, 0x03,
+ 0x4D, 0xB1, 0x16, 0xDA, 0x45, 0x68, 0xA5, 0xFB, 0x20, 0xF1, 0xBF, 0xCF, 0xBD, 0x03, 0x09, 0xB8,
+ 0x05, 0xDA, 0xB2, 0x99, 0xBF, 0x90, 0x7B, 0x9E, 0xBF, 0x05, 0xEE, 0xBD, 0x0C, 0x5A, 0x60, 0x27,
+ 0x7F, 0x1B, 0xE5, 0xD7, 0x0E, 0xCD, 0x37, 0x37, 0x77, 0x0E, 0x4D, 0xE7, 0x17, 0x33, 0x8B, 0x1A,
+ 0x72, 0x03, 0xB9, 0x49, 0xFC, 0xE7, 0xBC, 0x8A, 0xBD, 0x0B, 0x99, 0xEB, 0x50, 0x32, 0x74, 0x3B,
+ 0x7B, 0x93, 0x7F, 0x0B, 0x5A, 0xF5, 0x70, 0xF6, 0x4E, 0xEE, 0x0D, 0xE4, 0xF2, 0x4E, 0xF6, 0x5E,
+ 0xAE, 0x89, 0x5F, 0x9F, 0x4B, 0x2B, 0x29, 0x68, 0xDA, 0x6C, 0xAE, 0x15, 0x79, 0xCB, 0x88, 0x59,
+ 0x62, 0x68, 0xE9, 0x2B, 0xA0, 0xDF, 0x96, 0x42, 0xFB, 0x5D, 0xC8, 0x37, 0xA1, 0xDD, 0x9C, 0xCF,
+ 0x5E, 0x61, 0x7F, 0x43, 0x5B, 0xD5, 0xE8, 0xA7, 0xB9, 0x2A, 0xE8, 0x93, 0x6B, 0xE8, 0x06, 0xAE,
+ 0xE4, 0xCE, 0x63, 0x87, 0xD0, 0x75, 0xCA, 0x16, 0xE5, 0x6C, 0x68, 0xE5, 0xB3, 0xA0, 0x83, 0x27,
+ 0xE7, 0xE6, 0x2B, 0xA7, 0x2A, 0x27, 0xF1, 0x6B, 0xF9, 0x8F, 0xF8, 0x2D, 0xFC, 0x25, 0xD4, 0xF7,
+ 0x57, 0x90, 0xF3, 0x9F, 0x43, 0x9F, 0xED, 0xA0, 0x23, 0x79, 0x7F, 0x6E, 0x3B, 0x4A, 0xE3, 0x00,
+ 0xE8, 0x94, 0xAF, 0xF1, 0x7F, 0xD2, 0xCF, 0x78, 0x05, 0x34, 0xCB, 0x24, 0xC8, 0x40, 0x9F, 0xB4,
+ 0x70, 0xBF, 0x0E, 0xED, 0xB1, 0x13, 0xBA, 0x71, 0x19, 0xB4, 0xEC, 0x26, 0xC8, 0x89, 0xD0, 0xCD,
+ 0x67, 0xC3, 0x06, 0xFA, 0x2A, 0x64, 0xA2, 0x87, 0xCE, 0x63, 0x9D, 0xBC, 0x8C, 0xB7, 0x29, 0x9B,
+ 0x80, 0x77, 0x04, 0x2D, 0xCC, 0xBD, 0x9E, 0xBB, 0x27, 0x57, 0x8E, 0xFC, 0xF5, 0x83, 0x81, 0x1F,
+ 0x63, 0x67, 0xF2, 0xBB, 0xD9, 0x09, 0xB0, 0x26, 0x02, 0xD8, 0x0C, 0xF7, 0xF3, 0xAA, 0xDC, 0x14,
+ 0x9E, 0xC8, 0x8D, 0xA7, 0x72, 0x7E, 0xA7, 0xB2, 0x8C, 0xDF, 0xCE, 0x62, 0xB4, 0x81, 0x1D, 0x06,
+ 0x59, 0xAC, 0x66, 0x6F, 0xB0, 0xD7, 0xA8, 0x92, 0xDF, 0x04, 0xD6, 0x58, 0x00, 0x4D, 0xF3, 0x10,
+ 0x4B, 0xB3, 0xBF, 0xF3, 0xD1, 0xBC, 0x8B, 0xEF, 0xE0, 0xF3, 0x78, 0x1D, 0x6D, 0xE7, 0x49, 0xE8,
+ 0xEC, 0x19, 0x3C, 0x01, 0xDB, 0x42, 0x5C, 0xF7, 0xC0, 0x46, 0x51, 0x87, 0x11, 0x78, 0xF6, 0xAF,
+ 0xDB, 0xC3, 0xF4, 0xA3, 0xB7, 0x1E, 0x0F, 0x4C, 0xB5, 0xEF, 0x71, 0xE5, 0xEC, 0x1C, 0xFA, 0xFC,
+ 0x28, 0x9D, 0x37, 0xE5, 0x0F, 0xE8, 0xEB, 0xD2, 0xA7, 0xA6, 0xAD, 0x93, 0xA2, 0x08, 0x5B, 0xD9,
+ 0xD4, 0x39, 0x3E, 0xA8, 0x3C, 0xC6, 0x55, 0x55, 0x89, 0x29, 0x6A, 0x4C, 0x5C, 0x5C, 0x51, 0x71,
+ 0xE9, 0xBA, 0xA6, 0x8A, 0x73, 0x2C, 0x75, 0x45, 0xD1, 0x54, 0x53, 0xD7, 0x55, 0x0D, 0x97, 0xAE,
+ 0xDB, 0x9A, 0x2E, 0x43, 0xAA, 0x78, 0xC5, 0xD4, 0x18, 0x7E, 0x13, 0xF7, 0x9B, 0xE2, 0x8E, 0x98,
+ 0xF8, 0x66, 0xA8, 0xE2, 0x5C, 0x4D, 0x05, 0xB7, 0x8B, 0x28, 0x74, 0x55, 0x8D, 0x7E, 0xC1, 0xA5,
+ 0x88, 0x94, 0xE4, 0x25, 0x62, 0x82, 0x21, 0x8B, 0xD8, 0x09, 0x31, 0x9A, 0x0A, 0x57, 0x2D, 0x3D,
+ 0x46, 0x1A, 0xD2, 0x43, 0xDC, 0x8A, 0x86, 0x9C, 0xE1, 0x3E, 0x31, 0x0E, 0xA6, 0x23, 0x98, 0xAE,
+ 0x20, 0x1A, 0x4B, 0x17, 0x79, 0xE3, 0x9C, 0x74, 0x55, 0xE7, 0x51, 0x79, 0x08, 0xEB, 0x1F, 0xDF,
+ 0x10, 0x10, 0x97, 0x1E, 0x5D, 0xE2, 0xA3, 0xC2, 0xE5, 0xFF, 0xFD, 0x95, 0x8C, 0xE5, 0x18, 0x12,
+ 0xBB, 0xA6, 0x59, 0x86, 0x7C, 0x57, 0x24, 0x06, 0x81, 0x05, 0x7F, 0x22, 0x79, 0x71, 0xAA, 0x87,
+ 0x0E, 0xA8, 0x78, 0x19, 0xE2, 0xE0, 0x4B, 0x0B, 0xDF, 0x50, 0x18, 0xBA, 0x61, 0x38, 0xBA, 0xA1,
+ 0x29, 0xAA, 0x08, 0xAE, 0x69, 0x31, 0xF9, 0x5F, 0xE4, 0xD6, 0xD2, 0xF2, 0xD8, 0x35, 0x13, 0xB7,
+ 0x22, 0x79, 0x11, 0x5A, 0x33, 0x10, 0x56, 0x5E, 0x31, 0x81, 0x58, 0xE4, 0x48, 0x2B, 0xC1, 0x2E,
+ 0x4A, 0x96, 0x10, 0xA3, 0x05, 0x6F, 0x1B, 0xD8, 0x71, 0x83, 0x66, 0x68, 0x11, 0x76, 0x43, 0x60,
+ 0x37, 0xC8, 0x40, 0x30, 0x43, 0x00, 0xB3, 0x0D, 0x71, 0x2B, 0x10, 0x19, 0x9A, 0x91, 0xC7, 0x2E,
+ 0xD0, 0xE9, 0x22, 0x87, 0x11, 0x76, 0xA4, 0x65, 0x18, 0xCA, 0xD0, 0xB5, 0x3F, 0xEC, 0xB6, 0x67,
+ 0x02, 0x7B, 0x2C, 0xA6, 0xE9, 0xB6, 0x29, 0xB0, 0xA3, 0x50, 0x81, 0x0F, 0xD8, 0xA3, 0xAC, 0xC9,
+ 0x62, 0xD4, 0x4C, 0x43, 0x44, 0x98, 0xC7, 0x6E, 0x9B, 0x48, 0x14, 0xBE, 0xA6, 0xE1, 0x19, 0x46,
+ 0x3E, 0xB8, 0xA8, 0x27, 0x35, 0x26, 0x0A, 0x5B, 0x53, 0x6C, 0x5D, 0x22, 0x14, 0xA5, 0x24, 0xEA,
+ 0x8E, 0x2B, 0xBA, 0x78, 0x94, 0xC8, 0x34, 0xCC, 0x08, 0xBB, 0x5A, 0xC0, 0xAE, 0x6B, 0x91, 0xF4,
+ 0xE8, 0x3A, 0xB0, 0xE3, 0x0B, 0x19, 0xA6, 0x69, 0xC3, 0xDB, 0x31, 0x50, 0x0C, 0xBA, 0x48, 0x10,
+ 0x5F, 0x20, 0x55, 0xB8, 0x2F, 0x26, 0xEC, 0x71, 0x04, 0x33, 0x15, 0x80, 0x72, 0x4C, 0x45, 0xD6,
+ 0x30, 0x7C, 0x0C, 0xF1, 0x88, 0x57, 0x1E, 0x3B, 0x00, 0x47, 0x95, 0x6D, 0x18, 0x48, 0xCB, 0x34,
+ 0x3F, 0x07, 0x76, 0xC7, 0xB7, 0x04, 0x76, 0x55, 0x17, 0x71, 0xC6, 0xF0, 0x2E, 0xC1, 0xC4, 0x04,
+ 0x76, 0x21, 0xE5, 0x11, 0x76, 0x0B, 0xE0, 0x21, 0xEA, 0x86, 0x19, 0x8B, 0x19, 0xBA, 0x63, 0x99,
+ 0x02, 0x8D, 0x61, 0x99, 0xBE, 0x69, 0xEA, 0x31, 0x4D, 0x40, 0xD6, 0x85, 0xC4, 0xC5, 0x64, 0x6E,
+ 0x15, 0x47, 0xD4, 0x80, 0x2A, 0x4A, 0xC2, 0x86, 0x77, 0x0C, 0xC5, 0x89, 0x60, 0xBA, 0x65, 0x5A,
+ 0x91, 0x2C, 0x0E, 0x8F, 0xDD, 0x10, 0xD8, 0x2D, 0xCB, 0x81, 0xB7, 0x6B, 0xAA, 0x24, 0x4B, 0x0B,
+ 0xC0, 0x75, 0xE4, 0xC8, 0x12, 0xD8, 0xD1, 0x13, 0x91, 0xD8, 0x01, 0xCA, 0x35, 0x63, 0xB2, 0x86,
+ 0xE1, 0x63, 0x96, 0x60, 0x37, 0x45, 0x0E, 0x45, 0x7B, 0x32, 0x4D, 0xA4, 0x65, 0x59, 0x9F, 0x03,
+ 0xBB, 0x1B, 0x58, 0x84, 0x1B, 0x54, 0xC3, 0x70, 0x2D, 0x81, 0x1D, 0x02, 0xA5, 0x18, 0x40, 0x04,
+ 0x2C, 0x40, 0xAF, 0x01, 0x2C, 0xF2, 0x61, 0x59, 0xA2, 0x30, 0x75, 0xD3, 0x42, 0xCC, 0xBA, 0x67,
+ 0x23, 0x19, 0x14, 0xAD, 0x65, 0x05, 0xA6, 0x65, 0x00, 0x3B, 0x82, 0x1B, 0x12, 0xAF, 0x61, 0xC4,
+ 0x20, 0x37, 0xAE, 0x10, 0x0A, 0x55, 0x78, 0x8B, 0x36, 0x01, 0xEC, 0x86, 0xB8, 0xDD, 0x46, 0x58,
+ 0x79, 0x45, 0x82, 0x1F, 0x13, 0xA5, 0x28, 0x6B, 0x17, 0x17, 0x91, 0x10, 0x24, 0x42, 0x8C, 0x6E,
+ 0x4C, 0x31, 0x3C, 0x53, 0x23, 0x13, 0xBE, 0x88, 0x1B, 0xF2, 0x0E, 0xEC, 0x80, 0x84, 0x3E, 0x98,
+ 0x58, 0x6F, 0x66, 0xC5, 0x2C, 0xCB, 0xF4, 0xAC, 0x98, 0x11, 0x61, 0x37, 0x2C, 0xAE, 0x17, 0xB1,
+ 0xE3, 0x9B, 0x48, 0xBF, 0x88, 0x3D, 0xE2, 0x15, 0xF9, 0x7F, 0x7F, 0xD8, 0xBD, 0xD0, 0x06, 0x76,
+ 0x55, 0x33, 0x4C, 0xCF, 0x96, 0x65, 0x10, 0x81, 0xD1, 0x54, 0x59, 0x2D, 0x7A, 0x84, 0xDD, 0x46,
+ 0xC5, 0x8B, 0x17, 0x42, 0x98, 0x86, 0x6F, 0x23, 0x19, 0x94, 0xBF, 0x6D, 0x87, 0x96, 0x2D, 0x83,
+ 0x1B, 0x78, 0xA1, 0x79, 0xAA, 0xA6, 0x90, 0x8B, 0x98, 0x27, 0x9A, 0x1B, 0xE0, 0x99, 0x86, 0x6B,
+ 0x14, 0xB1, 0x9B, 0x36, 0xC2, 0x0E, 0x87, 0x1D, 0x11, 0x99, 0xC0, 0x8E, 0x3A, 0x23, 0xCB, 0xB6,
+ 0x3D, 0x78, 0xFB, 0x96, 0x46, 0x48, 0xCC, 0xB4, 0x11, 0x9B, 0x09, 0xF9, 0x13, 0xD2, 0x83, 0xDE,
+ 0xA7, 0x8D, 0x60, 0x36, 0xB0, 0x5B, 0xBE, 0x2D, 0x6E, 0x05, 0x22, 0xDB, 0xB0, 0xF3, 0xD8, 0x05,
+ 0x3A, 0x00, 0x16, 0xE9, 0xC7, 0x10, 0x04, 0x69, 0xD9, 0x76, 0x6C, 0xE8, 0xDA, 0x1F, 0x76, 0x3F,
+ 0xE1, 0x48, 0xEC, 0xA6, 0xE9, 0x3B, 0x08, 0xA6, 0x99, 0x31, 0x91, 0x6B, 0x90, 0xAB, 0xA1, 0x09,
+ 0x4A, 0x13, 0xC5, 0x68, 0x1A, 0x0E, 0xC0, 0xDB, 0x02, 0xBB, 0xAA, 0x5A, 0x46, 0xE0, 0xA0, 0x0E,
+ 0x91, 0x92, 0x63, 0x27, 0x6C, 0xDB, 0x84, 0x7C, 0x20, 0xB8, 0x6C, 0x13, 0x79, 0xEC, 0xBE, 0xA8,
+ 0x34, 0x4D, 0x78, 0x7B, 0x06, 0x3C, 0xD1, 0x60, 0x11, 0xCC, 0x74, 0x6C, 0xC7, 0x94, 0x97, 0x44,
+ 0x2C, 0xEB, 0x47, 0x16, 0x45, 0x84, 0x5D, 0x47, 0x9D, 0x81, 0x76, 0x1D, 0x1F, 0xDE, 0x01, 0x34,
+ 0x8F, 0x2C, 0x5B, 0x00, 0x87, 0xCE, 0xD0, 0x1C, 0xC3, 0x10, 0xD8, 0x1D, 0x04, 0x73, 0x62, 0x00,
+ 0x15, 0x38, 0xAA, 0x94, 0x6E, 0xF8, 0xD8, 0xE8, 0x8D, 0x15, 0xB0, 0xDB, 0xB8, 0x41, 0xAA, 0x18,
+ 0xDB, 0x46, 0x5A, 0x8E, 0xF3, 0x39, 0xB0, 0x07, 0x49, 0x97, 0x04, 0xDD, 0x9A, 0x56, 0xE0, 0x80,
+ 0x82, 0x35, 0x2B, 0xA6, 0xC7, 0x2C, 0x03, 0xB5, 0x2E, 0xAB, 0xC5, 0x80, 0xC8, 0xA1, 0xD6, 0x5C,
+ 0x47, 0x14, 0xA6, 0x69, 0x3B, 0x88, 0xD9, 0x0C, 0x5D, 0x24, 0x8A, 0xA2, 0x75, 0x9D, 0xA4, 0xED,
+ 0x58, 0xC0, 0x6E, 0x99, 0x28, 0x20, 0x60, 0xD7, 0x2C, 0x4B, 0x55, 0xCD, 0x58, 0x80, 0x5A, 0x36,
+ 0x35, 0xE1, 0xED, 0xA3, 0x8D, 0x0B, 0xA1, 0x75, 0x70, 0xBB, 0xEB, 0xB8, 0x25, 0xD8, 0x45, 0x1E,
+ 0xA3, 0x36, 0x80, 0xE8, 0xAD, 0x3C, 0x76, 0xDB, 0x75, 0x03, 0x54, 0x5B, 0xE8, 0xE8, 0x64, 0xC3,
+ 0x17, 0x71, 0xA3, 0xAD, 0xAB, 0xBA, 0x2B, 0xB0, 0x3B, 0xE4, 0x22, 0x98, 0xA3, 0x02, 0x54, 0xE8,
+ 0xAA, 0x52, 0xBA, 0xE1, 0xE3, 0x94, 0x60, 0x77, 0x70, 0x83, 0x25, 0xE2, 0x75, 0x1C, 0xA4, 0xE5,
+ 0xBA, 0xEA, 0xBF, 0xC7, 0x1E, 0xA6, 0x3C, 0x12, 0x9A, 0xDB, 0xB2, 0x43, 0xB7, 0x88, 0xDD, 0x44,
+ 0xAD, 0x9B, 0x52, 0x55, 0xA8, 0x02, 0xBB, 0xE9, 0xB9, 0xB6, 0x88, 0xD9, 0x71, 0x05, 0xF6, 0xB8,
+ 0x87, 0x64, 0x50, 0xFE, 0x9E, 0x9B, 0x72, 0x5C, 0x0B, 0x4A, 0x1C, 0xC1, 0x2D, 0x0B, 0xB9, 0xD7,
+ 0x6C, 0x91, 0xDB, 0x58, 0x68, 0x49, 0x84, 0xF0, 0x0E, 0x50, 0x6C, 0x02, 0xBB, 0xEB, 0x5A, 0x96,
+ 0xE7, 0x78, 0x96, 0xBC, 0x64, 0x0B, 0x97, 0xD8, 0x65, 0x51, 0x44, 0xD8, 0x41, 0x07, 0x26, 0x39,
+ 0x9E, 0x17, 0xAA, 0x31, 0x2B, 0x0E, 0xEC, 0x10, 0x34, 0x0B, 0x71, 0xAB, 0xB6, 0xC0, 0x8E, 0x92,
+ 0x14, 0xA3, 0x2D, 0x08, 0xE6, 0xAA, 0xAE, 0xEB, 0xC4, 0x0B, 0xD8, 0x3D, 0xCB, 0x55, 0xCC, 0x22,
+ 0x76, 0x17, 0x37, 0xE4, 0xB1, 0x23, 0x2D, 0xCF, 0x8B, 0x8C, 0x09, 0xF9, 0x7F, 0x7F, 0xD8, 0xE3,
+ 0xE9, 0x08, 0xBB, 0x6D, 0xC7, 0x45, 0x70, 0xDD, 0x06, 0x18, 0x60, 0x00, 0x76, 0x29, 0x91, 0x42,
+ 0x84, 0x6C, 0x81, 0xDD, 0x16, 0xF0, 0x3D, 0x4D, 0x73, 0xAC, 0x84, 0x8F, 0x64, 0x20, 0x56, 0x9E,
+ 0x97, 0x76, 0x3D, 0x5B, 0x93, 0x90, 0x2D, 0xC1, 0x34, 0x9A, 0x2D, 0xDA, 0x84, 0x1A, 0x17, 0x4D,
+ 0x42, 0x17, 0xDE, 0x01, 0xDA, 0x38, 0x14, 0x3F, 0xEA, 0xD3, 0xB6, 0x7D, 0x37, 0x8F, 0xDD, 0x28,
+ 0x60, 0xB7, 0x25, 0x76, 0x44, 0x6F, 0x03, 0xBB, 0x13, 0x61, 0x8F, 0xC3, 0x3B, 0xE1, 0x1A, 0x24,
+ 0xCB, 0x16, 0xC0, 0x05, 0x76, 0x4F, 0x60, 0xF7, 0xC8, 0x43, 0x30, 0x0F, 0xD8, 0xDD, 0x84, 0xA7,
+ 0xDA, 0x22, 0x06, 0xF8, 0x78, 0x79, 0xEC, 0x02, 0x9D, 0x8B, 0x1C, 0xDA, 0x82, 0x4B, 0x5C, 0xD7,
+ 0x73, 0x0B, 0xD8, 0xD5, 0x7F, 0x89, 0x3D, 0x51, 0xE6, 0x0B, 0xEC, 0x86, 0xED, 0x24, 0x7C, 0xF0,
+ 0x7A, 0x1E, 0x3B, 0x6A, 0xDD, 0x92, 0x6A, 0x52, 0x62, 0xB7, 0x7C, 0xCF, 0xB1, 0xF1, 0x72, 0x81,
+ 0xDD, 0xB5, 0x92, 0x81, 0x07, 0x34, 0x8E, 0xEB, 0x7B, 0x65, 0x1E, 0xF2, 0x67, 0x0A, 0xEC, 0x36,
+ 0x78, 0xC7, 0xD4, 0x1D, 0xD1, 0x26, 0xD4, 0x84, 0x2D, 0x11, 0x6A, 0x8E, 0x1D, 0xA2, 0xD8, 0x04,
+ 0x76, 0x04, 0x73, 0x02, 0xCF, 0xB7, 0xE5, 0x25, 0x5B, 0xB8, 0xC4, 0x2E, 0x8B, 0x02, 0x42, 0xEC,
+ 0x40, 0x41, 0x41, 0xAA, 0xC8, 0xF5, 0xFD, 0x04, 0xBC, 0x93, 0x9E, 0x41, 0xB2, 0x6C, 0x1D, 0x4D,
+ 0x85, 0xBE, 0x04, 0xF7, 0x59, 0x02, 0xBB, 0x8F, 0x60, 0xBE, 0x0A, 0x50, 0x49, 0x5F, 0x93, 0x2D,
+ 0x9B, 0x7C, 0x60, 0xB7, 0x8A, 0xD8, 0x51, 0xD9, 0x8E, 0x23, 0xB0, 0x7B, 0x9E, 0xEF, 0xF9, 0xBE,
+ 0xFF, 0x39, 0xB0, 0x27, 0xCB, 0x03, 0x12, 0x46, 0x94, 0xE3, 0x26, 0x03, 0x55, 0xBC, 0xAB, 0xA6,
+ 0xEA, 0x00, 0x11, 0xCC, 0x27, 0xA1, 0xC7, 0x50, 0xD1, 0x68, 0xAD, 0x81, 0xEF, 0x3A, 0x02, 0xBE,
+ 0x8F, 0x98, 0xED, 0x54, 0x80, 0x44, 0x81, 0x3D, 0xF0, 0xCB, 0x3D, 0xDF, 0x01, 0x76, 0x04, 0x77,
+ 0x04, 0xD3, 0xE8, 0x2E, 0xD2, 0xB6, 0xD5, 0xA4, 0x63, 0x09, 0x84, 0xF0, 0x8B, 0x83, 0xDF, 0x80,
+ 0xDD, 0xF1, 0x7D, 0xC7, 0x09, 0xFC, 0xC0, 0x91, 0x97, 0xAC, 0x6D, 0x91, 0x47, 0xA7, 0x14, 0x3B,
+ 0xE4, 0x95, 0xBC, 0x20, 0x48, 0x02, 0x6E, 0xCA, 0x37, 0x09, 0xF1, 0x3B, 0x88, 0x5B, 0x13, 0xD8,
+ 0x03, 0x81, 0xDD, 0xA7, 0x00, 0xC1, 0x02, 0x0D, 0xA0, 0x52, 0x81, 0xE6, 0x48, 0xEC, 0x81, 0xE3,
+ 0x97, 0x60, 0xF7, 0x71, 0x83, 0xC4, 0xEE, 0xFB, 0x48, 0x2B, 0x08, 0x22, 0x43, 0x4A, 0x8B, 0xEC,
+ 0xC6, 0xE1, 0xAF, 0x54, 0x36, 0x04, 0x76, 0xDD, 0x74, 0xDC, 0x94, 0xC4, 0xEE, 0x02, 0xBB, 0x0B,
+ 0xEC, 0x42, 0x21, 0x43, 0x76, 0xE5, 0x79, 0x9A, 0x76, 0x18, 0xB8, 0xAE, 0x80, 0x1F, 0x68, 0xBA,
+ 0xE7, 0xA4, 0x43, 0x24, 0x03, 0xB1, 0x0A, 0x83, 0xAC, 0x1F, 0xB8, 0x30, 0xAF, 0x11, 0x1C, 0x90,
+ 0x1C, 0x60, 0x77, 0x91, 0x5B, 0x60, 0x07, 0xD1, 0x02, 0xBB, 0xEB, 0x24, 0xC4, 0x52, 0x7A, 0x34,
+ 0xD8, 0x20, 0x10, 0xFB, 0x22, 0x84, 0x7B, 0x63, 0x97, 0x62, 0x80, 0xE8, 0x5D, 0x81, 0x1D, 0x92,
+ 0xEF, 0x85, 0x61, 0x4A, 0x53, 0xDD, 0xB4, 0xC4, 0x0E, 0xDE, 0x73, 0x75, 0x0D, 0x2F, 0x13, 0xD2,
+ 0x23, 0x7A, 0x46, 0xA1, 0x2B, 0xB0, 0x07, 0x81, 0x9F, 0x0E, 0x35, 0xD9, 0xB2, 0xE1, 0x13, 0xC4,
+ 0xEC, 0x22, 0xF6, 0x00, 0x37, 0xB8, 0x11, 0x76, 0xA4, 0x15, 0x86, 0x9F, 0x03, 0x7B, 0xBA, 0x22,
+ 0x2E, 0xB1, 0xBB, 0x1E, 0xE2, 0x04, 0xB1, 0xBB, 0xB0, 0x44, 0x5D, 0x07, 0x12, 0xEF, 0x08, 0xEC,
+ 0x76, 0x84, 0x3D, 0x1E, 0x78, 0x88, 0xD9, 0xF1, 0x43, 0x5D, 0xF7, 0x9D, 0x4C, 0x3C, 0x80, 0x74,
+ 0x7A, 0x7E, 0x3C, 0xAC, 0x08, 0x42, 0x89, 0xDD, 0xC1, 0x1D, 0x60, 0x1A, 0xC3, 0x13, 0xD8, 0xB5,
+ 0x94, 0x0B, 0x15, 0x03, 0x86, 0xF7, 0x9C, 0x24, 0xB8, 0xB0, 0x80, 0x3D, 0x1E, 0xC4, 0x5D, 0x79,
+ 0xC9, 0xDA, 0x96, 0xED, 0x52, 0x62, 0x87, 0x10, 0x7B, 0x50, 0xCE, 0x1E, 0xB0, 0xFB, 0xF1, 0x78,
+ 0x1A, 0xDE, 0x19, 0x58, 0x5B, 0xB2, 0x6C, 0x01, 0x1C, 0xB6, 0x42, 0x84, 0x3D, 0xA4, 0x38, 0x82,
+ 0x85, 0xC0, 0x1E, 0x64, 0x42, 0xDD, 0x15, 0x31, 0x00, 0x7B, 0x98, 0xC7, 0xAE, 0x15, 0xB0, 0x0B,
+ 0x1D, 0x12, 0x04, 0x61, 0x10, 0x8F, 0xC7, 0xB5, 0xA1, 0x6B, 0x7F, 0xD8, 0x33, 0x95, 0x79, 0xEC,
+ 0x7E, 0x26, 0x2E, 0x3A, 0x52, 0x1E, 0xB0, 0x7B, 0x12, 0xBB, 0x34, 0x11, 0x44, 0xF3, 0xF1, 0x1C,
+ 0xF1, 0xBC, 0xA1, 0x80, 0x0F, 0xEC, 0x81, 0x5B, 0x96, 0x40, 0x81, 0xA3, 0xF9, 0x26, 0xC2, 0xCA,
+ 0x20, 0xF4, 0x60, 0xB8, 0x02, 0xB2, 0xEB, 0x4A, 0xEC, 0x9E, 0xAE, 0xBB, 0x5A, 0xDA, 0x83, 0x92,
+ 0x11, 0xD8, 0xDD, 0x14, 0xF8, 0x0D, 0xD8, 0x51, 0x9F, 0x9E, 0x97, 0x08, 0x13, 0x25, 0xD8, 0x45,
+ 0x1E, 0x3D, 0x29, 0x06, 0x79, 0xEC, 0x90, 0x57, 0x42, 0x8E, 0x33, 0x48, 0xAF, 0x2C, 0xB4, 0x28,
+ 0x80, 0x2F, 0xE2, 0xD6, 0x05, 0xF6, 0xB8, 0xE3, 0x08, 0xEC, 0x09, 0x04, 0x8B, 0x6B, 0xA8, 0xD0,
+ 0xB2, 0x38, 0x4C, 0x4B, 0x64, 0x0C, 0xA5, 0x11, 0xC6, 0x9C, 0x22, 0xF6, 0x10, 0x37, 0x78, 0x22,
+ 0xDE, 0x30, 0x8C, 0x87, 0x89, 0x44, 0x42, 0xFF, 0xF7, 0xD8, 0xCB, 0xAA, 0x13, 0xE8, 0x39, 0x18,
+ 0x96, 0xE7, 0x97, 0x25, 0x8A, 0xD8, 0x5D, 0x74, 0x6C, 0x5C, 0x89, 0x1D, 0xC9, 0x03, 0x7B, 0x22,
+ 0xEE, 0x7B, 0xA1, 0xEF, 0x06, 0x71, 0xDD, 0x08, 0xDC, 0xF2, 0x24, 0x92, 0x41, 0x93, 0x4A, 0xC4,
+ 0xAB, 0xC3, 0xB8, 0x67, 0xD8, 0xA8, 0x6E, 0x04, 0x02, 0x2D, 0x1B, 0xBE, 0x2F, 0xB0, 0x67, 0x80,
+ 0xDD, 0x45, 0xD7, 0xD8, 0x77, 0x85, 0x1E, 0x30, 0x54, 0xC3, 0x8B, 0xC7, 0x3D, 0x3F, 0x19, 0x26,
+ 0x3C, 0x79, 0xC9, 0xDA, 0x1E, 0xC2, 0x8E, 0x06, 0xEC, 0xC3, 0x30, 0x11, 0xD8, 0x91, 0xE3, 0x32,
+ 0x54, 0x75, 0x39, 0x2C, 0xCD, 0x40, 0xC8, 0x95, 0x6F, 0xE8, 0x78, 0x59, 0x09, 0x07, 0x5D, 0xCD,
+ 0x38, 0x25, 0x10, 0x2C, 0xA1, 0xC7, 0xE3, 0x61, 0x36, 0x91, 0xC7, 0x9E, 0xF0, 0xE2, 0x25, 0xD8,
+ 0xE3, 0xB8, 0xC1, 0x8F, 0xB0, 0x27, 0x24, 0x76, 0x71, 0xC9, 0xEE, 0x82, 0xBE, 0x3F, 0xEC, 0xFF,
+ 0x27, 0x00, 0x00, 0xFF, 0xFF, 0xA4, 0xB4, 0xB8, 0xA4}
diff --git a/vendor/github.com/jung-kurt/gofpdf/layer.go b/vendor/github.com/jung-kurt/gofpdf/layer.go
new file mode 100644
index 0000000..bca364f
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/layer.go
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2014 Kurt Jung (Gmail: kurt.w.jung)
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package gofpdf
+
+// Routines in this file are translated from
+// http://www.fpdf.org/en/script/script97.php
+
+type layerType struct {
+ name string
+ visible bool
+ objNum int // object number
+}
+
+type layerRecType struct {
+ list []layerType
+ currentLayer int
+ openLayerPane bool
+}
+
+func (f *Fpdf) layerInit() {
+ f.layer.list = make([]layerType, 0)
+ f.layer.currentLayer = -1
+ f.layer.openLayerPane = false
+}
+
+// AddLayer defines a layer that can be shown or hidden when the document is
+// displayed. name specifies the layer name that the document reader will
+// display in the layer list. visible specifies whether the layer will be
+// initially visible. The return value is an integer ID that is used in a call
+// to BeginLayer().
+func (f *Fpdf) AddLayer(name string, visible bool) (layerID int) {
+ layerID = len(f.layer.list)
+ f.layer.list = append(f.layer.list, layerType{name: name, visible: visible})
+ return
+}
+
+// BeginLayer is called to begin adding content to the specified layer. All
+// content added to the page between a call to BeginLayer and a call to
+// EndLayer is added to the layer specified by id. See AddLayer for more
+// details.
+func (f *Fpdf) BeginLayer(id int) {
+ f.EndLayer()
+ if id >= 0 && id < len(f.layer.list) {
+ f.outf("/OC /OC%d BDC", id)
+ f.layer.currentLayer = id
+ }
+}
+
+// EndLayer is called to stop adding content to the currently active layer. See
+// BeginLayer for more details.
+func (f *Fpdf) EndLayer() {
+ if f.layer.currentLayer >= 0 {
+ f.out("EMC")
+ f.layer.currentLayer = -1
+ }
+}
+
+// OpenLayerPane advises the document reader to open the layer pane when the
+// document is initially displayed.
+func (f *Fpdf) OpenLayerPane() {
+ f.layer.openLayerPane = true
+}
+
+func (f *Fpdf) layerEndDoc() {
+ if len(f.layer.list) > 0 {
+ if f.pdfVersion < "1.5" {
+ f.pdfVersion = "1.5"
+ }
+ }
+}
+
+func (f *Fpdf) layerPutLayers() {
+ for j, l := range f.layer.list {
+ f.newobj()
+ f.layer.list[j].objNum = f.n
+ f.outf("<</Type /OCG /Name %s>>", f.textstring(utf8toutf16(l.name)))
+ f.out("endobj")
+ }
+}
+
+func (f *Fpdf) layerPutResourceDict() {
+ if len(f.layer.list) > 0 {
+ f.out("/Properties <<")
+ for j, layer := range f.layer.list {
+ f.outf("/OC%d %d 0 R", j, layer.objNum)
+ }
+ f.out(">>")
+ }
+
+}
+
+func (f *Fpdf) layerPutCatalog() {
+ if len(f.layer.list) > 0 {
+ onStr := ""
+ offStr := ""
+ for _, layer := range f.layer.list {
+ onStr += sprintf("%d 0 R ", layer.objNum)
+ if !layer.visible {
+ offStr += sprintf("%d 0 R ", layer.objNum)
+ }
+ }
+ f.outf("/OCProperties <</OCGs [%s] /D <</OFF [%s] /Order [%s]>>>>", onStr, offStr, onStr)
+ if f.layer.openLayerPane {
+ f.out("/PageMode /UseOC")
+ }
+ }
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/license.txt b/vendor/github.com/jung-kurt/gofpdf/license.txt
new file mode 100644
index 0000000..eb1abac
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/license.txt
@@ -0,0 +1,23 @@
+MIT License
+
+Copyright (c) 2013-2016 Kurt Jung (Gmail: kurt.w.jung)
+
+Portions copyright by the contributors acknowledged in the documentation.
+
+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/vendor/github.com/jung-kurt/gofpdf/list/list.go b/vendor/github.com/jung-kurt/gofpdf/list/list.go
new file mode 100644
index 0000000..8099404
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/list/list.go
@@ -0,0 +1,59 @@
+package main
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+func matchTail(str, tailStr string) (match bool, headStr string) {
+ sln := len(str)
+ ln := len(tailStr)
+ if sln > ln {
+ match = str[sln-ln:] == tailStr
+ if match {
+ headStr = str[:sln-ln]
+ }
+ }
+ return
+}
+
+func matchHead(str, headStr string) (match bool, tailStr string) {
+ ln := len(headStr)
+ if len(str) > ln {
+ match = str[:ln] == headStr
+ if match {
+ tailStr = str[ln:]
+ }
+ }
+ return
+}
+
+func main() {
+ var err error
+ var ok bool
+ var showStr, name string
+ err = filepath.Walk("pdf/reference", func(path string, info os.FileInfo, err error) error {
+ if info.Mode().IsRegular() {
+ name = filepath.Base(path)
+ ok, name = matchTail(name, ".pdf")
+ if ok {
+ name = strings.Replace(name, "_", " ", -1)
+ ok, showStr = matchHead(name, "Fpdf ")
+ if ok {
+ fmt.Printf("[%s](%s)\n", showStr, path)
+ } else {
+ ok, showStr = matchHead(name, "contrib ")
+ if ok {
+ fmt.Printf("[%s](%s)\n", showStr, path)
+ }
+ }
+ }
+ }
+ return nil
+ })
+ if err != nil {
+ fmt.Println(err)
+ }
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/makefont/doc.go b/vendor/github.com/jung-kurt/gofpdf/makefont/doc.go
new file mode 100644
index 0000000..306ead2
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/makefont/doc.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2013 Kurt Jung
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+Command makefont generates a font definition file.
+
+This utility is used to generate a font definition file that allows TrueType
+and Type1 fonts to be used in PDFs produced with the fpdf package.
+*/
+package main
diff --git a/vendor/github.com/jung-kurt/gofpdf/makefont/makefont b/vendor/github.com/jung-kurt/gofpdf/makefont/makefont
new file mode 100755
index 0000000..2e49bc1
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/makefont/makefont
Binary files differ
diff --git a/vendor/github.com/jung-kurt/gofpdf/makefont/makefont.go b/vendor/github.com/jung-kurt/gofpdf/makefont/makefont.go
new file mode 100644
index 0000000..eb2993e
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/makefont/makefont.go
@@ -0,0 +1,71 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "github.com/jung-kurt/gofpdf"
+ "os"
+)
+
+func errPrintf(fmtStr string, args ...interface{}) {
+ fmt.Fprintf(os.Stderr, fmtStr, args...)
+}
+
+func showHelp() {
+ errPrintf("Usage: %s [options] font_file [font_file...]\n", os.Args[0])
+ flag.PrintDefaults()
+ fmt.Fprintln(os.Stderr, "\n"+
+ "font_file is the name of the TrueType file (extension .ttf), OpenType file\n"+
+ "(extension .otf) or binary Type1 file (extension .pfb) from which to\n"+
+ "generate a definition file. If an OpenType file is specified, it must be one\n"+
+ "that is based on TrueType outlines, not PostScript outlines; this cannot be\n"+
+ "determined from the file extension alone. If a Type1 file is specified, a\n"+
+ "metric file with the same pathname except with the extension .afm must be\n"+
+ "present.")
+ errPrintf("\nExample: %s --embed --enc=../font/cp1252.map --dst=../font calligra.ttf /opt/font/symbol.pfb\n", os.Args[0])
+}
+
+func tutorialSummary(f *gofpdf.Fpdf, fileStr string) {
+ if f.Ok() {
+ fl, err := os.Create(fileStr)
+ defer fl.Close()
+ if err == nil {
+ f.Output(fl)
+ } else {
+ f.SetError(err)
+ }
+ }
+ if f.Ok() {
+ fmt.Printf("Successfully generated %s\n", fileStr)
+ } else {
+ errPrintf("%s\n", f.Error())
+ }
+}
+
+func main() {
+ var dstDirStr, encodingFileStr string
+ var err error
+ var help, embed bool
+ flag.StringVar(&dstDirStr, "dst", ".", "directory for output files (*.z, *.json)")
+ flag.StringVar(&encodingFileStr, "enc", "cp1252.map", "code page file")
+ flag.BoolVar(&embed, "embed", false, "embed font into PDF")
+ flag.BoolVar(&help, "help", false, "command line usage")
+ flag.Parse()
+ if help {
+ showHelp()
+ } else {
+ args := flag.Args()
+ if len(args) > 0 {
+ for _, fileStr := range args {
+ err = gofpdf.MakeFont(fileStr, encodingFileStr, dstDirStr, os.Stderr, embed)
+ if err != nil {
+ errPrintf("%s\n", err)
+ }
+ // errPrintf("Font file [%s], Encoding file [%s], Embed [%v]\n", fileStr, encodingFileStr, embed)
+ }
+ } else {
+ errPrintf("At least one Type1 or TrueType font must be specified\n")
+ showHelp()
+ }
+ }
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/png.go b/vendor/github.com/jung-kurt/gofpdf/png.go
new file mode 100644
index 0000000..854b003
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/png.go
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2013-2016 Kurt Jung (Gmail: kurt.w.jung)
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package gofpdf
+
+import (
+ "bytes"
+ "fmt"
+ "strings"
+)
+
+func (f *Fpdf) pngColorSpace(ct byte) (colspace string, colorVal int) {
+ colorVal = 1
+ switch ct {
+ case 0, 4:
+ colspace = "DeviceGray"
+ case 2, 6:
+ colspace = "DeviceRGB"
+ colorVal = 3
+ case 3:
+ colspace = "Indexed"
+ default:
+ f.err = fmt.Errorf("unknown color type in PNG buffer: %d", ct)
+ }
+ return
+}
+
+func (f *Fpdf) parsepngstream(buf *bytes.Buffer, readdpi bool) (info *ImageInfoType) {
+ info = f.newImageInfo()
+ // Check signature
+ if string(buf.Next(8)) != "\x89PNG\x0d\x0a\x1a\x0a" {
+ f.err = fmt.Errorf("not a PNG buffer")
+ return
+ }
+ // Read header chunk
+ _ = buf.Next(4)
+ if string(buf.Next(4)) != "IHDR" {
+ f.err = fmt.Errorf("incorrect PNG buffer")
+ return
+ }
+ w := f.readBeInt32(buf)
+ h := f.readBeInt32(buf)
+ bpc := f.readByte(buf)
+ if bpc > 8 {
+ f.err = fmt.Errorf("16-bit depth not supported in PNG file")
+ }
+ ct := f.readByte(buf)
+ var colspace string
+ var colorVal int
+ colspace, colorVal = f.pngColorSpace(ct)
+ if f.err != nil {
+ return
+ }
+ if f.readByte(buf) != 0 {
+ f.err = fmt.Errorf("'unknown compression method in PNG buffer")
+ return
+ }
+ if f.readByte(buf) != 0 {
+ f.err = fmt.Errorf("'unknown filter method in PNG buffer")
+ return
+ }
+ if f.readByte(buf) != 0 {
+ f.err = fmt.Errorf("interlacing not supported in PNG buffer")
+ return
+ }
+ _ = buf.Next(4)
+ dp := sprintf("/Predictor 15 /Colors %d /BitsPerComponent %d /Columns %d", colorVal, bpc, w)
+ // Scan chunks looking for palette, transparency and image data
+ pal := make([]byte, 0, 32)
+ var trns []int
+ data := make([]byte, 0, 32)
+ loop := true
+ for loop {
+ n := int(f.readBeInt32(buf))
+ // dbg("Loop [%d]", n)
+ switch string(buf.Next(4)) {
+ case "PLTE":
+ // dbg("PLTE")
+ // Read palette
+ pal = buf.Next(n)
+ _ = buf.Next(4)
+ case "tRNS":
+ // dbg("tRNS")
+ // Read transparency info
+ t := buf.Next(n)
+ if ct == 0 {
+ trns = []int{int(t[1])} // ord(substr($t,1,1)));
+ } else if ct == 2 {
+ trns = []int{int(t[1]), int(t[3]), int(t[5])} // array(ord(substr($t,1,1)), ord(substr($t,3,1)), ord(substr($t,5,1)));
+ } else {
+ pos := strings.Index(string(t), "\x00")
+ if pos >= 0 {
+ trns = []int{pos} // array($pos);
+ }
+ }
+ _ = buf.Next(4)
+ case "IDAT":
+ // dbg("IDAT")
+ // Read image data block
+ data = append(data, buf.Next(n)...)
+ _ = buf.Next(4)
+ case "IEND":
+ // dbg("IEND")
+ loop = false
+ case "pHYs":
+ // dbg("pHYs")
+ // png files theoretically support different x/y dpi
+ // but we ignore files like this
+ // but if they're the same then we can stamp our info
+ // object with it
+ x := int(f.readBeInt32(buf))
+ y := int(f.readBeInt32(buf))
+ units := buf.Next(1)[0]
+ // fmt.Printf("got a pHYs block, x=%d, y=%d, u=%d, readdpi=%t\n",
+ // x, y, int(units), readdpi)
+ // only modify the info block if the user wants us to
+ if x == y && readdpi {
+ switch units {
+ // if units is 1 then measurement is px/meter
+ case 1:
+ info.dpi = float64(x) / 39.3701 // inches per meter
+ default:
+ info.dpi = float64(x)
+ }
+ }
+ _ = buf.Next(4)
+ default:
+ // dbg("default")
+ _ = buf.Next(n + 4)
+ }
+ if loop {
+ loop = n > 0
+ }
+ }
+ if colspace == "Indexed" && len(pal) == 0 {
+ f.err = fmt.Errorf("missing palette in PNG buffer")
+ }
+ info.w = float64(w)
+ info.h = float64(h)
+ info.cs = colspace
+ info.bpc = int(bpc)
+ info.f = "FlateDecode"
+ info.dp = dp
+ info.pal = pal
+ info.trns = trns
+ // dbg("ct [%d]", ct)
+ if ct >= 4 {
+ // Separate alpha and color channels
+ var err error
+ data, err = sliceUncompress(data)
+ if err != nil {
+ f.err = err
+ return
+ }
+ var color, alpha bytes.Buffer
+ if ct == 4 {
+ // Gray image
+ width := int(w)
+ height := int(h)
+ length := 2 * width
+ var pos, elPos int
+ for i := 0; i < height; i++ {
+ pos = (1 + length) * i
+ color.WriteByte(data[pos])
+ alpha.WriteByte(data[pos])
+ elPos = pos + 1
+ for k := 0; k < width; k++ {
+ color.WriteByte(data[elPos])
+ alpha.WriteByte(data[elPos+1])
+ elPos += 2
+ }
+ }
+ } else {
+ // RGB image
+ width := int(w)
+ height := int(h)
+ length := 4 * width
+ var pos, elPos int
+ for i := 0; i < height; i++ {
+ pos = (1 + length) * i
+ color.WriteByte(data[pos])
+ alpha.WriteByte(data[pos])
+ elPos = pos + 1
+ for k := 0; k < width; k++ {
+ color.Write(data[elPos : elPos+3])
+ alpha.WriteByte(data[elPos+3])
+ elPos += 4
+ }
+ }
+ }
+ data = sliceCompress(color.Bytes())
+ info.smask = sliceCompress(alpha.Bytes())
+ if f.pdfVersion < "1.4" {
+ f.pdfVersion = "1.4"
+ }
+ }
+ info.data = data
+ return
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/protect.go b/vendor/github.com/jung-kurt/gofpdf/protect.go
new file mode 100644
index 0000000..e934c2b
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/protect.go
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2013-2014 Kurt Jung (Gmail: kurt.w.jung)
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+// PDF protection is adapted from the work of Klemen VODOPIVEC for the fpdf
+// product.
+
+package gofpdf
+
+import (
+ "crypto/md5"
+ "crypto/rc4"
+ "encoding/binary"
+ "math/rand"
+)
+
+// Advisory bitflag constants that control document activities
+const (
+ CnProtectPrint = 4
+ CnProtectModify = 8
+ CnProtectCopy = 16
+ CnProtectAnnotForms = 32
+)
+
+type protectType struct {
+ encrypted bool
+ uValue []byte
+ oValue []byte
+ pValue int
+ padding []byte
+ encryptionKey []byte
+ objNum int
+ rc4cipher *rc4.Cipher
+ rc4n uint32 // Object number associated with rc4 cipher
+}
+
+func (p *protectType) rc4(n uint32, buf *[]byte) {
+ if p.rc4cipher == nil || p.rc4n != n {
+ p.rc4cipher, _ = rc4.NewCipher(p.objectKey(n))
+ p.rc4n = n
+ }
+ p.rc4cipher.XORKeyStream(*buf, *buf)
+}
+
+func (p *protectType) objectKey(n uint32) []byte {
+ var nbuf, b []byte
+ nbuf = make([]byte, 8, 8)
+ binary.LittleEndian.PutUint32(nbuf, n)
+ b = append(b, p.encryptionKey...)
+ b = append(b, nbuf[0], nbuf[1], nbuf[2], 0, 0)
+ s := md5.Sum(b)
+ return s[0:10]
+}
+
+func oValueGen(userPass, ownerPass []byte) (v []byte) {
+ var c *rc4.Cipher
+ tmp := md5.Sum(ownerPass)
+ c, _ = rc4.NewCipher(tmp[0:5])
+ cap := len(userPass)
+ v = make([]byte, cap, cap)
+ c.XORKeyStream(v, userPass)
+ return
+}
+
+func (p *protectType) uValueGen() (v []byte) {
+ var c *rc4.Cipher
+ c, _ = rc4.NewCipher(p.encryptionKey)
+ cap := len(p.padding)
+ v = make([]byte, cap, cap)
+ c.XORKeyStream(v, p.padding)
+ return
+}
+
+func (p *protectType) setProtection(privFlag byte, userPassStr, ownerPassStr string) {
+ privFlag = 192 | (privFlag & (CnProtectCopy | CnProtectModify | CnProtectPrint | CnProtectAnnotForms))
+ p.padding = []byte{
+ 0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41,
+ 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08,
+ 0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80,
+ 0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A,
+ }
+ userPass := []byte(userPassStr)
+ var ownerPass []byte
+ if ownerPassStr == "" {
+ ownerPass = make([]byte, 8, 8)
+ binary.LittleEndian.PutUint64(ownerPass, uint64(rand.Int63()))
+ } else {
+ ownerPass = []byte(ownerPassStr)
+ }
+ userPass = append(userPass, p.padding...)[0:32]
+ ownerPass = append(ownerPass, p.padding...)[0:32]
+ p.encrypted = true
+ p.oValue = oValueGen(userPass, ownerPass)
+ var buf []byte
+ buf = append(buf, userPass...)
+ buf = append(buf, p.oValue...)
+ buf = append(buf, privFlag, 0xff, 0xff, 0xff)
+ sum := md5.Sum(buf)
+ p.encryptionKey = sum[0:5]
+ p.uValue = p.uValueGen()
+ p.pValue = -(int(privFlag^255) + 1)
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/svgbasic.go b/vendor/github.com/jung-kurt/gofpdf/svgbasic.go
new file mode 100644
index 0000000..cb8e91e
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/svgbasic.go
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2014 Kurt Jung (Gmail: kurt.w.jung)
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package gofpdf
+
+import (
+ "encoding/xml"
+ "fmt"
+ "io/ioutil"
+ "strconv"
+ "strings"
+)
+
+var pathCmdSub *strings.Replacer
+
+func init() {
+ // Handle permitted constructions like "100L200,230"
+ pathCmdSub = strings.NewReplacer(",", " ",
+ "L", " L ", "l", " l ",
+ "C", " C ", "c", " c ",
+ "M", " M ", "m", " m ")
+}
+
+// SVGBasicSegmentType describes a single curve or position segment
+type SVGBasicSegmentType struct {
+ Cmd byte // See http://www.w3.org/TR/SVG/paths.html for path command structure
+ Arg [6]float64
+}
+
+func absolutizePath(segs []SVGBasicSegmentType) {
+ var x, y float64
+ var segPtr *SVGBasicSegmentType
+ adjust := func(pos int, adjX, adjY float64) {
+ segPtr.Arg[pos] += adjX
+ segPtr.Arg[pos+1] += adjY
+ }
+ for j, seg := range segs {
+ segPtr = &segs[j]
+ if j == 0 && seg.Cmd == 'm' {
+ segPtr.Cmd = 'M'
+ }
+ switch segPtr.Cmd {
+ case 'M':
+ x = seg.Arg[0]
+ y = seg.Arg[1]
+ case 'm':
+ adjust(0, x, y)
+ segPtr.Cmd = 'M'
+ x = segPtr.Arg[0]
+ y = segPtr.Arg[1]
+ case 'L':
+ x = seg.Arg[0]
+ y = seg.Arg[1]
+ case 'l':
+ adjust(0, x, y)
+ segPtr.Cmd = 'L'
+ x = segPtr.Arg[0]
+ y = segPtr.Arg[1]
+ case 'C':
+ x = seg.Arg[4]
+ y = seg.Arg[5]
+ case 'c':
+ adjust(0, x, y)
+ adjust(2, x, y)
+ adjust(4, x, y)
+ segPtr.Cmd = 'C'
+ x = segPtr.Arg[4]
+ y = segPtr.Arg[5]
+ }
+ }
+}
+
+func pathParse(pathStr string) (segs []SVGBasicSegmentType, err error) {
+ var seg SVGBasicSegmentType
+ var j, argJ, argCount, prevArgCount int
+ setup := func(n int) {
+ // It is not strictly necessary to clear arguments, but result may be clearer
+ // to caller
+ for j := 0; j < len(seg.Arg); j++ {
+ seg.Arg[j] = 0.0
+ }
+ argJ = 0
+ argCount = n
+ prevArgCount = n
+ }
+ var str string
+ var c byte
+ pathStr = pathCmdSub.Replace(pathStr)
+ strList := strings.Fields(pathStr)
+ count := len(strList)
+ for j = 0; j < count && err == nil; j++ {
+ str = strList[j]
+ if argCount == 0 { // Look for path command or argument continuation
+ c = str[0]
+ if c == '-' || (c >= '0' && c <= '9') { // More arguments
+ if j > 0 {
+ setup(prevArgCount)
+ // Repeat previous action
+ if seg.Cmd == 'M' {
+ seg.Cmd = 'L'
+ } else if seg.Cmd == 'm' {
+ seg.Cmd = 'l'
+ }
+ } else {
+ err = fmt.Errorf("expecting SVG path command at first position, got %s", str)
+ }
+ }
+ }
+ if err == nil {
+ if argCount == 0 {
+ seg.Cmd = str[0]
+ switch seg.Cmd {
+ case 'M', 'm': // Absolute/relative moveto: x, y
+ setup(2)
+ case 'C', 'c': // Absolute/relative Bézier curve: cx0, cy0, cx1, cy1, x1, y1
+ setup(6)
+ case 'L', 'l': // Absolute/relative lineto: x, y
+ setup(2)
+ default:
+ err = fmt.Errorf("expecting SVG path command at position %d, got %s", j, str)
+ }
+ } else {
+ seg.Arg[argJ], err = strconv.ParseFloat(str, 64)
+ if err == nil {
+ argJ++
+ argCount--
+ if argCount == 0 {
+ segs = append(segs, seg)
+ }
+ }
+ }
+ }
+ }
+ if err == nil {
+ if argCount == 0 {
+ absolutizePath(segs)
+ } else {
+ err = fmt.Errorf("expecting additional (%d) numeric arguments", argCount)
+ }
+ }
+ return
+}
+
+// SVGBasicType aggregates the information needed to describe a multi-segment
+// basic vector image
+type SVGBasicType struct {
+ Wd, Ht float64
+ Segments [][]SVGBasicSegmentType
+}
+
+// SVGBasicParse parses a simple scalable vector graphics (SVG) buffer into a
+// descriptor. Only a small subset of the SVG standard, in particular the path
+// information generated by jSignature, is supported. The returned path data
+// includes only the commands 'M' (absolute moveto: x, y), 'L' (absolute
+// lineto: x, y), and 'C' (absolute cubic Bézier curve: cx0, cy0, cx1, cy1,
+// x1,y1).
+func SVGBasicParse(buf []byte) (sig SVGBasicType, err error) {
+ type pathType struct {
+ D string `xml:"d,attr"`
+ }
+ type srcType struct {
+ Wd float64 `xml:"width,attr"`
+ Ht float64 `xml:"height,attr"`
+ Paths []pathType `xml:"path"`
+ }
+ var src srcType
+ err = xml.Unmarshal(buf, &src)
+ if err == nil {
+ if src.Wd > 0 && src.Ht > 0 {
+ sig.Wd, sig.Ht = src.Wd, src.Ht
+ var segs []SVGBasicSegmentType
+ for _, path := range src.Paths {
+ if err == nil {
+ segs, err = pathParse(path.D)
+ if err == nil {
+ sig.Segments = append(sig.Segments, segs)
+ }
+ }
+ }
+ } else {
+ err = fmt.Errorf("unacceptable values for basic SVG extent: %.2f x %.2f",
+ sig.Wd, sig.Ht)
+ }
+ }
+ return
+}
+
+// SVGBasicFileParse parses a simple scalable vector graphics (SVG) file into a
+// basic descriptor. The SVGBasicWrite() example demonstrates this method.
+func SVGBasicFileParse(svgFileStr string) (sig SVGBasicType, err error) {
+ var buf []byte
+ buf, err = ioutil.ReadFile(svgFileStr)
+ if err == nil {
+ sig, err = SVGBasicParse(buf)
+ }
+ return
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/svgwrite.go b/vendor/github.com/jung-kurt/gofpdf/svgwrite.go
new file mode 100644
index 0000000..04f6cb3
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/svgwrite.go
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2014 Kurt Jung (Gmail: kurt.w.jung)
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package gofpdf
+
+// SVGBasicWrite renders the paths encoded in the basic SVG image specified by
+// sb. The scale value is used to convert the coordinates in the path to the
+// unit of measure specified in New(). The current position (as set with a call
+// to SetXY()) is used as the origin of the image. The current line cap style
+// (as set with SetLineCapStyle()), line width (as set with SetLineWidth()),
+// and draw color (as set with SetDrawColor()) are used in drawing the image
+// paths.
+func (f *Fpdf) SVGBasicWrite(sb *SVGBasicType, scale float64) {
+ originX, originY := f.GetXY()
+ var x, y, newX, newY float64
+ var cx0, cy0, cx1, cy1 float64
+ var path []SVGBasicSegmentType
+ var seg SVGBasicSegmentType
+ val := func(arg int) (float64, float64) {
+ return originX + scale*seg.Arg[arg], originY + scale*seg.Arg[arg+1]
+ }
+ for j := 0; j < len(sb.Segments) && f.Ok(); j++ {
+ path = sb.Segments[j]
+ for k := 0; k < len(path) && f.Ok(); k++ {
+ seg = path[k]
+ switch seg.Cmd {
+ case 'M':
+ x, y = val(0)
+ f.SetXY(x, y)
+ case 'L':
+ newX, newY = val(0)
+ f.Line(x, y, newX, newY)
+ x, y = newX, newY
+ case 'C':
+ cx0, cy0 = val(0)
+ cx1, cy1 = val(2)
+ newX, newY = val(4)
+ f.CurveCubic(x, y, cx0, cy0, newX, newY, cx1, cy1, "D")
+ x, y = newX, newY
+ default:
+ f.SetErrorf("Unexpected path command '%c'", seg.Cmd)
+ }
+ }
+ }
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/template.go b/vendor/github.com/jung-kurt/gofpdf/template.go
new file mode 100644
index 0000000..1826fd7
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/template.go
@@ -0,0 +1,269 @@
+package gofpdf
+
+/*
+ * Copyright (c) 2015 Kurt Jung (Gmail: kurt.w.jung),
+ * Marcus Downing, Jan Slabon (Setasign)
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+import (
+ "sort"
+)
+
+// CreateTemplate defines a new template using the current page size.
+func (f *Fpdf) CreateTemplate(fn func(*Tpl)) Template {
+ return newTpl(PointType{0, 0}, f.curPageSize, f.unitStr, f.fontDirStr, fn, f)
+}
+
+// CreateTemplateCustom starts a template, using the given bounds.
+func (f *Fpdf) CreateTemplateCustom(corner PointType, size SizeType, fn func(*Tpl)) Template {
+ return newTpl(corner, size, f.unitStr, f.fontDirStr, fn, f)
+}
+
+// CreateTemplate creates a template not attached to any document
+func CreateTemplate(corner PointType, size SizeType, unitStr, fontDirStr string, fn func(*Tpl)) Template {
+ return newTpl(corner, size, unitStr, fontDirStr, fn, nil)
+}
+
+// UseTemplate adds a template to the current page or another template,
+// using the size and position at which it was originally written.
+func (f *Fpdf) UseTemplate(t Template) {
+ if t == nil {
+ f.SetErrorf("template is nil")
+ return
+ }
+ corner, size := t.Size()
+ f.UseTemplateScaled(t, corner, size)
+}
+
+// UseTemplateScaled adds a template to the current page or another template,
+// using the given page coordinates.
+func (f *Fpdf) UseTemplateScaled(t Template, corner PointType, size SizeType) {
+ if t == nil {
+ f.SetErrorf("template is nil")
+ return
+ }
+
+ // You have to add at least a page first
+ if f.page <= 0 {
+ f.SetErrorf("cannot use a template without first adding a page")
+ return
+ }
+
+ // make a note of the fact that we actually use this template, as well as any other templates,
+ // images or fonts it uses
+ f.templates[t.ID()] = t
+ for _, tt := range t.Templates() {
+ f.templates[tt.ID()] = tt
+ }
+ for name, ti := range t.Images() {
+ name = sprintf("t%d-%s", t.ID(), name)
+ f.images[name] = ti
+ }
+
+ // template data
+ _, templateSize := t.Size()
+ scaleX := size.Wd / templateSize.Wd
+ scaleY := size.Ht / templateSize.Ht
+ tx := corner.X * f.k
+ ty := (f.curPageSize.Ht - corner.Y - size.Ht) * f.k
+
+ f.outf("q %.4f 0 0 %.4f %.4f %.4f cm", scaleX, scaleY, tx, ty) // Translate
+ f.outf("/TPL%d Do Q", t.ID())
+}
+
+var nextTemplateIDChannel = func() chan int64 {
+ ch := make(chan int64)
+ go func() {
+ var nextID int64 = 1
+ for {
+ ch <- nextID
+ nextID++
+ }
+ }()
+ return ch
+}()
+
+// GenerateTemplateID gives the next template ID. These numbers are global so that they can never clash.
+func GenerateTemplateID() int64 {
+ return <-nextTemplateIDChannel
+}
+
+// Template is an object that can be written to, then used and re-used any number of times within a document.
+type Template interface {
+ ID() int64
+ Size() (PointType, SizeType)
+ Bytes() []byte
+ Images() map[string]*ImageInfoType
+ Templates() []Template
+}
+
+func (f *Fpdf) templateFontCatalog() {
+ var keyList []string
+ var font fontDefType
+ var key string
+ f.out("/Font <<")
+ for key = range f.fonts {
+ keyList = append(keyList, key)
+ }
+ if f.catalogSort {
+ sort.Strings(keyList)
+ }
+ for _, key = range keyList {
+ font = f.fonts[key]
+ f.outf("/F%d %d 0 R", font.I, font.N)
+ }
+ f.out(">>")
+}
+
+// putTemplates writes the templates to the PDF
+func (f *Fpdf) putTemplates() {
+ filter := ""
+ if f.compress {
+ filter = "/Filter /FlateDecode "
+ }
+
+ templates := sortTemplates(f.templates, f.catalogSort)
+ var t Template
+ for _, t = range templates {
+ corner, size := t.Size()
+
+ f.newobj()
+ f.templateObjects[t.ID()] = f.n
+ f.outf("<<%s/Type /XObject", filter)
+ f.out("/Subtype /Form")
+ f.out("/Formtype 1")
+ f.outf("/BBox [%.2f %.2f %.2f %.2f]", corner.X*f.k, corner.Y*f.k, (corner.X+size.Wd)*f.k, (corner.Y+size.Ht)*f.k)
+ if corner.X != 0 || corner.Y != 0 {
+ f.outf("/Matrix [1 0 0 1 %.5f %.5f]", -corner.X*f.k*2, corner.Y*f.k*2)
+ }
+
+ // Template's resource dictionary
+ f.out("/Resources ")
+ f.out("<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]")
+
+ f.templateFontCatalog()
+
+ tImages := t.Images()
+ tTemplates := t.Templates()
+ if len(tImages) > 0 || len(tTemplates) > 0 {
+ f.out("/XObject <<")
+ {
+ var key string
+ var keyList []string
+ var ti *ImageInfoType
+ for key = range tImages {
+ keyList = append(keyList, key)
+ }
+ if gl.catalogSort {
+ sort.Strings(keyList)
+ }
+ for _, key = range keyList {
+ // for _, ti := range tImages {
+ ti = tImages[key]
+ f.outf("/I%d %d 0 R", ti.i, ti.n)
+ }
+ }
+ for _, tt := range tTemplates {
+ id := tt.ID()
+ if objID, ok := f.templateObjects[id]; ok {
+ f.outf("/TPL%d %d 0 R", id, objID)
+ }
+ }
+ f.out(">>")
+ }
+
+ f.out(">>")
+
+ // Write the template's byte stream
+ buffer := t.Bytes()
+ // fmt.Println("Put template bytes", string(buffer[:]))
+ if f.compress {
+ buffer = sliceCompress(buffer)
+ }
+ f.outf("/Length %d >>", len(buffer))
+ f.putstream(buffer)
+ f.out("endobj")
+ }
+}
+
+func templateKeyList(mp map[int64]Template, sort bool) (keyList []int64) {
+ var key int64
+ for key = range mp {
+ keyList = append(keyList, key)
+ }
+ if sort {
+ gensort(len(keyList),
+ func(a, b int) bool {
+ return keyList[a] < keyList[b]
+ },
+ func(a, b int) {
+ keyList[a], keyList[b] = keyList[b], keyList[a]
+ })
+ }
+ return
+}
+
+// sortTemplates puts templates in a suitable order based on dependices
+func sortTemplates(templates map[int64]Template, catalogSort bool) []Template {
+ chain := make([]Template, 0, len(templates)*2)
+
+ // build a full set of dependency chains
+ var keyList []int64
+ var key int64
+ var t Template
+ keyList = templateKeyList(templates, catalogSort)
+ for _, key = range keyList {
+ t = templates[key]
+ tlist := templateChainDependencies(t)
+ for _, tt := range tlist {
+ if tt != nil {
+ chain = append(chain, tt)
+ }
+ }
+ }
+
+ // reduce that to make a simple list
+ sorted := make([]Template, 0, len(templates))
+chain:
+ for _, t := range chain {
+ for _, already := range sorted {
+ if t == already {
+ continue chain
+ }
+ }
+ sorted = append(sorted, t)
+ }
+
+ return sorted
+}
+
+// templateChainDependencies is a recursive function for determining the full chain of template dependencies
+func templateChainDependencies(template Template) []Template {
+ requires := template.Templates()
+ chain := make([]Template, len(requires)*2)
+ for _, req := range requires {
+ for _, sub := range templateChainDependencies(req) {
+ chain = append(chain, sub)
+ }
+ }
+ chain = append(chain, template)
+ return chain
+}
+
+// < 0002640 31 20 31 32 20 30 20 52 0a 2f 54 50 4c 32 20 31 |1 12 0 R./TPL2 1|
+// < 0002650 35 20 30 20 52 0a 2f 54 50 4c 31 20 31 34 20 30 |5 0 R./TPL1 14 0|
+
+// > 0002640 31 20 31 32 20 30 20 52 0a 2f 54 50 4c 31 20 31 |1 12 0 R./TPL1 1|
+// > 0002650 34 20 30 20 52 0a 2f 54 50 4c 32 20 31 35 20 30 |4 0 R./TPL2 15 0|
diff --git a/vendor/github.com/jung-kurt/gofpdf/template_impl.go b/vendor/github.com/jung-kurt/gofpdf/template_impl.go
new file mode 100644
index 0000000..01bb040
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/template_impl.go
@@ -0,0 +1,123 @@
+package gofpdf
+
+/*
+ * Copyright (c) 2015 Kurt Jung (Gmail: kurt.w.jung),
+ * Marcus Downing, Jan Slabon (Setasign)
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+// newTpl creates a template, copying graphics settings from a template if one is given
+func newTpl(corner PointType, size SizeType, unitStr, fontDirStr string, fn func(*Tpl), copyFrom *Fpdf) Template {
+ orientationStr := "p"
+ if size.Wd > size.Ht {
+ orientationStr = "l"
+ }
+ sizeStr := ""
+
+ fpdf := fpdfNew(orientationStr, unitStr, sizeStr, fontDirStr, size)
+ tpl := Tpl{*fpdf}
+ if copyFrom != nil {
+ tpl.loadParamsFromFpdf(copyFrom)
+ }
+ tpl.Fpdf.SetAutoPageBreak(false, 0)
+ tpl.Fpdf.AddPage()
+ fn(&tpl)
+ bytes := tpl.Fpdf.pages[tpl.Fpdf.page].Bytes()
+ templates := make([]Template, 0, len(tpl.Fpdf.templates))
+ for _, key := range templateKeyList(tpl.Fpdf.templates, true) {
+ templates = append(templates, tpl.Fpdf.templates[key])
+ }
+ images := tpl.Fpdf.images
+
+ id := GenerateTemplateID()
+ template := FpdfTpl{id, corner, size, bytes, images, templates}
+ return &template
+}
+
+// FpdfTpl is a concrete implementation of the Template interface.
+type FpdfTpl struct {
+ id int64
+ corner PointType
+ size SizeType
+ bytes []byte
+ images map[string]*ImageInfoType
+ templates []Template
+}
+
+// ID returns the global template identifier
+func (t *FpdfTpl) ID() int64 {
+ return t.id
+}
+
+// Size gives the bounding dimensions of this template
+func (t *FpdfTpl) Size() (corner PointType, size SizeType) {
+ return t.corner, t.size
+}
+
+// Bytes returns the actual template data, not including resources
+func (t *FpdfTpl) Bytes() []byte {
+ return t.bytes
+}
+
+// Images returns a list of the images used in this template
+func (t *FpdfTpl) Images() map[string]*ImageInfoType {
+ return t.images
+}
+
+// Templates returns a list of templates used in this template
+func (t *FpdfTpl) Templates() []Template {
+ return t.templates
+}
+
+// Tpl is an Fpdf used for writing a template. It has most of the facilities of
+// an Fpdf, but cannot add more pages. Tpl is used directly only during the
+// limited time a template is writable.
+type Tpl struct {
+ Fpdf
+}
+
+func (t *Tpl) loadParamsFromFpdf(f *Fpdf) {
+ t.Fpdf.compress = false
+
+ t.Fpdf.k = f.k
+ t.Fpdf.x = f.x
+ t.Fpdf.y = f.y
+ t.Fpdf.lineWidth = f.lineWidth
+ t.Fpdf.capStyle = f.capStyle
+ t.Fpdf.joinStyle = f.joinStyle
+
+ t.Fpdf.color.draw = f.color.draw
+ t.Fpdf.color.fill = f.color.fill
+ t.Fpdf.color.text = f.color.text
+
+ t.Fpdf.fonts = f.fonts
+ t.Fpdf.currentFont = f.currentFont
+ t.Fpdf.fontFamily = f.fontFamily
+ t.Fpdf.fontSize = f.fontSize
+ t.Fpdf.fontSizePt = f.fontSizePt
+ t.Fpdf.fontStyle = f.fontStyle
+ t.Fpdf.ws = f.ws
+}
+
+// AddPage does nothing because you cannot add pages to a template
+func (t *Tpl) AddPage() {
+}
+
+// AddPageFormat does nothign because you cannot add pages to a template
+func (t *Tpl) AddPageFormat(orientationStr string, size SizeType) {
+}
+
+// SetAutoPageBreak does nothing because you cannot add pages to a template
+func (t *Tpl) SetAutoPageBreak(auto bool, margin float64) {
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/ttfparser.go b/vendor/github.com/jung-kurt/gofpdf/ttfparser.go
new file mode 100644
index 0000000..669ab4d
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/ttfparser.go
@@ -0,0 +1,374 @@
+/*
+ * Copyright (c) 2013 Kurt Jung (Gmail: kurt.w.jung)
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package gofpdf
+
+// Utility to parse TTF font files
+// Version: 1.0
+// Date: 2011-06-18
+// Author: Olivier PLATHEY
+// Port to Go: Kurt Jung, 2013-07-15
+
+import (
+ "encoding/binary"
+ "fmt"
+ "os"
+ "regexp"
+ "strings"
+)
+
+// TtfType contains metrics of a TrueType font.
+type TtfType struct {
+ Embeddable bool
+ UnitsPerEm uint16
+ PostScriptName string
+ Bold bool
+ ItalicAngle int16
+ IsFixedPitch bool
+ TypoAscender int16
+ TypoDescender int16
+ UnderlinePosition int16
+ UnderlineThickness int16
+ Xmin, Ymin, Xmax, Ymax int16
+ CapHeight int16
+ Widths []uint16
+ Chars map[uint16]uint16
+}
+
+type ttfParser struct {
+ rec TtfType
+ f *os.File
+ tables map[string]uint32
+ numberOfHMetrics uint16
+ numGlyphs uint16
+}
+
+// TtfParse extracts various metrics from a TrueType font file.
+func TtfParse(fileStr string) (TtfRec TtfType, err error) {
+ var t ttfParser
+ t.f, err = os.Open(fileStr)
+ if err != nil {
+ return
+ }
+ version, err := t.ReadStr(4)
+ if err != nil {
+ return
+ }
+ if version == "OTTO" {
+ err = fmt.Errorf("fonts based on PostScript outlines are not supported")
+ return
+ }
+ if version != "\x00\x01\x00\x00" {
+ err = fmt.Errorf("unrecognized file format")
+ return
+ }
+ numTables := int(t.ReadUShort())
+ t.Skip(3 * 2) // searchRange, entrySelector, rangeShift
+ t.tables = make(map[string]uint32)
+ var tag string
+ for j := 0; j < numTables; j++ {
+ tag, err = t.ReadStr(4)
+ if err != nil {
+ return
+ }
+ t.Skip(4) // checkSum
+ offset := t.ReadULong()
+ t.Skip(4) // length
+ t.tables[tag] = offset
+ }
+ err = t.ParseComponents()
+ if err != nil {
+ return
+ }
+ t.f.Close()
+ TtfRec = t.rec
+ return
+}
+
+func (t *ttfParser) ParseComponents() (err error) {
+ err = t.ParseHead()
+ if err == nil {
+ err = t.ParseHhea()
+ if err == nil {
+ err = t.ParseMaxp()
+ if err == nil {
+ err = t.ParseHmtx()
+ if err == nil {
+ err = t.ParseCmap()
+ if err == nil {
+ err = t.ParseName()
+ if err == nil {
+ err = t.ParseOS2()
+ if err == nil {
+ err = t.ParsePost()
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return
+}
+
+func (t *ttfParser) ParseHead() (err error) {
+ err = t.Seek("head")
+ t.Skip(3 * 4) // version, fontRevision, checkSumAdjustment
+ magicNumber := t.ReadULong()
+ if magicNumber != 0x5F0F3CF5 {
+ err = fmt.Errorf("incorrect magic number")
+ return
+ }
+ t.Skip(2) // flags
+ t.rec.UnitsPerEm = t.ReadUShort()
+ t.Skip(2 * 8) // created, modified
+ t.rec.Xmin = t.ReadShort()
+ t.rec.Ymin = t.ReadShort()
+ t.rec.Xmax = t.ReadShort()
+ t.rec.Ymax = t.ReadShort()
+ return
+}
+
+func (t *ttfParser) ParseHhea() (err error) {
+ err = t.Seek("hhea")
+ if err == nil {
+ t.Skip(4 + 15*2)
+ t.numberOfHMetrics = t.ReadUShort()
+ }
+ return
+}
+
+func (t *ttfParser) ParseMaxp() (err error) {
+ err = t.Seek("maxp")
+ if err == nil {
+ t.Skip(4)
+ t.numGlyphs = t.ReadUShort()
+ }
+ return
+}
+
+func (t *ttfParser) ParseHmtx() (err error) {
+ err = t.Seek("hmtx")
+ if err == nil {
+ t.rec.Widths = make([]uint16, 0, 8)
+ for j := uint16(0); j < t.numberOfHMetrics; j++ {
+ t.rec.Widths = append(t.rec.Widths, t.ReadUShort())
+ t.Skip(2) // lsb
+ }
+ if t.numberOfHMetrics < t.numGlyphs {
+ lastWidth := t.rec.Widths[t.numberOfHMetrics-1]
+ for j := t.numberOfHMetrics; j < t.numGlyphs; j++ {
+ t.rec.Widths = append(t.rec.Widths, lastWidth)
+ }
+ }
+ }
+ return
+}
+
+func (t *ttfParser) ParseCmap() (err error) {
+ var offset int64
+ if err = t.Seek("cmap"); err != nil {
+ return
+ }
+ t.Skip(2) // version
+ numTables := int(t.ReadUShort())
+ offset31 := int64(0)
+ for j := 0; j < numTables; j++ {
+ platformID := t.ReadUShort()
+ encodingID := t.ReadUShort()
+ offset = int64(t.ReadULong())
+ if platformID == 3 && encodingID == 1 {
+ offset31 = offset
+ }
+ }
+ if offset31 == 0 {
+ err = fmt.Errorf("no Unicode encoding found")
+ return
+ }
+ startCount := make([]uint16, 0, 8)
+ endCount := make([]uint16, 0, 8)
+ idDelta := make([]int16, 0, 8)
+ idRangeOffset := make([]uint16, 0, 8)
+ t.rec.Chars = make(map[uint16]uint16)
+ t.f.Seek(int64(t.tables["cmap"])+offset31, os.SEEK_SET)
+ format := t.ReadUShort()
+ if format != 4 {
+ err = fmt.Errorf("unexpected subtable format: %d", format)
+ return
+ }
+ t.Skip(2 * 2) // length, language
+ segCount := int(t.ReadUShort() / 2)
+ t.Skip(3 * 2) // searchRange, entrySelector, rangeShift
+ for j := 0; j < segCount; j++ {
+ endCount = append(endCount, t.ReadUShort())
+ }
+ t.Skip(2) // reservedPad
+ for j := 0; j < segCount; j++ {
+ startCount = append(startCount, t.ReadUShort())
+ }
+ for j := 0; j < segCount; j++ {
+ idDelta = append(idDelta, t.ReadShort())
+ }
+ offset, _ = t.f.Seek(int64(0), os.SEEK_CUR)
+ for j := 0; j < segCount; j++ {
+ idRangeOffset = append(idRangeOffset, t.ReadUShort())
+ }
+ for j := 0; j < segCount; j++ {
+ c1 := startCount[j]
+ c2 := endCount[j]
+ d := idDelta[j]
+ ro := idRangeOffset[j]
+ if ro > 0 {
+ t.f.Seek(offset+2*int64(j)+int64(ro), os.SEEK_SET)
+ }
+ for c := c1; c <= c2; c++ {
+ if c == 0xFFFF {
+ break
+ }
+ var gid int32
+ if ro > 0 {
+ gid = int32(t.ReadUShort())
+ if gid > 0 {
+ gid += int32(d)
+ }
+ } else {
+ gid = int32(c) + int32(d)
+ }
+ if gid >= 65536 {
+ gid -= 65536
+ }
+ if gid > 0 {
+ t.rec.Chars[c] = uint16(gid)
+ }
+ }
+ }
+ return
+}
+
+func (t *ttfParser) ParseName() (err error) {
+ err = t.Seek("name")
+ if err == nil {
+ tableOffset, _ := t.f.Seek(0, os.SEEK_CUR)
+ t.rec.PostScriptName = ""
+ t.Skip(2) // format
+ count := t.ReadUShort()
+ stringOffset := t.ReadUShort()
+ for j := uint16(0); j < count && t.rec.PostScriptName == ""; j++ {
+ t.Skip(3 * 2) // platformID, encodingID, languageID
+ nameID := t.ReadUShort()
+ length := t.ReadUShort()
+ offset := t.ReadUShort()
+ if nameID == 6 {
+ // PostScript name
+ t.f.Seek(int64(tableOffset)+int64(stringOffset)+int64(offset), os.SEEK_SET)
+ var s string
+ s, err = t.ReadStr(int(length))
+ if err != nil {
+ return
+ }
+ s = strings.Replace(s, "\x00", "", -1)
+ var re *regexp.Regexp
+ if re, err = regexp.Compile("[(){}<> /%[\\]]"); err != nil {
+ return
+ }
+ t.rec.PostScriptName = re.ReplaceAllString(s, "")
+ }
+ }
+ if t.rec.PostScriptName == "" {
+ err = fmt.Errorf("the name PostScript was not found")
+ }
+ }
+ return
+}
+
+func (t *ttfParser) ParseOS2() (err error) {
+ err = t.Seek("OS/2")
+ if err == nil {
+ version := t.ReadUShort()
+ t.Skip(3 * 2) // xAvgCharWidth, usWeightClass, usWidthClass
+ fsType := t.ReadUShort()
+ t.rec.Embeddable = (fsType != 2) && (fsType&0x200) == 0
+ t.Skip(11*2 + 10 + 4*4 + 4)
+ fsSelection := t.ReadUShort()
+ t.rec.Bold = (fsSelection & 32) != 0
+ t.Skip(2 * 2) // usFirstCharIndex, usLastCharIndex
+ t.rec.TypoAscender = t.ReadShort()
+ t.rec.TypoDescender = t.ReadShort()
+ if version >= 2 {
+ t.Skip(3*2 + 2*4 + 2)
+ t.rec.CapHeight = t.ReadShort()
+ } else {
+ t.rec.CapHeight = 0
+ }
+ }
+ return
+}
+
+func (t *ttfParser) ParsePost() (err error) {
+ err = t.Seek("post")
+ if err == nil {
+ t.Skip(4) // version
+ t.rec.ItalicAngle = t.ReadShort()
+ t.Skip(2) // Skip decimal part
+ t.rec.UnderlinePosition = t.ReadShort()
+ t.rec.UnderlineThickness = t.ReadShort()
+ t.rec.IsFixedPitch = t.ReadULong() != 0
+ }
+ return
+}
+
+func (t *ttfParser) Seek(tag string) (err error) {
+ ofs, ok := t.tables[tag]
+ if ok {
+ t.f.Seek(int64(ofs), os.SEEK_SET)
+ } else {
+ err = fmt.Errorf("table not found: %s", tag)
+ }
+ return
+}
+
+func (t *ttfParser) Skip(n int) {
+ t.f.Seek(int64(n), os.SEEK_CUR)
+}
+
+func (t *ttfParser) ReadStr(length int) (str string, err error) {
+ var n int
+ buf := make([]byte, length)
+ n, err = t.f.Read(buf)
+ if err == nil {
+ if n == length {
+ str = string(buf)
+ } else {
+ err = fmt.Errorf("unable to read %d bytes", length)
+ }
+ }
+ return
+}
+
+func (t *ttfParser) ReadUShort() (val uint16) {
+ binary.Read(t.f, binary.BigEndian, &val)
+ return
+}
+
+func (t *ttfParser) ReadShort() (val int16) {
+ binary.Read(t.f, binary.BigEndian, &val)
+ return
+}
+
+func (t *ttfParser) ReadULong() (val uint32) {
+ binary.Read(t.f, binary.BigEndian, &val)
+ return
+}
diff --git a/vendor/github.com/jung-kurt/gofpdf/util.go b/vendor/github.com/jung-kurt/gofpdf/util.go
new file mode 100644
index 0000000..149271c
--- /dev/null
+++ b/vendor/github.com/jung-kurt/gofpdf/util.go
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2013 Kurt Jung (Gmail: kurt.w.jung)
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package gofpdf
+
+import (
+ "bytes"
+ "compress/zlib"
+ "fmt"
+ // "github.com/davecgh/go-spew/spew"
+ "bufio"
+ "io"
+ "math"
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+func round(f float64) int {
+ if f < 0 {
+ return -int(math.Floor(-f + 0.5))
+ }
+ return int(math.Floor(f + 0.5))
+}
+
+func sprintf(fmtStr string, args ...interface{}) string {
+ return fmt.Sprintf(fmtStr, args...)
+}
+
+// Returns true if the specified normal file exists
+func fileExist(filename string) (ok bool) {
+ info, err := os.Stat(filename)
+ if err == nil {
+ if ^os.ModePerm&info.Mode() == 0 {
+ ok = true
+ }
+ }
+ return ok
+}
+
+// Returns the size of the specified file; ok will be false
+// if the file does not exist or is not an ordinary file
+func fileSize(filename string) (size int64, ok bool) {
+ info, err := os.Stat(filename)
+ ok = err == nil
+ if ok {
+ size = info.Size()
+ }
+ return
+}
+
+// Returns a new buffer populated with the contents of the specified Reader
+func bufferFromReader(r io.Reader) (b *bytes.Buffer, err error) {
+ b = new(bytes.Buffer)
+ _, err = b.ReadFrom(r)
+ return
+}
+
+// Returns true if the two specified float slices are equal
+func slicesEqual(a, b []float64) bool {
+ if len(a) != len(b) {
+ return false
+ }
+ for i := range a {
+ if a[i] != b[i] {
+ return false
+ }
+ }
+ return true
+}
+
+// Returns a zlib-compressed copy of the specified byte array
+func sliceCompress(data []byte) []byte {
+ var buf bytes.Buffer
+ cmp, _ := zlib.NewWriterLevel(&buf, zlib.BestSpeed)
+ cmp.Write(data)
+ cmp.Close()
+ return buf.Bytes()
+}
+
+// Returns an uncompressed copy of the specified zlib-compressed byte array
+func sliceUncompress(data []byte) (outData []byte, err error) {
+ inBuf := bytes.NewBuffer(data)
+ r, err := zlib.NewReader(inBuf)
+ defer r.Close()
+ if err == nil {
+ var outBuf bytes.Buffer
+ _, err = outBuf.ReadFrom(r)
+ if err == nil {
+ outData = outBuf.Bytes()
+ }
+ }
+ return
+}
+
+// Convert UTF-8 to UTF-16BE with BOM; from http://www.fpdf.org/
+func utf8toutf16(s string) string {
+ res := make([]byte, 0, 8)
+ res = append(res, 0xFE, 0xFF)
+ nb := len(s)
+ i := 0
+ for i < nb {
+ c1 := byte(s[i])
+ i++
+ if c1 >= 224 {
+ // 3-byte character
+ c2 := byte(s[i])
+ i++
+ c3 := byte(s[i])
+ i++
+ res = append(res, ((c1&0x0F)<<4)+((c2&0x3C)>>2),
+ ((c2&0x03)<<6)+(c3&0x3F))
+ } else if c1 >= 192 {
+ // 2-byte character
+ c2 := byte(s[i])
+ i++
+ res = append(res, ((c1 & 0x1C) >> 2),
+ ((c1&0x03)<<6)+(c2&0x3F))
+ } else {
+ // Single-byte character
+ res = append(res, 0, c1)
+ }
+ }
+ return string(res)
+}
+
+// Return a if cnd is true, otherwise b
+func intIf(cnd bool, a, b int) int {
+ if cnd {
+ return a
+ }
+ return b
+}
+
+// Return aStr if cnd is true, otherwise bStr
+func strIf(cnd bool, aStr, bStr string) string {
+ if cnd {
+ return aStr
+ }
+ return bStr
+}
+
+// Dump the internals of the specified values
+// func dump(fileStr string, a ...interface{}) {
+// fl, err := os.OpenFile(fileStr, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
+// if err == nil {
+// fmt.Fprintf(fl, "----------------\n")
+// spew.Fdump(fl, a...)
+// fl.Close()
+// }
+// }
+
+func repClosure(m map[rune]byte) func(string) string {
+ var buf bytes.Buffer
+ return func(str string) string {
+ var ch byte
+ var ok bool
+ buf.Truncate(0)
+ for _, r := range str {
+ if r < 0x80 {
+ ch = byte(r)
+ } else {
+ ch, ok = m[r]
+ if !ok {
+ ch = byte('.')
+ }
+ }
+ buf.WriteByte(ch)
+ }
+ return buf.String()
+ }
+}
+
+// UnicodeTranslator returns a function that can be used to translate, where
+// possible, utf-8 strings to a form that is compatible with the specified code
+// page. The returned function accepts a string and returns a string.
+//
+// r is a reader that should read a buffer made up of content lines that
+// pertain to the code page of interest. Each line is made up of three
+// whitespace separated fields. The first begins with "!" and is followed by
+// two hexadecimal digits that identify the glyph position in the code page of
+// interest. The second field begins with "U+" and is followed by the unicode
+// code point value. The third is the glyph name. A number of these code page
+// map files are packaged with the gfpdf library in the font directory.
+//
+// An error occurs only if a line is read that does not conform to the expected
+// format. In this case, the returned function is valid but does not perform
+// any rune translation.
+func UnicodeTranslator(r io.Reader) (f func(string) string, err error) {
+ m := make(map[rune]byte)
+ var uPos, cPos uint32
+ var lineStr, nameStr string
+ sc := bufio.NewScanner(r)
+ for sc.Scan() {
+ lineStr = sc.Text()
+ lineStr = strings.TrimSpace(lineStr)
+ if len(lineStr) > 0 {
+ _, err = fmt.Sscanf(lineStr, "!%2X U+%4X %s", &cPos, &uPos, &nameStr)
+ if err == nil {
+ if cPos >= 0x80 {
+ m[rune(uPos)] = byte(cPos)
+ }
+ }
+ }
+ }
+ if err == nil {
+ f = repClosure(m)
+ } else {
+ f = func(s string) string {
+ return s
+ }
+ }
+ return
+}
+
+// UnicodeTranslatorFromFile returns a function that can be used to translate,
+// where possible, utf-8 strings to a form that is compatible with the
+// specified code page. See UnicodeTranslator for more details.
+//
+// fileStr identifies a font descriptor file that maps glyph positions to names.
+//
+// If an error occurs reading the file, the returned function is valid but does
+// not perform any rune translation.
+func UnicodeTranslatorFromFile(fileStr string) (f func(string) string, err error) {
+ var fl *os.File
+ fl, err = os.Open(fileStr)
+ if err == nil {
+ f, err = UnicodeTranslator(fl)
+ fl.Close()
+ } else {
+ f = func(s string) string {
+ return s
+ }
+ }
+ return
+}
+
+// UnicodeTranslatorFromDescriptor returns a function that can be used to
+// translate, where possible, utf-8 strings to a form that is compatible with
+// the specified code page. See UnicodeTranslator for more details.
+//
+// cpStr identifies a code page. A descriptor file in the font directory, set
+// with the fontDirStr argument in the call to New(), should have this name
+// plus the extension ".map". If cpStr is empty, it will be replaced with
+// "cp1252", the gofpdf code page default.
+//
+// If an error occurs reading the descriptor, the returned function is valid
+// but does not perform any rune translation.
+//
+// The CellFormat (4) example demonstrates this method.
+func (f *Fpdf) UnicodeTranslatorFromDescriptor(cpStr string) (rep func(string) string) {
+ var str string
+ var ok bool
+ if f.err != nil {
+ return
+ }
+ if len(cpStr) == 0 {
+ cpStr = "cp1252"
+ }
+ str, ok = embeddedMapList[cpStr]
+ if ok {
+ rep, f.err = UnicodeTranslator(strings.NewReader(str))
+ } else {
+ rep, f.err = UnicodeTranslatorFromFile(filepath.Join(f.fontpath, cpStr) + ".map")
+ }
+ return
+}
+
+// Transform moves a point by given X, Y offset
+func (p *PointType) Transform(x, y float64) PointType {
+ return PointType{p.X + x, p.Y + y}
+}
+
+// Orientation returns the orientation of a given size:
+// "P" for portrait, "L" for landscape
+func (s *SizeType) Orientation() string {
+ if s == nil || s.Ht == s.Wd {
+ return ""
+ }
+ if s.Wd > s.Ht {
+ return "L"
+ }
+ return "P"
+}
+
+// ScaleBy expands a size by a certain factor
+func (s *SizeType) ScaleBy(factor float64) SizeType {
+ return SizeType{s.Wd * factor, s.Ht * factor}
+}
+
+// ScaleToWidth adjusts the height of a size to match the given width
+func (s *SizeType) ScaleToWidth(width float64) SizeType {
+ height := s.Ht * width / s.Wd
+ return SizeType{width, height}
+}
+
+// ScaleToHeight adjusts the width of a size to match the given height
+func (s *SizeType) ScaleToHeight(height float64) SizeType {
+ width := s.Wd * height / s.Ht
+ return SizeType{width, height}
+}