loubw hace 3 semanas
commit
f3685b737f
Se han modificado 100 ficheros con 20243 adiciones y 0 borrados
  1. 1 0
      .gitattribute
  2. 25 0
      .gitignore
  3. 14 0
      .travis.yml
  4. 21 0
      LICENSE
  5. 29 0
      Makefile
  6. 282 0
      README.md
  7. 157 0
      attachments.go
  8. 146 0
      compare.go
  9. 302 0
      contrib/barcode/barcode.go
  10. 222 0
      contrib/barcode/barcode_test.go
  11. 68 0
      contrib/ghostscript/ghostscript.go
  12. 143 0
      contrib/gofpdi/gofpdi.go
  13. 76 0
      contrib/gofpdi/gofpdi_test.go
  14. 43 0
      contrib/httpimg/httpimg.go
  15. 23 0
      contrib/httpimg/httpimg_test.go
  16. 83 0
      contrib/tiff/tiff.go
  17. 23 0
      contrib/tiff/tiff_test.go
  18. 738 0
      def.go
  19. 291 0
      doc.go
  20. 288 0
      doc/document.md
  21. 13 0
      doc/go.awk
  22. 68 0
      doc/html.txt
  23. 559 0
      embedded.go
  24. 474 0
      font.go
  25. 272 0
      font/CalligrapherRegular.afm
  26. BIN
      font/CalligrapherRegular.pfb
  27. BIN
      font/DejaVuSansCondensed-Bold.ttf
  28. BIN
      font/DejaVuSansCondensed-BoldOblique.ttf
  29. BIN
      font/DejaVuSansCondensed-Oblique.ttf
  30. 0 0
      font/DejaVuSansCondensed.json
  31. BIN
      font/DejaVuSansCondensed.ttf
  32. 1 0
      font/calligra.json
  33. BIN
      font/calligra.ttf
  34. BIN
      font/calligra.z
  35. 1 0
      font/courier.json
  36. 1 0
      font/courierb.json
  37. 1 0
      font/courierbi.json
  38. 1 0
      font/courieri.json
  39. 251 0
      font/cp1250.map
  40. 255 0
      font/cp1251.map
  41. 251 0
      font/cp1252.map
  42. 239 0
      font/cp1253.map
  43. 249 0
      font/cp1254.map
  44. 233 0
      font/cp1255.map
  45. 244 0
      font/cp1257.map
  46. 247 0
      font/cp1258.map
  47. 225 0
      font/cp874.map
  48. 1 0
      font/helvetica.json
  49. 0 0
      font/helvetica_1251.json
  50. BIN
      font/helvetica_1251.z
  51. 0 0
      font/helvetica_1253.json
  52. BIN
      font/helvetica_1253.z
  53. 1 0
      font/helveticab.json
  54. 1 0
      font/helveticabi.json
  55. 1 0
      font/helveticai.json
  56. 256 0
      font/iso-8859-1.map
  57. 248 0
      font/iso-8859-11.map
  58. 256 0
      font/iso-8859-15.map
  59. 256 0
      font/iso-8859-16.map
  60. 256 0
      font/iso-8859-2.map
  61. 256 0
      font/iso-8859-4.map
  62. 256 0
      font/iso-8859-5.map
  63. 250 0
      font/iso-8859-7.map
  64. 256 0
      font/iso-8859-9.map
  65. 256 0
      font/koi8-r.map
  66. 256 0
      font/koi8-u.map
  67. 1 0
      font/times.json
  68. 1 0
      font/timesb.json
  69. 1 0
      font/timesbi.json
  70. 1 0
      font/timesi.json
  71. 1 0
      font/zapfdingbats.json
  72. 5007 0
      fpdf.go
  73. 2924 0
      fpdf_test.go
  74. 213 0
      fpdftrans.go
  75. 12 0
      go.mod
  76. 20 0
      go.sum
  77. 446 0
      grid.go
  78. 220 0
      htmlbasic.go
  79. BIN
      image/doc.png
  80. 20 0
      image/doc.svg
  81. BIN
      image/fpdf.png
  82. BIN
      image/gofpdf.png
  83. BIN
      image/golang-gopher.png
  84. BIN
      image/golang-gopher.tiff
  85. BIN
      image/logo-gray.png
  86. BIN
      image/logo-progressive.jpg
  87. BIN
      image/logo-rgb.png
  88. BIN
      image/logo.gif
  89. BIN
      image/logo.jpg
  90. BIN
      image/logo.png
  91. BIN
      image/logo_gofpdf.jpg
  92. BIN
      image/mit.png
  93. 20 0
      image/mit.svg
  94. 73 0
      image/signature.svg
  95. BIN
      image/sweden.png
  96. 143 0
      internal/example/example.go
  97. 31 0
      internal/example/example_test.go
  98. 24 0
      internal/files/bin/Makefile
  99. 28 0
      internal/files/bin/bin.go
  100. 1691 0
      internal/files/files.go

+ 1 - 0
.gitattribute

@@ -0,0 +1 @@
+*.pdf binary

+ 25 - 0
.gitignore

@@ -0,0 +1,25 @@
+*.0
+coverage
+font/CalligrapherRegular.json
+font/CalligrapherRegular.z
+font/Ubuntu-*
+internal/files/bin/bin
+look
+makefont/makefont
+open
+**/*.out
+pdf/*.pdf
+pdf.txt
+private
+*.sublime*
+*.swp
+**/*.test
+.idea/
+doc/body.html
+doc/body.md
+doc/index.html
+doc/index.html.ok
+coverage.html
+
+# macOS
+.DS_Store

+ 14 - 0
.travis.yml

@@ -0,0 +1,14 @@
+language: go
+
+sudo: false
+
+go:
+  - master
+
+os:
+  - linux
+            
+script: go test -v
+
+notifications:
+  email: false

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Kurt Jung and 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.

+ 29 - 0
Makefile

@@ -0,0 +1,29 @@
+all : documentation
+
+documentation : doc/index.html doc.go README.md 
+
+cov : all
+	go test -v -coverprofile=coverage && go tool cover -html=coverage -o=coverage.html
+
+check :
+	golint .
+	go vet -all .
+	gofmt -s -l .
+	goreportcard-cli -v | grep -v cyclomatic
+
+README.md : doc/document.md
+	pandoc --read=markdown --write=gfm < $< > $@
+
+doc/index.html : doc/document.md doc/html.txt
+	pandoc --read=markdown --write=html --template=doc/html.txt \
+		--metadata pagetitle="GoFPDF Document Generator" < $< > $@
+
+doc.go : doc/document.md doc/go.awk
+	pandoc --read=markdown --write=plain $< | awk --assign=package_name=gofpdf --file=doc/go.awk > $@
+	gofmt -s -w $@
+
+build :
+	go build -v
+
+clean :
+	rm -f coverage.html coverage doc/index.html doc.go README.md

+ 282 - 0
README.md

@@ -0,0 +1,282 @@
+# GoFPDF document generator
+
+[![No Maintenance
+Intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/)
+[![MIT
+licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/jung-kurt/gofpdf/master/LICENSE)
+[![Report](https://goreportcard.com/badge/github.com/jung-kurt/gofpdf)](https://goreportcard.com/report/github.com/jung-kurt/gofpdf)
+[![GoDoc](https://img.shields.io/badge/godoc-GoFPDF-blue.svg)](https://godoc.org/github.com/jung-kurt/gofpdf)
+
+![](https://github.com/jung-kurt/gofpdf/raw/master/image/logo_gofpdf.jpg?raw=true)
+
+Package gofpdf implements a PDF document generator with high level
+support for text, drawing and images.
+
+## Features
+
+  - UTF-8 support
+  - 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
+  - Barcodes
+  - Charting facility
+  - Import PDFs as templates
+
+gofpdf has no dependencies other than the Go standard library. All tests
+pass on Linux, Mac and Windows platforms.
+
+gofpdf supports UTF-8 TrueType fonts and “right-to-left” languages. Note
+that Chinese, Japanese, and Korean characters may not be included in
+many general purpose fonts. For these languages, a specialized font (for
+example,
+[NotoSansSC](https://github.com/jsntn/webfonts/blob/master/NotoSansSC-Regular.ttf)
+for simplified Chinese) can be used.
+
+Also, support is provided to automatically translate UTF-8 runes to code
+page encodings for languages that have fewer than 256 glyphs.
+
+## We Are Closed
+
+This repository will not be maintained, at least for some unknown
+duration. But it is hoped that gofpdf has a bright future in the open
+source world. Due to Go’s promise of compatibility, gofpdf should
+continue to function without modification for a longer time than would
+be the case with many other languages.
+
+Forks should be based on the [last viable
+commit](https://github.com/jung-kurt/gofpdf/commit/603f56990463f011cb1dbb64ef7f872c1adc009a).
+Tools such as
+[active-forks](https://techgaun.github.io/active-forks/index.html#jung-kurt/gofpdf)
+can be used to select a fork that looks promising for your needs. If a
+particular fork looks like it has taken the lead in attracting
+followers, this README will be updated to point people in that
+direction.
+
+The efforts of all contributors to this project have been deeply
+appreciated. Best wishes to all of you.
+
+## Installation
+
+To install the package on your system, run
+
+``` shell
+go get github.com/jung-kurt/gofpdf
+```
+
+Later, to receive updates, run
+
+``` shell
+go get -u -v github.com/jung-kurt/gofpdf/...
+```
+
+## Quick Start
+
+The following Go code generates a simple PDF file.
+
+``` go
+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](https://github.com/jung-kurt/gofpdf/blob/master/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](http://www.fpdf.org/) library written in PHP (despite
+the caveat in the introduction to [Effective
+Go](https://golang.org/doc/effective_go.html)). 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](https://github.com/jung-kurt/gofpdf/blob/master/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 and if the third argument to
+`ComparePDFFiles()` in internal/example/example.go is true. (By default
+it is false.) 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()`.
+
+You should use `AddUTF8Font()` or `AddUTF8FontFromBytes()` to add a
+TrueType UTF-8 encoded font. Use `RTL()` and `LTR()` methods switch
+between “right-to-left” and “left-to-right” mode.
+
+In order to use a different non-UTF-8 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.
+
+``` shell
+./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 [Google
+Fonts](https://fonts.google.com/) and [DejaVu
+Fonts](http://dejavu-fonts.org/).
+
+## Related Packages
+
+The [draw2d](https://github.com/llgcode/draw2d) package 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](https://github.com/jung-kurt/gofpdf/blob/master/fpdf_test.go)
+    if appropriate
+  - conform to the standards of [golint](https://github.com/golang/lint)
+    and [go vet](https://golang.org/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/)
+are the preferred means of accepting 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](http://www.fpdf.org/) library created by Olivier Plathey, and a
+number of font and image resources are copied directly from it. Bruno
+Michel has provided valuable assistance with the code. 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. Jelmer
+Snoek and Guillermo Pascual 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. Dan
+Meyers added support for embedded JavaScript. David Fish added a generic
+alias-replacement function to enable, among other things, table of
+contents functionality. Andy Bakun identified and corrected a problem in
+which the internal catalogs were not sorted stably. Paul Montag added
+encoding and decoding functionality for templates, including images that
+are embedded in templates; this allows templates to be stored
+independently of gofpdf. Paul also added support for page boxes used in
+printing PDF documents. Wojciech Matusiak added supported for word
+spacing. Artem Korotkiy added support of UTF-8 fonts. Dave Barnes added
+support for imported objects and templates. Brigham Thompson added
+support for rounded rectangles. Joe Westcott added underline
+functionality and optimized image storage. Benoit KUGLER contributed
+support for rectangles with corners of unequal radius, modification
+times, and for file attachments and annotations.
+
+## Roadmap
+
+  - Remove all legacy code page font support; use UTF-8 exclusively
+  - Improve test coverage as reported by the coverage tool.

+ 157 - 0
attachments.go

@@ -0,0 +1,157 @@
+package gofpdf
+
+import (
+	"crypto/md5"
+	"encoding/hex"
+	"fmt"
+	"strings"
+)
+
+// Attachment defines a content to be included in the pdf, in one
+// of the following ways :
+// 	- associated with the document as a whole : see SetAttachments()
+//	- accessible via a link localized on a page : see AddAttachmentAnnotation()
+type Attachment struct {
+	Content []byte
+
+	// Filename is the displayed name of the attachment
+	Filename string
+
+	// Description is only displayed when using AddAttachmentAnnotation(),
+	// and might be modified by the pdf reader.
+	Description string
+
+	objectNumber int // filled when content is included
+}
+
+// return the hex encoded checksum of `data`
+func checksum(data []byte) string {
+	tmp := md5.Sum(data)
+	sl := make([]byte, len(tmp))
+	for i, v := range tmp {
+		sl[i] = v
+	}
+	return hex.EncodeToString(sl)
+}
+
+// Writes a compressed file like object as ``/EmbeddedFile``. Compressing is
+// done with deflate. Includes length, compressed length and MD5 checksum.
+func (f *Fpdf) writeCompressedFileObject(content []byte) {
+	lenUncompressed := len(content)
+	sum := checksum(content)
+	compressed := sliceCompress(content)
+	lenCompressed := len(compressed)
+	f.newobj()
+	f.outf("<< /Type /EmbeddedFile /Length %d /Filter /FlateDecode /Params << /CheckSum <%s> /Size %d >> >>\n",
+		lenCompressed, sum, lenUncompressed)
+	f.putstream(compressed)
+	f.out("endobj")
+}
+
+// Embed includes the content of `a`, and update its internal reference.
+func (f *Fpdf) embed(a *Attachment) {
+	if a.objectNumber != 0 { // already embedded (objectNumber start at 2)
+		return
+	}
+	oldState := f.state
+	f.state = 1 // we write file content in the main buffer
+	f.writeCompressedFileObject(a.Content)
+	streamID := f.n
+	f.newobj()
+	f.outf("<< /Type /Filespec /F () /UF %s /EF << /F %d 0 R >> /Desc %s\n>>",
+		f.textstring(utf8toutf16(a.Filename)),
+		streamID,
+		f.textstring(utf8toutf16(a.Description)))
+	f.out("endobj")
+	a.objectNumber = f.n
+	f.state = oldState
+}
+
+// SetAttachments writes attachments as embedded files (document attachment).
+// These attachments are global, see AddAttachmentAnnotation() for a link
+// anchored in a page. Note that only the last call of SetAttachments is
+// useful, previous calls are discarded. Be aware that not all PDF readers
+// support document attachments. See the SetAttachment example for a
+// demonstration of this method.
+func (f *Fpdf) SetAttachments(as []Attachment) {
+	f.attachments = as
+}
+
+// embed current attachments. store object numbers
+// for later use by getEmbeddedFiles()
+func (f *Fpdf) putAttachments() {
+	for i, a := range f.attachments {
+		f.embed(&a)
+		f.attachments[i] = a
+	}
+}
+
+// return /EmbeddedFiles tree name catalog entry.
+func (f Fpdf) getEmbeddedFiles() string {
+	names := make([]string, len(f.attachments))
+	for i, as := range f.attachments {
+		names[i] = fmt.Sprintf("(Attachement%d) %d 0 R ", i+1, as.objectNumber)
+	}
+	nameTree := fmt.Sprintf("<< /Names [\n %s \n] >>", strings.Join(names, "\n"))
+	return nameTree
+}
+
+// ---------------------------------- Annotations ----------------------------------
+
+type annotationAttach struct {
+	*Attachment
+
+	x, y, w, h float64 // fpdf coordinates (y diff and scaling done)
+}
+
+// AddAttachmentAnnotation puts a link on the current page, on the rectangle
+// defined by `x`, `y`, `w`, `h`. This link points towards the content defined
+// in `a`, which is embedded in the document. Note than no drawing is done by
+// this method : a method like `Cell()` or `Rect()` should be called to
+// indicate to the reader that there is a link here. Requiring a pointer to an
+// Attachment avoids useless copies in the resulting pdf: attachment pointing
+// to the same data will have their content only be included once, and be
+// shared amongst all links. Be aware that not all PDF readers support
+// annotated attachments. See the AddAttachmentAnnotation example for a
+// demonstration of this method.
+func (f *Fpdf) AddAttachmentAnnotation(a *Attachment, x, y, w, h float64) {
+	if a == nil {
+		return
+	}
+	f.pageAttachments[f.page] = append(f.pageAttachments[f.page], annotationAttach{
+		Attachment: a,
+		x:          x * f.k, y: f.hPt - y*f.k, w: w * f.k, h: h * f.k,
+	})
+}
+
+// embed current annotations attachments. store object numbers
+// for later use by putAttachmentAnnotationLinks(), which is
+// called for each page.
+func (f *Fpdf) putAnnotationsAttachments() {
+	// avoid duplication
+	m := map[*Attachment]bool{}
+	for _, l := range f.pageAttachments {
+		for _, an := range l {
+			if m[an.Attachment] { // already embedded
+				continue
+			}
+			f.embed(an.Attachment)
+		}
+	}
+}
+
+func (f *Fpdf) putAttachmentAnnotationLinks(out *fmtBuffer, page int) {
+	for _, an := range f.pageAttachments[page] {
+		x1, y1, x2, y2 := an.x, an.y, an.x+an.w, an.y-an.h
+		as := fmt.Sprintf("<< /Type /XObject /Subtype /Form /BBox [%.2f %.2f %.2f %.2f] /Length 0 >>",
+			x1, y1, x2, y2)
+		as += "\nstream\nendstream"
+
+		out.printf("<< /Type /Annot /Subtype /FileAttachment /Rect [%.2f %.2f %.2f %.2f] /Border [0 0 0]\n",
+			x1, y1, x2, y2)
+		out.printf("/Contents %s ", f.textstring(utf8toutf16(an.Description)))
+		out.printf("/T %s ", f.textstring(utf8toutf16(an.Filename)))
+		out.printf("/AP << /N %s>>", as)
+		out.printf("/FS %d 0 R >>\n", an.objectNumber)
+	}
+}

+ 146 - 0
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, printDiff bool) (eq bool) {
+	eq = bytes.Equal(sl1, sl2)
+	if !eq && printDiff {
+		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, printDiff bool) (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], printDiff) {
+			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, printDiff bool) (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(), printDiff)
+		}
+	}
+	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, printDiff bool) (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, printDiff)
+		} else {
+			// Second file is missing; treat this as success
+			err = nil
+		}
+	}
+	return
+}

+ 302 - 0
contrib/barcode/barcode.go

@@ -0,0 +1,302 @@
+// 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"
+	"image/jpeg"
+	"io"
+	"strconv"
+	"sync"
+
+	"github.com/boombuler/barcode"
+	"github.com/boombuler/barcode/aztec"
+	"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"
+)
+
+// 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)
+}
+
+// printBarcode internally prints the scaled or unscaled barcode to the PDF. Used by both
+// Barcode() and BarcodeUnscalable().
+func printBarcode(pdf barcodePdf, code string, x, y float64, 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)
+	scaleToWidth := unscaled.Bounds().Dx()
+	scaleToHeight := unscaled.Bounds().Dy()
+
+	if info == nil {
+		bcode, err := barcode.Scale(
+			unscaled,
+			scaleToWidth,
+			scaleToHeight,
+		)
+
+		if err != nil {
+			pdf.SetError(err)
+			return
+		}
+
+		err = registerScaledBarcode(pdf, bname, bcode)
+		if err != nil {
+			pdf.SetError(err)
+			return
+		}
+	}
+
+	scaleToWidthF := float64(scaleToWidth)
+	scaleToHeightF := float64(scaleToHeight)
+
+	if w != nil {
+		scaleToWidthF = *w
+	}
+	if h != nil {
+		scaleToHeightF = *h
+	}
+
+	pdf.Image(bname, x, y, scaleToWidthF, scaleToHeightF, flow, "jpg", 0, "")
+
+}
+
+// BarcodeUnscalable puts a registered barcode in the current page.
+//
+// Its arguments work in the same way as that of Barcode(). However, it allows for an unscaled
+// barcode in the width and/or height dimensions. This can be useful if you want to prevent
+// side effects of upscaling.
+func BarcodeUnscalable(pdf barcodePdf, code string, x, y float64, w, h *float64, flow bool) {
+	printBarcode(pdf, code, x, y, w, h, flow)
+}
+
+// Barcode puts a registered barcode in the current page.
+//
+// The size should be specified in the units used to create the PDF document.
+// If width or height are left unspecfied, the barcode is not scaled in the unspecified dimensions.
+//
+// Positioning with x, y and flow is inherited from Fpdf.Image().
+func Barcode(pdf barcodePdf, code string, x, y, w, h float64, flow bool) {
+	printBarcode(pdf, code, x, y, &w, &h, flow)
+}
+
+// GetUnscaledBarcodeDimensions returns the width and height of the
+// unscaled barcode associated with the given code.
+func GetUnscaledBarcodeDimensions(pdf barcodePdf, code string) (w, h float64) {
+	barcodes.Lock()
+	unscaled, ok := barcodes.cache[code]
+	barcodes.Unlock()
+
+	if !ok {
+		err := errors.New("Barcode not found")
+		pdf.SetError(err)
+		return
+	}
+
+	return convertFrom96Dpi(pdf, float64(unscaled.Bounds().Dx())),
+		convertFrom96Dpi(pdf, float64(unscaled.Bounds().Dy()))
+}
+
+// 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
+}
+
+// RegisterAztec registers a barcode of type Aztec to the PDF, but not to
+// the page. Use Barcode() with the return value to put the barcode on the page.
+// code is the string to be encoded. minECCPercent is the error correction percentage. 33 is the default.
+// userSpecifiedLayers can be a value between -4 and 32 inclusive.
+func RegisterAztec(pdf barcodePdf, code string, minECCPercent int, userSpecifiedLayers int) string {
+	bcode, err := aztec.Encode([]byte(code), minECCPercent, userSpecifiedLayers)
+	return registerBarcode(pdf, bcode, err)
+}
+
+// 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 ""
+	}
+
+	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
+}
+
+// convertFrom96Dpi converts the given value, which is based on a 96 DPI value
+// required for an Image, to a 72 DPI value like the rest of the PDF document.
+func convertFrom96Dpi(pdf barcodePdf, value float64) float64 {
+	return value / pdf.GetConversionRatio() * 72 / 96
+}

+ 222 - 0
contrib/barcode/barcode_test.go

@@ -0,0 +1,222 @@
+package barcode_test
+
+import (
+	"testing"
+
+	"github.com/boombuler/barcode/code128"
+	"github.com/boombuler/barcode/qr"
+	"github.com/jung-kurt/gofpdf"
+	"github.com/jung-kurt/gofpdf/contrib/barcode"
+	"github.com/jung-kurt/gofpdf/internal/example"
+)
+
+func createPdf() (pdf *gofpdf.Fpdf) {
+	pdf = gofpdf.New("L", "mm", "A4", "")
+	pdf.SetFont("Helvetica", "", 12)
+	pdf.SetFillColor(200, 200, 220)
+	pdf.AddPage()
+	return
+}
+
+func ExampleRegister() {
+	pdf := createPdf()
+
+	fileStr := example.Filename("contrib_barcode_Register")
+
+	bcode, err := code128.Encode("gofpdf")
+
+	if err == nil {
+		key := barcode.Register(bcode)
+		var width float64 = 100
+		var height float64 = 10.0
+		barcode.BarcodeUnscalable(pdf, key, 15, 15, &width, &height, false)
+	}
+
+	err = pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated ../../pdf/contrib_barcode_Register.pdf
+}
+
+func ExampleRegisterCodabar() {
+	pdf := createPdf()
+
+	key := barcode.RegisterCode128(pdf, "codabar")
+	var width float64 = 100
+	var height float64 = 10
+	barcode.BarcodeUnscalable(pdf, key, 15, 15, &width, &height, false)
+
+	fileStr := example.Filename("contrib_barcode_RegisterCodabar")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated ../../pdf/contrib_barcode_RegisterCodabar.pdf
+}
+
+func ExampleRegisterAztec() {
+	pdf := createPdf()
+
+	key := barcode.RegisterAztec(pdf, "aztec", 33, 0)
+	barcode.Barcode(pdf, key, 15, 15, 100, 100, false)
+
+	fileStr := example.Filename("contrib_barcode_RegisterAztec")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated ../../pdf/contrib_barcode_RegisterAztec.pdf
+}
+
+func ExampleRegisterCode128() {
+	pdf := createPdf()
+
+	key := barcode.RegisterCode128(pdf, "code128")
+	barcode.Barcode(pdf, key, 15, 15, 100, 10, false)
+
+	fileStr := example.Filename("contrib_barcode_RegisterCode128")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated ../../pdf/contrib_barcode_RegisterCode128.pdf
+}
+
+func ExampleRegisterCode39() {
+	pdf := createPdf()
+
+	key := barcode.RegisterCode39(pdf, "CODE39", false, true)
+	barcode.Barcode(pdf, key, 15, 15, 100, 10, false)
+
+	fileStr := example.Filename("contrib_barcode_RegisterCode39")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated ../../pdf/contrib_barcode_RegisterCode39.pdf
+}
+
+func ExampleRegisterDataMatrix() {
+	pdf := createPdf()
+
+	key := barcode.RegisterDataMatrix(pdf, "datamatrix")
+	barcode.Barcode(pdf, key, 15, 15, 20, 20, false)
+
+	fileStr := example.Filename("contrib_barcode_RegisterDataMatrix")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated ../../pdf/contrib_barcode_RegisterDataMatrix.pdf
+}
+
+func ExampleRegisterEAN() {
+	pdf := createPdf()
+
+	key := barcode.RegisterEAN(pdf, "96385074")
+	barcode.Barcode(pdf, key, 15, 15, 100, 10, false)
+
+	fileStr := example.Filename("contrib_barcode_RegisterEAN")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated ../../pdf/contrib_barcode_RegisterEAN.pdf
+}
+
+func ExampleRegisterQR() {
+	pdf := createPdf()
+
+	key := barcode.RegisterQR(pdf, "qrcode", qr.H, qr.Unicode)
+	barcode.Barcode(pdf, key, 15, 15, 100, 10, false)
+
+	fileStr := example.Filename("contrib_barcode_RegisterQR")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated ../../pdf/contrib_barcode_RegisterQR.pdf
+}
+
+func ExampleRegisterTwoOfFive() {
+	pdf := createPdf()
+
+	key := barcode.RegisterTwoOfFive(pdf, "1234567895", true)
+	barcode.Barcode(pdf, key, 15, 15, 100, 10, false)
+
+	fileStr := example.Filename("contrib_barcode_RegisterTwoOfFive")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated ../../pdf/contrib_barcode_RegisterTwoOfFive.pdf
+}
+
+func ExampleRegisterPdf417() {
+	pdf := createPdf()
+
+	key := barcode.RegisterPdf417(pdf, "1234567895", 10, 5)
+	barcode.Barcode(pdf, key, 15, 15, 100, 10, false)
+
+	fileStr := example.Filename("contrib_barcode_RegisterPdf417")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated ../../pdf/contrib_barcode_RegisterPdf417.pdf
+}
+
+// TestRegisterCode128 ensures that no panic arises when an invalid barcode is registered.
+func TestRegisterCode128(t *testing.T) {
+	pdf := createPdf()
+	barcode.RegisterCode128(pdf, "Invalid character: é")
+}
+
+// TestBarcodeUnscalable shows that the barcode may be scaled or not by providing optional heights and widths.
+func TestBarcodeUnscalable(t *testing.T) {
+	pdf := createPdf()
+
+	key := barcode.RegisterCode128(pdf, "code128")
+	var width float64 = 100
+	var height float64 = 10
+	barcode.BarcodeUnscalable(pdf, key, 15, 15, &width, &height, false)
+	barcode.BarcodeUnscalable(pdf, key, 15, 35, nil, &height, false)
+	barcode.BarcodeUnscalable(pdf, key, 15, 55, &width, nil, false)
+	barcode.BarcodeUnscalable(pdf, key, 15, 75, nil, nil, false)
+
+	fileStr := example.Filename("contrib_barcode_Barcode")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated ../../pdf/contrib_barcode_Barcode.pdf
+}
+
+// TestGetUnscaledBarcodeDimensions shows that the width and height returned by the function match that of the barcode
+func TestGetUnscaledBarcodeDimensions(t *testing.T) {
+	pdf := createPdf()
+
+	key := barcode.RegisterQR(pdf, "qrcode", qr.H, qr.Unicode)
+	barcode.BarcodeUnscalable(pdf, key, 15, 15, nil, nil, false)
+	w, h := barcode.GetUnscaledBarcodeDimensions(pdf, key)
+
+	pdf.SetDrawColor(255, 0, 0)
+	pdf.Line(15, 15, 15+w, 15+h)
+
+	fileStr := example.Filename("contrib_barcode_GetBarcodeDimensions")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated ../../pdf/contrib_barcode_GetBarcodeDimensions.pdf
+}
+
+// TestBarcodeNonIntegerScalingFactors shows that the barcode may be scaled to non-integer sizes
+func TestBarcodeNonIntegerScalingFactors(t *testing.T) {
+	pdf := gofpdf.New("L", "in", "A4", "")
+	pdf.SetFont("Helvetica", "", 12)
+	pdf.SetFillColor(200, 200, 220)
+	pdf.AddPage()
+
+	key := barcode.RegisterQR(pdf, "qrcode", qr.H, qr.Unicode)
+	var scale float64 = 1.5
+	barcode.BarcodeUnscalable(pdf, key, 0.5, 0.5, &scale, &scale, false)
+
+	pdf.SetDrawColor(255, 0, 0)
+	pdf.Line(0.5, 0.5, 0.5+scale, 0.5+scale)
+
+	fileStr := example.Filename("contrib_barcode_BarcodeScaling")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated ../../pdf/contrib_barcode_BarcodeScaling.pdf
+}

+ 68 - 0
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")
+}

+ 143 - 0
contrib/gofpdi/gofpdi.go

@@ -0,0 +1,143 @@
+/*
+Package gofpdi wraps the gofpdi PDF library to import existing PDFs as templates. See github.com/phpdave11/gofpdi
+for further information and examples.
+
+Users should call NewImporter() to obtain their own Importer instance to work with.
+To retain backwards compatibility, the package offers a default Importer that may be used via global functions. Note
+however that use of the default Importer is not thread safe.
+*/
+package gofpdi
+
+import (
+	realgofpdi "github.com/phpdave11/gofpdi"
+	"io"
+)
+
+// gofpdiPdf is a partial interface that only implements the functions we need
+// from the PDF generator to put the imported PDF templates on the PDF.
+type gofpdiPdf interface {
+	ImportObjects(objs map[string][]byte)
+	ImportObjPos(objs map[string]map[int]string)
+	ImportTemplates(tpls map[string]string)
+	UseImportedTemplate(tplName string, x float64, y float64, w float64, h float64)
+	SetError(err error)
+}
+
+// Importer wraps an Importer from the gofpdi library.
+type Importer struct {
+	fpdi *realgofpdi.Importer
+}
+
+// NewImporter creates a new Importer wrapping functionality from the gofpdi library.
+func NewImporter() *Importer {
+	return &Importer{
+		fpdi: realgofpdi.NewImporter(),
+	}
+}
+
+// ImportPage imports a page of a PDF file with the specified box (/MediaBox,
+// /TrimBox, /ArtBox, /CropBox, or /BleedBox). Returns a template id that can
+// be used with UseImportedTemplate to draw the template onto the page.
+func (i *Importer) ImportPage(f gofpdiPdf, sourceFile string, pageno int, box string) int {
+	// Set source file for fpdi
+	i.fpdi.SetSourceFile(sourceFile)
+	// return template id
+	return i.getTemplateID(f, pageno, box)
+}
+
+// ImportPageFromStream imports a page of a PDF with the specified box
+// (/MediaBox, TrimBox, /ArtBox, /CropBox, or /BleedBox). Returns a template id
+// that can be used with UseImportedTemplate to draw the template onto the
+// page.
+func (i *Importer) ImportPageFromStream(f gofpdiPdf, rs *io.ReadSeeker, pageno int, box string) int {
+	// Set source stream for fpdi
+	i.fpdi.SetSourceStream(rs)
+	// return template id
+	return i.getTemplateID(f, pageno, box)
+}
+
+func (i *Importer) getTemplateID(f gofpdiPdf, pageno int, box string) int {
+	// Import page
+	tpl := i.fpdi.ImportPage(pageno, box)
+
+	// Import objects into current pdf document
+	// Unordered means that the objects will be returned with a sha1 hash instead of an integer
+	// The objects themselves may have references to other hashes which will be replaced in ImportObjects()
+	tplObjIDs := i.fpdi.PutFormXobjectsUnordered()
+
+	// Set template names and ids (hashes) in gofpdf
+	f.ImportTemplates(tplObjIDs)
+
+	// Get a map[string]string of the imported objects.
+	// The map keys will be the ID of each object.
+	imported := i.fpdi.GetImportedObjectsUnordered()
+
+	// Import gofpdi objects into gofpdf
+	f.ImportObjects(imported)
+
+	// Get a map[string]map[int]string of the object hashes and their positions within each object,
+	// to be replaced with object ids (integers).
+	importedObjPos := i.fpdi.GetImportedObjHashPos()
+
+	// Import gofpdi object hashes and their positions into gopdf
+	f.ImportObjPos(importedObjPos)
+
+	return tpl
+}
+
+// UseImportedTemplate draws the template onto the page at x,y. If w is 0, the
+// template will be scaled to fit based on h. If h is 0, the template will be
+// scaled to fit based on w.
+func (i *Importer) UseImportedTemplate(f gofpdiPdf, tplid int, x float64, y float64, w float64, h float64) {
+	// Get values from fpdi
+	tplName, scaleX, scaleY, tX, tY := i.fpdi.UseTemplate(tplid, x, y, w, h)
+
+	f.UseImportedTemplate(tplName, scaleX, scaleY, tX, tY)
+}
+
+// GetPageSizes returns page dimensions for all pages of the imported pdf.
+// Result consists of map[<page number>]map[<box>]map[<dimension>]<value>.
+// <page number>: page number, note that page numbers start at 1
+// <box>: box identifier, e.g. "/MediaBox"
+// <dimension>: dimension string, either "w" or "h"
+func (i *Importer) GetPageSizes() map[int]map[string]map[string]float64 {
+	return i.fpdi.GetPageSizes()
+}
+
+// Default Importer used by global functions
+var fpdi = NewImporter()
+
+// ImportPage imports a page of a PDF file with the specified box (/MediaBox,
+// /TrimBox, /ArtBox, /CropBox, or /BleedBox). Returns a template id that can
+// be used with UseImportedTemplate to draw the template onto the page.
+// Note: This uses the default Importer. Call NewImporter() to obtain a custom Importer.
+func ImportPage(f gofpdiPdf, sourceFile string, pageno int, box string) int {
+	return fpdi.ImportPage(f, sourceFile, pageno, box)
+}
+
+// ImportPageFromStream imports a page of a PDF with the specified box
+// (/MediaBox, TrimBox, /ArtBox, /CropBox, or /BleedBox). Returns a template id
+// that can be used with UseImportedTemplate to draw the template onto the
+// page.
+// Note: This uses the default Importer. Call NewImporter() to obtain a custom Importer.
+func ImportPageFromStream(f gofpdiPdf, rs *io.ReadSeeker, pageno int, box string) int {
+	return fpdi.ImportPageFromStream(f, rs, pageno, box)
+}
+
+// UseImportedTemplate draws the template onto the page at x,y. If w is 0, the
+// template will be scaled to fit based on h. If h is 0, the template will be
+// scaled to fit based on w.
+// Note: This uses the default Importer. Call NewImporter() to obtain a custom Importer.
+func UseImportedTemplate(f gofpdiPdf, tplid int, x float64, y float64, w float64, h float64) {
+	fpdi.UseImportedTemplate(f, tplid, x, y, w, h)
+}
+
+// GetPageSizes returns page dimensions for all pages of the imported pdf.
+// Result consists of map[<page number>]map[<box>]map[<dimension>]<value>.
+// <page number>: page number, note that page numbers start at 1
+// <box>: box identifier, e.g. "/MediaBox"
+// <dimension>: dimension string, either "w" or "h"
+// Note: This uses the default Importer. Call NewImporter() to obtain a custom Importer.
+func GetPageSizes() map[int]map[string]map[string]float64 {
+	return fpdi.GetPageSizes()
+}

+ 76 - 0
contrib/gofpdi/gofpdi_test.go

@@ -0,0 +1,76 @@
+package gofpdi
+
+import (
+	"bytes"
+	"github.com/jung-kurt/gofpdf"
+	"github.com/jung-kurt/gofpdf/internal/example"
+	"io"
+	"sync"
+	"testing"
+)
+
+func ExampleNewImporter() {
+	// create new pdf
+	pdf := gofpdf.New("P", "pt", "A4", "")
+
+	// for testing purposes, get an arbitrary template pdf as stream
+	rs, _ := getTemplatePdf()
+
+	// create a new Importer instance
+	imp := NewImporter()
+
+	// import first page and determine page sizes
+	tpl := imp.ImportPageFromStream(pdf, &rs, 1, "/MediaBox")
+	pageSizes := imp.GetPageSizes()
+	nrPages := len(imp.GetPageSizes())
+
+	// add all pages from template pdf
+	for i := 1; i <= nrPages; i++ {
+		pdf.AddPage()
+		if i > 1 {
+			tpl = imp.ImportPageFromStream(pdf, &rs, i, "/MediaBox")
+		}
+		imp.UseImportedTemplate(pdf, tpl, 0, 0, pageSizes[i]["/MediaBox"]["w"], pageSizes[i]["/MediaBox"]["h"])
+	}
+
+	// output
+	fileStr := example.Filename("contrib_gofpdi_Importer")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated ../../pdf/contrib_gofpdi_Importer.pdf
+}
+
+func TestGofpdiConcurrent(t *testing.T) {
+	wg := sync.WaitGroup{}
+	for i := 0; i < 100; i++ {
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			pdf := gofpdf.New("P", "mm", "A4", "")
+			pdf.AddPage()
+			rs, _ := getTemplatePdf()
+			imp := NewImporter()
+			tpl := imp.ImportPageFromStream(pdf, &rs, 1, "/MediaBox")
+			imp.UseImportedTemplate(pdf, tpl, 0, 0, 210.0, 297.0)
+			// write to bytes buffer
+			buf := bytes.Buffer{}
+			if err := pdf.Output(&buf); err != nil {
+				t.Fail()
+			}
+		}()
+	}
+	wg.Wait()
+}
+
+func getTemplatePdf() (io.ReadSeeker, error) {
+	tpdf := gofpdf.New("P", "pt", "A4", "")
+	tpdf.AddPage()
+	tpdf.SetFont("Arial", "", 12)
+	tpdf.Text(20, 20, "Example Page 1")
+	tpdf.AddPage()
+	tpdf.Text(20, 20, "Example Page 2")
+	tbuf := bytes.Buffer{}
+	err := tpdf.Output(&tbuf)
+	return bytes.NewReader(tbuf.Bytes()), err
+}

+ 43 - 0
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)
+}

+ 23 - 0
contrib/httpimg/httpimg_test.go

@@ -0,0 +1,23 @@
+package httpimg_test
+
+import (
+	"github.com/jung-kurt/gofpdf"
+	"github.com/jung-kurt/gofpdf/contrib/httpimg"
+	"github.com/jung-kurt/gofpdf/internal/example"
+)
+
+func ExampleRegister() {
+	pdf := gofpdf.New("L", "mm", "A4", "")
+	pdf.SetFont("Helvetica", "", 12)
+	pdf.SetFillColor(200, 200, 220)
+	pdf.AddPage()
+
+	url := "https://github.com/jung-kurt/gofpdf/raw/master/image/logo_gofpdf.jpg?raw=true"
+	httpimg.Register(pdf, url, "")
+	pdf.Image(url, 15, 15, 267, 0, false, "", 0, "")
+	fileStr := example.Filename("contrib_httpimg_Register")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated ../../pdf/contrib_httpimg_Register.pdf
+}

+ 83 - 0
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
+}

+ 23 - 0
contrib/tiff/tiff_test.go

@@ -0,0 +1,23 @@
+package tiff_test
+
+import (
+	"github.com/jung-kurt/gofpdf"
+	"github.com/jung-kurt/gofpdf/contrib/tiff"
+	"github.com/jung-kurt/gofpdf/internal/example"
+)
+
+// ExampleRegisterFile demonstrates the loading and display of a TIFF image.
+func ExampleRegisterFile() {
+	pdf := gofpdf.New("L", "mm", "A4", "")
+	pdf.SetFont("Helvetica", "", 12)
+	pdf.SetFillColor(200, 200, 220)
+	pdf.AddPageFormat("L", gofpdf.SizeType{Wd: 200, Ht: 200})
+	opt := gofpdf.ImageOptions{ImageType: "tiff", ReadDpi: false}
+	_ = tiff.RegisterFile(pdf, "sample", opt, "../../image/golang-gopher.tiff")
+	pdf.Image("sample", 0, 0, 200, 200, false, "", 0, "")
+	fileStr := example.Filename("Fpdf_Contrib_Tiff")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated ../../pdf/Fpdf_Contrib_Tiff.pdf
+}

+ 738 - 0
def.go

@@ -0,0 +1,738 @@
+/*
+ * 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"
+	"crypto/sha1"
+	"encoding/gob"
+	"encoding/json"
+	"fmt"
+	"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
+}
+
+const (
+	// OrientationPortrait represents the portrait orientation.
+	OrientationPortrait = "portrait"
+
+	// OrientationLandscape represents the landscape orientation.
+	OrientationLandscape = "landscape"
+)
+
+const (
+	// UnitPoint represents the size unit point
+	UnitPoint = "pt"
+	// UnitMillimeter represents the size unit millimeter
+	UnitMillimeter = "mm"
+	// UnitCentimeter represents the size unit centimeter
+	UnitCentimeter = "cm"
+	// UnitInch represents the size unit inch
+	UnitInch = "inch"
+)
+
+const (
+	// PageSizeA3 represents DIN/ISO A3 page size
+	PageSizeA3 = "A3"
+	// PageSizeA4 represents DIN/ISO A4 page size
+	PageSizeA4 = "A4"
+	// PageSizeA5 represents DIN/ISO A5 page size
+	PageSizeA5 = "A5"
+	// PageSizeLetter represents US Letter page size
+	PageSizeLetter = "Letter"
+	// PageSizeLegal represents US Legal page size
+	PageSizeLegal = "Legal"
+)
+
+const (
+	// BorderNone set no border
+	BorderNone = ""
+	// BorderFull sets a full border
+	BorderFull = "1"
+	// BorderLeft sets the border on the left side
+	BorderLeft = "L"
+	// BorderTop sets the border at the top
+	BorderTop = "T"
+	// BorderRight sets the border on the right side
+	BorderRight = "R"
+	// BorderBottom sets the border on the bottom
+	BorderBottom = "B"
+)
+
+const (
+	// LineBreakNone disables linebreak
+	LineBreakNone = 0
+	// LineBreakNormal enables normal linebreak
+	LineBreakNormal = 1
+	// LineBreakBelow enables linebreak below
+	LineBreakBelow = 2
+)
+
+const (
+	// AlignLeft left aligns the cell
+	AlignLeft = "L"
+	// AlignRight right aligns the cell
+	AlignRight = "R"
+	// AlignCenter centers the cell
+	AlignCenter = "C"
+	// AlignTop aligns the cell to the top
+	AlignTop = "T"
+	// AlignBottom aligns the cell to the bottom
+	AlignBottom = "B"
+	// AlignMiddle aligns the cell to the middle
+	AlignMiddle = "M"
+	// AlignBaseline aligns the cell to the baseline
+	AlignBaseline = "B"
+)
+
+type colorMode int
+
+const (
+	colorModeRGB colorMode = iota
+	colorModeSpot
+	colorModeCMYK
+)
+
+type colorType struct {
+	r, g, b    float64
+	ir, ig, ib int
+	mode       colorMode
+	spotStr    string // name of current spot color
+	gray       bool
+	str        string
+}
+
+// SpotColorType specifies a named spot color value
+type spotColorType struct {
+	id, objID int
+	val       cmykColorType
+}
+
+// CMYKColorType specifies an ink-based CMYK color value
+type cmykColorType struct {
+	c, m, y, k byte // 0% to 100%
+}
+
+// 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.
+// Changes to this structure should be reflected in its GobEncode and GobDecode
+// methods.
+type ImageInfoType struct {
+	data  []byte  // Raw image data
+	smask []byte  // Soft Mask, an 8bit per-pixel transparency mask
+	n     int     // Image object number
+	w     float64 // Width
+	h     float64 // Height
+	cs    string  // Color space
+	pal   []byte  // Image color palette
+	bpc   int     // Bits Per Component
+	f     string  // Image filter
+	dp    string  // DecodeParms
+	trns  []int   // Transparency mask
+	scale float64 // Document scale factor
+	dpi   float64 // Dots-per-inch found from image file (png only)
+	i     string  // SHA-1 checksum of the above values.
+}
+
+func generateImageID(info *ImageInfoType) (string, error) {
+	b, err := info.GobEncode()
+	return fmt.Sprintf("%x", sha1.Sum(b)), err
+}
+
+// GobEncode encodes the receiving image to a byte slice.
+func (info *ImageInfoType) GobEncode() (buf []byte, err error) {
+	fields := []interface{}{info.data, info.smask, info.n, info.w, info.h, info.cs,
+		info.pal, info.bpc, info.f, info.dp, info.trns, info.scale, info.dpi}
+	w := new(bytes.Buffer)
+	encoder := gob.NewEncoder(w)
+	for j := 0; j < len(fields) && err == nil; j++ {
+		err = encoder.Encode(fields[j])
+	}
+	if err == nil {
+		buf = w.Bytes()
+	}
+	return
+}
+
+// GobDecode decodes the specified byte buffer (generated by GobEncode) into
+// the receiving image.
+func (info *ImageInfoType) GobDecode(buf []byte) (err error) {
+	fields := []interface{}{&info.data, &info.smask, &info.n, &info.w, &info.h,
+		&info.cs, &info.pal, &info.bpc, &info.f, &info.dp, &info.trns, &info.scale, &info.dpi}
+	r := bytes.NewBuffer(buf)
+	decoder := gob.NewDecoder(r)
+	for j := 0; j < len(fields) && err == nil; j++ {
+		err = decoder.Decode(fields[j])
+	}
+
+	info.i, err = generateImageID(info)
+	return
+}
+
+// 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
+	fontType         string
+}
+
+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)
+}
+
+// Pdf defines the interface used for various methods. It is implemented by the
+// main FPDF instance as well as templates.
+type Pdf interface {
+	AddFont(familyStr, styleStr, fileStr string)
+	AddFontFromBytes(familyStr, styleStr string, jsonFileBytes, zFileBytes []byte)
+	AddFontFromReader(familyStr, styleStr string, r io.Reader)
+	AddLayer(name string, visible bool) (layerID int)
+	AddLink() int
+	AddPage()
+	AddPageFormat(orientationStr string, size SizeType)
+	AddSpotColor(nameStr string, c, m, y, k byte)
+	AliasNbPages(aliasStr string)
+	ArcTo(x, y, rx, ry, degRotate, degStart, degEnd float64)
+	Arc(x, y, rx, ry, degRotate, degStart, degEnd float64, styleStr string)
+	BeginLayer(id int)
+	Beziergon(points []PointType, styleStr string)
+	Bookmark(txtStr string, level int, y float64)
+	CellFormat(w, h float64, txtStr, borderStr string, ln int, alignStr string, fill bool, link int, linkStr string)
+	Cellf(w, h float64, fmtStr string, args ...interface{})
+	Cell(w, h float64, txtStr string)
+	Circle(x, y, r float64, styleStr string)
+	ClearError()
+	ClipCircle(x, y, r float64, outline bool)
+	ClipEllipse(x, y, rx, ry float64, outline bool)
+	ClipEnd()
+	ClipPolygon(points []PointType, outline bool)
+	ClipRect(x, y, w, h float64, outline bool)
+	ClipRoundedRect(x, y, w, h, r float64, outline bool)
+	ClipText(x, y float64, txtStr string, outline bool)
+	Close()
+	ClosePath()
+	CreateTemplateCustom(corner PointType, size SizeType, fn func(*Tpl)) Template
+	CreateTemplate(fn func(*Tpl)) Template
+	CurveBezierCubicTo(cx0, cy0, cx1, cy1, x, y float64)
+	CurveBezierCubic(x0, y0, cx0, cy0, cx1, cy1, x1, y1 float64, styleStr string)
+	CurveCubic(x0, y0, cx0, cy0, x1, y1, cx1, cy1 float64, styleStr string)
+	CurveTo(cx, cy, x, y float64)
+	Curve(x0, y0, cx, cy, x1, y1 float64, styleStr string)
+	DrawPath(styleStr string)
+	Ellipse(x, y, rx, ry, degRotate float64, styleStr string)
+	EndLayer()
+	Err() bool
+	Error() error
+	GetAlpha() (alpha float64, blendModeStr string)
+	GetAutoPageBreak() (auto bool, margin float64)
+	GetCellMargin() float64
+	GetConversionRatio() float64
+	GetDrawColor() (int, int, int)
+	GetDrawSpotColor() (name string, c, m, y, k byte)
+	GetFillColor() (int, int, int)
+	GetFillSpotColor() (name string, c, m, y, k byte)
+	GetFontDesc(familyStr, styleStr string) FontDescType
+	GetFontSize() (ptSize, unitSize float64)
+	GetImageInfo(imageStr string) (info *ImageInfoType)
+	GetLineWidth() float64
+	GetMargins() (left, top, right, bottom float64)
+	GetPageSizeStr(sizeStr string) (size SizeType)
+	GetPageSize() (width, height float64)
+	GetStringWidth(s string) float64
+	GetTextColor() (int, int, int)
+	GetTextSpotColor() (name string, c, m, y, k byte)
+	GetX() float64
+	GetXY() (float64, float64)
+	GetY() float64
+	HTMLBasicNew() (html HTMLBasicType)
+	Image(imageNameStr string, x, y, w, h float64, flow bool, tp string, link int, linkStr string)
+	ImageOptions(imageNameStr string, x, y, w, h float64, flow bool, options ImageOptions, link int, linkStr string)
+	ImageTypeFromMime(mimeStr string) (tp string)
+	LinearGradient(x, y, w, h float64, r1, g1, b1, r2, g2, b2 int, x1, y1, x2, y2 float64)
+	LineTo(x, y float64)
+	Line(x1, y1, x2, y2 float64)
+	LinkString(x, y, w, h float64, linkStr string)
+	Link(x, y, w, h float64, link int)
+	Ln(h float64)
+	MoveTo(x, y float64)
+	MultiCell(w, h float64, txtStr, borderStr, alignStr string, fill bool)
+	Ok() bool
+	OpenLayerPane()
+	OutputAndClose(w io.WriteCloser) error
+	OutputFileAndClose(fileStr string) error
+	Output(w io.Writer) error
+	PageCount() int
+	PageNo() int
+	PageSize(pageNum int) (wd, ht float64, unitStr string)
+	PointConvert(pt float64) (u float64)
+	PointToUnitConvert(pt float64) (u float64)
+	Polygon(points []PointType, styleStr string)
+	RadialGradient(x, y, w, h float64, r1, g1, b1, r2, g2, b2 int, x1, y1, x2, y2, r float64)
+	RawWriteBuf(r io.Reader)
+	RawWriteStr(str string)
+	Rect(x, y, w, h float64, styleStr string)
+	RegisterAlias(alias, replacement string)
+	RegisterImage(fileStr, tp string) (info *ImageInfoType)
+	RegisterImageOptions(fileStr string, options ImageOptions) (info *ImageInfoType)
+	RegisterImageOptionsReader(imgName string, options ImageOptions, r io.Reader) (info *ImageInfoType)
+	RegisterImageReader(imgName, tp string, r io.Reader) (info *ImageInfoType)
+	SetAcceptPageBreakFunc(fnc func() bool)
+	SetAlpha(alpha float64, blendModeStr string)
+	SetAuthor(authorStr string, isUTF8 bool)
+	SetAutoPageBreak(auto bool, margin float64)
+	SetCatalogSort(flag bool)
+	SetCellMargin(margin float64)
+	SetCompression(compress bool)
+	SetCreationDate(tm time.Time)
+	SetCreator(creatorStr string, isUTF8 bool)
+	SetDashPattern(dashArray []float64, dashPhase float64)
+	SetDisplayMode(zoomStr, layoutStr string)
+	SetDrawColor(r, g, b int)
+	SetDrawSpotColor(nameStr string, tint byte)
+	SetError(err error)
+	SetErrorf(fmtStr string, args ...interface{})
+	SetFillColor(r, g, b int)
+	SetFillSpotColor(nameStr string, tint byte)
+	SetFont(familyStr, styleStr string, size float64)
+	SetFontLoader(loader FontLoader)
+	SetFontLocation(fontDirStr string)
+	SetFontSize(size float64)
+	SetFontStyle(styleStr string)
+	SetFontUnitSize(size float64)
+	SetFooterFunc(fnc func())
+	SetFooterFuncLpi(fnc func(lastPage bool))
+	SetHeaderFunc(fnc func())
+	SetHeaderFuncMode(fnc func(), homeMode bool)
+	SetHomeXY()
+	SetJavascript(script string)
+	SetKeywords(keywordsStr string, isUTF8 bool)
+	SetLeftMargin(margin float64)
+	SetLineCapStyle(styleStr string)
+	SetLineJoinStyle(styleStr string)
+	SetLineWidth(width float64)
+	SetLink(link int, y float64, page int)
+	SetMargins(left, top, right float64)
+	SetPageBoxRec(t string, pb PageBox)
+	SetPageBox(t string, x, y, wd, ht float64)
+	SetPage(pageNum int)
+	SetProtection(actionFlag byte, userPassStr, ownerPassStr string)
+	SetRightMargin(margin float64)
+	SetSubject(subjectStr string, isUTF8 bool)
+	SetTextColor(r, g, b int)
+	SetTextSpotColor(nameStr string, tint byte)
+	SetTitle(titleStr string, isUTF8 bool)
+	SetTopMargin(margin float64)
+	SetUnderlineThickness(thickness float64)
+	SetXmpMetadata(xmpStream []byte)
+	SetX(x float64)
+	SetXY(x, y float64)
+	SetY(y float64)
+	SplitLines(txt []byte, w float64) [][]byte
+	String() string
+	SVGBasicWrite(sb *SVGBasicType, scale float64)
+	Text(x, y float64, txtStr string)
+	TransformBegin()
+	TransformEnd()
+	TransformMirrorHorizontal(x float64)
+	TransformMirrorLine(angle, x, y float64)
+	TransformMirrorPoint(x, y float64)
+	TransformMirrorVertical(y float64)
+	TransformRotate(angle, x, y float64)
+	TransformScale(scaleWd, scaleHt, x, y float64)
+	TransformScaleX(scaleWd, x, y float64)
+	TransformScaleXY(s, x, y float64)
+	TransformScaleY(scaleHt, x, y float64)
+	TransformSkew(angleX, angleY, x, y float64)
+	TransformSkewX(angleX, x, y float64)
+	TransformSkewY(angleY, x, y float64)
+	Transform(tm TransformMatrix)
+	TransformTranslate(tx, ty float64)
+	TransformTranslateX(tx float64)
+	TransformTranslateY(ty float64)
+	UnicodeTranslatorFromDescriptor(cpStr string) (rep func(string) string)
+	UnitToPointConvert(u float64) (pt float64)
+	UseTemplateScaled(t Template, corner PointType, size SizeType)
+	UseTemplate(t Template)
+	WriteAligned(width, lineHeight float64, textStr, alignStr string)
+	Writef(h float64, fmtStr string, args ...interface{})
+	Write(h float64, txtStr string)
+	WriteLinkID(h float64, displayStr string, linkID int)
+	WriteLinkString(h float64, displayStr, targetStr string)
+}
+
+// PageBox defines the coordinates and extent of the various page box types
+type PageBox struct {
+	SizeType
+	PointType
+}
+
+// Fpdf is the principal structure for creating a single PDF document
+type Fpdf struct {
+	isCurrentUTF8    bool                       // is current font used in utf-8 mode
+	isRTL            bool                       // is is right to left mode enabled
+	page             int                        // current page number
+	n                int                        // current object number
+	offsets          []int                      // array of object offsets
+	templates        map[string]Template        // templates used in this document
+	templateObjects  map[string]int             // template object IDs within this document
+	importedObjs     map[string][]byte          // imported template objects (gofpdi)
+	importedObjPos   map[string]map[int]string  // imported template objects hashes and their positions (gofpdi)
+	importedTplObjs  map[string]string          // imported template names and IDs (hashed) (gofpdi)
+	importedTplIDs   map[string]int             // imported template ids hash to object id int (gofpdi)
+	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
+	defPageBoxes     map[string]PageBox         // default page size
+	curPageSize      SizeType                   // current page size
+	pageSizes        map[int]SizeType           // used for pages with non default sizes or orientations
+	pageBoxes        map[int]map[string]PageBox // used to define the crop, trim, bleed and art boxes
+	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
+	strikeout        bool                       // strike out 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
+	aliasMap         map[string]string          // map of alias->replacement
+	pageLinks        [][]linkType               // pageLinks[page][link], both 1-based
+	links            []intLinkType              // array of internal links
+	attachments      []Attachment               // slice of content to embed globally
+	pageAttachments  [][]annotationAttach       // 1-based array of annotation for file attachments (per page)
+	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
+	headerHomeMode   bool                       // set position to home after headerFnc is called
+	inFooter         bool                       // flag set when processing footer
+	footerFnc        func()                     // function provided by app and called to write footer
+	footerFncLpi     func(bool)                 // function provided by app and called to write footer with last page flag
+	zoomMode         string                     // zoom display mode
+	layoutMode       string                     // layout display mode
+	xmp              []byte                     // XMP metadata
+	producer         string                     // producer
+	title            string                     // title
+	subject          string                     // subject
+	author           string                     // author
+	keywords         string                     // keywords
+	creator          string                     // creator
+	creationDate     time.Time                  // override for document CreationDate value
+	modDate          time.Time                  // override for document ModDate 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
+	nJs              int                        // JavaScript object number
+	javascript       *string                    // JavaScript code to include in the PDF
+	colorFlag        bool                       // indicates whether fill and text colors are different
+	color            struct {
+		// Composite values of colors
+		draw, fill, text colorType
+	}
+	spotColorMap           map[string]spotColorType // Map of named ink-based colors
+	userUnderlineThickness float64                  // A custom user underline thickness multiplier.
+}
+
+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           []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
+	N            int           // Set by font loader
+	DiffN        int           // Position of diff in app array, set by font loader
+	i            string        // 1-based position in font list, set by font loader, not this program
+	utf8File     *utf8FontFile // UTF-8 font
+	usedRunes    map[int]int   // Array of used runes
+}
+
+// generateFontID generates a font Id from the font definition
+func generateFontID(fdt fontDefType) (string, error) {
+	// file can be different if generated in different instance
+	fdt.File = ""
+	b, err := json.Marshal(&fdt)
+	return fmt.Sprintf("%x", sha1.Sum(b)), err
+}
+
+type fontInfoType struct {
+	Data               []byte
+	File               string
+	OriginalSize       int
+	FontName           string
+	Bold               bool
+	IsFixedPitch       bool
+	UnderlineThickness int
+	UnderlinePosition  int
+	Widths             []int
+	Size1, Size2       uint32
+	Desc               FontDescType
+}

+ 291 - 0
doc.go

@@ -0,0 +1,291 @@
+/*
+Package gofpdf implements a PDF document generator with high level
+support for text, drawing and images.
+
+
+Features
+
+
+-   UTF-8 support
+
+-   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
+
+-   Barcodes
+
+-   Charting facility
+
+-   Import PDFs as templates
+
+gofpdf has no dependencies other than the Go standard library. All tests
+pass on Linux, Mac and Windows platforms.
+
+gofpdf supports UTF-8 TrueType fonts and “right-to-left” languages. Note
+that Chinese, Japanese, and Korean characters may not be included in
+many general purpose fonts. For these languages, a specialized font (for
+example, NotoSansSC for simplified Chinese) can be used.
+
+Also, support is provided to automatically translate UTF-8 runes to code
+page encodings for languages that have fewer than 256 glyphs.
+
+
+We Are Closed
+
+This repository will not be maintained, at least for some unknown
+duration. But it is hoped that gofpdf has a bright future in the open
+source world. Due to Go’s promise of compatibility, gofpdf should
+continue to function without modification for a longer time than would
+be the case with many other languages.
+
+Forks should be based on the last viable commit. Tools such as
+active-forks can be used to select a fork that looks promising for your
+needs. If a particular fork looks like it has taken the lead in
+attracting followers, this README will be updated to point people in
+that direction.
+
+The efforts of all contributors to this project have been deeply
+appreciated. Best wishes to all of you.
+
+
+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 and if the third argument to
+ComparePDFFiles() in internal/example/example.go is true. (By default it
+is false.) 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().
+
+You should use AddUTF8Font() or AddUTF8FontFromBytes() to add a TrueType
+UTF-8 encoded font. Use RTL() and LTR() methods switch between
+“right-to-left” and “left-to-right” mode.
+
+In order to use a different non-UTF-8 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 Google Fonts and DejaVu Fonts.
+
+
+Related Packages
+
+The draw2d package 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 and go vet, that is, golint . and
+go vet . should not generate any warnings
+
+-   not diminish test coverage
+
+Pull requests are the preferred means of accepting 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 created by Olivier Plathey, and a number of font and image
+resources are copied directly from it. Bruno Michel has provided
+valuable assistance with the code. 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. Jelmer
+Snoek and Guillermo Pascual 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. Dan
+Meyers added support for embedded JavaScript. David Fish added a generic
+alias-replacement function to enable, among other things, table of
+contents functionality. Andy Bakun identified and corrected a problem in
+which the internal catalogs were not sorted stably. Paul Montag added
+encoding and decoding functionality for templates, including images that
+are embedded in templates; this allows templates to be stored
+independently of gofpdf. Paul also added support for page boxes used in
+printing PDF documents. Wojciech Matusiak added supported for word
+spacing. Artem Korotkiy added support of UTF-8 fonts. Dave Barnes added
+support for imported objects and templates. Brigham Thompson added
+support for rounded rectangles. Joe Westcott added underline
+functionality and optimized image storage. Benoit KUGLER contributed
+support for rectangles with corners of unequal radius, modification
+times, and for file attachments and annotations.
+
+
+Roadmap
+
+
+-   Remove all legacy code page font support; use UTF-8 exclusively
+
+-   Improve test coverage as reported by the coverage tool.
+*/
+package gofpdf

+ 288 - 0
doc/document.md

@@ -0,0 +1,288 @@
+# GoFPDF document generator
+
+[![No Maintenance Intended][badge-no-maintain]][unmaintained]
+[![MIT licensed][badge-mit]][license]
+[![Report][badge-report]][report]
+[![GoDoc][badge-doc]][godoc]
+
+![][logo]
+
+Package gofpdf implements a PDF document generator with high level support for
+text, drawing and images.
+
+## Features
+
+* UTF-8 support
+* 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
+* Barcodes
+* Charting facility
+* Import PDFs as templates
+
+gofpdf has no dependencies other than the Go standard library. All tests pass
+on Linux, Mac and Windows platforms.
+
+gofpdf supports UTF-8 TrueType fonts and "right-to-left" languages. Note that
+Chinese, Japanese, and Korean characters may not be included in many general
+purpose fonts. For these languages, a specialized font (for example,
+[NotoSansSC][noto] for simplified Chinese) can be used.
+
+Also, support is provided to automatically translate UTF-8 runes to code page
+encodings for languages that have fewer than 256 glyphs.
+
+## We Are Closed
+
+This repository will not be maintained, at least for some unknown duration. But
+it is hoped that gofpdf has a bright future in the open source world. Due to
+Go's promise of compatibility, gofpdf should continue to function without
+modification for a longer time than would be the case with many other
+languages.
+
+Forks should be based on the [last viable commit][last-commit]. Tools such as
+[active-forks][gofpdf-fork] can be used to select a fork that looks promising
+for your needs. If a particular fork looks like it has taken the lead in
+attracting followers, this README will be updated to point people in that
+direction.
+
+The efforts of all contributors to this project have been deeply appreciated.
+Best wishes to all of you.
+
+## Installation
+
+To install the package on your system, run
+
+```shell
+go get github.com/jung-kurt/gofpdf
+```
+
+Later, to receive updates, run
+
+```shell
+go get -u -v github.com/jung-kurt/gofpdf/...
+```
+
+## Quick Start
+
+The following Go code generates a simple PDF file.
+
+```go
+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][fpdf-test] 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][fpdf-site] library written in PHP (despite the caveat in the
+introduction to [Effective Go][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][fpdf-test] 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 and if the third argument to `ComparePDFFiles()` in
+internal/example/example.go is true. (By default it is false.) 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()`.
+
+You should use `AddUTF8Font()` or `AddUTF8FontFromBytes()` to add a TrueType
+UTF-8 encoded font. Use `RTL()` and `LTR()` methods switch between
+"right-to-left" and "left-to-right" mode.
+
+In order to use a different non-UTF-8 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.
+
+```shell
+./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 [Google Fonts][gfont] and [DejaVu Fonts][dfont].
+
+## Related Packages
+
+The [draw2d][draw2d-site] package 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][test] if appropriate
+* conform to the standards of [golint][lint] and
+[go vet][vet], that is, `golint .` and
+`go vet .` should not generate any warnings
+* not diminish [test coverage][coverage]
+
+[Pull requests][pr] are the preferred means of accepting 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][fpdf-site]
+library created by Olivier Plathey, and a number of font and image resources
+are copied directly from it. Bruno Michel has provided valuable assistance with
+the code. 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. Jelmer Snoek and Guillermo Pascual 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. Dan Meyers added support for embedded JavaScript. David Fish added a
+generic alias-replacement function to enable, among other things, table of
+contents functionality. Andy Bakun identified and corrected a problem in which
+the internal catalogs were not sorted stably. Paul Montag added encoding and
+decoding functionality for templates, including images that are embedded in
+templates; this allows templates to be stored independently of gofpdf. Paul
+also added support for page boxes used in printing PDF documents. Wojciech
+Matusiak added supported for word spacing. Artem Korotkiy added support of
+UTF-8 fonts. Dave Barnes added support for imported objects and templates.
+Brigham Thompson added support for rounded rectangles. Joe Westcott added
+underline functionality and optimized image storage. Benoit KUGLER contributed
+support for rectangles with corners of unequal radius, modification times, and
+for file attachments and annotations.
+
+## Roadmap
+
+* Remove all legacy code page font support; use UTF-8 exclusively
+* Improve test coverage as reported by the coverage tool.
+
+[badge-author]: https://img.shields.io/badge/author-Kurt_Jung-blue.svg
+[badge-doc]: https://img.shields.io/badge/godoc-GoFPDF-blue.svg 
+[badge-github]: https://img.shields.io/badge/project-Git_Hub-blue.svg
+[badge-mit]: https://img.shields.io/badge/license-MIT-blue.svg
+[badge-no-maintain]: http://unmaintained.tech/badge.svg
+[badge-report]: https://goreportcard.com/badge/github.com/jung-kurt/gofpdf
+[badge-status]: https://travis-ci.org/jung-kurt/gofpdf.svg?branch=master
+[coverage]: https://blog.golang.org/cover
+[dfont]: http://dejavu-fonts.org/
+[draw2d-site]: https://github.com/llgcode/draw2d
+[effective-go]: https://golang.org/doc/effective_go.html 
+[fpdf-site]: http://www.fpdf.org/
+[fpdf-test]: https://github.com/jung-kurt/gofpdf/blob/master/fpdf_test.go
+[gfont]: https://fonts.google.com/
+[github]: https://github.com/jung-kurt/gofpdf
+[godoc]: https://godoc.org/github.com/jung-kurt/gofpdf
+[gofpdf-fork]: https://techgaun.github.io/active-forks/index.html#jung-kurt/gofpdf
+[issue109]: https://github.com/jung-kurt/gofpdf/issues/109
+[jung]: https://github.com/jung-kurt/
+[last-commit]: https://github.com/jung-kurt/gofpdf/commit/603f56990463f011cb1dbb64ef7f872c1adc009a
+[license]: https://raw.githubusercontent.com/jung-kurt/gofpdf/master/LICENSE
+[lint]: https://github.com/golang/lint
+[logo]: https://github.com/jung-kurt/gofpdf/raw/master/image/logo_gofpdf.jpg?raw=true
+[noto]: https://github.com/jsntn/webfonts/blob/master/NotoSansSC-Regular.ttf
+[pr]: https://help.github.com/articles/using-pull-requests/
+[report]: https://goreportcard.com/report/github.com/jung-kurt/gofpdf
+[status]: https://travis-ci.org/jung-kurt/gofpdf
+[test]: https://github.com/jung-kurt/gofpdf/blob/master/fpdf_test.go
+[unmaintained]: http://unmaintained.tech/
+[vet]: https://golang.org/cmd/vet/

+ 13 - 0
doc/go.awk

@@ -0,0 +1,13 @@
+BEGIN { show = 0 ; print "/*" }
+
+/^\-/ { trim = 1 ; print "" }
+
+/^Package/ { show = 1 }
+
+!NF { trim = 0 }
+
+trim { sub("^ +", "", $0) }
+
+show { print $0 }
+
+END { print "*/\npackage " package_name }

+ 68 - 0
doc/html.txt

@@ -0,0 +1,68 @@
+<!doctype html>
+
+<html lang="en">
+
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width initial-scale=1 maximum-scale=1 minimum-scale=1 user-scalable=0" />
+  <title>GoFPDF Document Generator</title>
+  <style>
+    body {
+      max-width: 800px;
+      font-family: sans-serif;
+      padding: 1em;
+    }
+
+    img {
+      max-width: 800px;
+    }
+
+    h1,
+    h2,
+    h3 {
+      color: #345;
+    }
+
+    .syntax {
+      display: block;
+      white-space: pre;
+      font-family: monospace;
+      background-color: #efe;
+      border: 1px solid #474;
+      margin: 1em 0;
+      padding: 0.25em 1.5em;
+    }
+
+    .warning {
+      background-color: #ffd;
+      border: 1px solid #665;
+      margin: 1em 0;
+      padding: 0 1em;
+    }
+
+    .key {
+      color: #131;
+      font-weight: bold;
+    }
+
+    .subkey {
+      font-style: italic;
+    }
+
+    pre {
+      margin: 1.5em 0;
+      background-color: #eee;
+      padding: 1em;
+      overflow-x: scroll;
+    }
+$if(highlighting-css)$
+$highlighting-css$
+$endif$
+  </style>
+</head>
+
+<body>
+$body$
+</body>
+
+</html>

+ 559 - 0
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
+	`,
+}

+ 474 - 0
font.go

@@ -0,0 +1,474 @@
+/*
+ * 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
+}
+
+// getInfoFromTrueType returns information from a TrueType font
+func getInfoFromTrueType(fileStr string, msgWriter io.Writer, embed bool, encList encListType) (info fontInfoType, err error) {
+	info.Widths = make([]int, 256)
+	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(r io.Reader) (s segmentType, err error) {
+	if err = binary.Read(r, 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(r, binary.LittleEndian, &s.tp); err != nil {
+		return
+	}
+	if err = binary.Read(r, binary.LittleEndian, &s.size); err != nil {
+		return
+	}
+	s.data = make([]byte, s.size)
+	_, err = r.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
+
+// getInfoFromType1 return information from a Type1 font
+func getInfoFromType1(fileStr string, msgWriter io.Writer, embed bool, encList encListType) (info fontInfoType, err error) {
+	info.Widths = make([]int, 256)
+	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)
+}
+
+// makeFontEncoding builds 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) error {
+	var 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 err
+	}
+	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 err
+	}
+	var f *os.File
+	f, err = os.Create(fileStr)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+	_, err = f.Write(buf)
+	if err != nil {
+		return err
+	}
+	err = f.Close()
+	if err != nil {
+		return err
+	}
+
+	return err
+}
+
+// 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) error {
+	if msgWriter == nil {
+		msgWriter = ioutil.Discard
+	}
+	if !fileExist(fontFileStr) {
+		return fmt.Errorf("font file not found: %s", fontFileStr)
+	}
+	extStr := strings.ToLower(fontFileStr[len(fontFileStr)-3:])
+	// printf("Font file extension [%s]\n", extStr)
+	var tpStr string
+	switch extStr {
+	case "ttf":
+		fallthrough
+	case "otf":
+		tpStr = "TrueType"
+	case "pfb":
+		tpStr = "Type1"
+	default:
+		return fmt.Errorf("unrecognized font file extension: %s", extStr)
+	}
+
+	var info fontInfoType
+	encList, err := loadMap(encodingFileStr)
+	if err != nil {
+		return err
+	}
+	// printf("Encoding table\n")
+	// dump(encList)
+	if tpStr == "TrueType" {
+		info, err = getInfoFromTrueType(fontFileStr, msgWriter, embed, encList)
+		if err != nil {
+			return err
+		}
+	} else {
+		info, err = getInfoFromType1(fontFileStr, msgWriter, embed, encList)
+		if err != nil {
+			return err
+		}
+	}
+	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 err
+		}
+		defer f.Close()
+		cmp := zlib.NewWriter(f)
+		_, err = cmp.Write(info.Data)
+		if err != nil {
+			return err
+		}
+		err = cmp.Close()
+		if err != nil {
+			return err
+		}
+		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 err
+	}
+	fmt.Fprintf(msgWriter, "Font definition file successfully generated: %s\n", defFileStr)
+	return nil
+}

+ 272 - 0
font/CalligrapherRegular.afm

@@ -0,0 +1,272 @@
+StartFontMetrics 2.0
+Comment Generated by FontForge 20141024
+Comment Creation Date: Thu Jul 23 17:38:06 2015
+FontName CalligrapherRegular
+FullName Calligrapher Regular
+FamilyName Calligrapher
+Weight Thin
+Notice (Generated by Fontographer 3.5)
+ItalicAngle 0
+IsFixedPitch false
+UnderlinePosition -190
+UnderlineThickness 20
+Version Altsys Fontographer 3.5  5/26/92
+EncodingScheme ISO10646-1
+FontBBox -173 -234 1328 899
+CapHeight 677
+XHeight 677
+Ascender 756
+Descender -219
+StartCharMetrics 250
+C 32 ; WX 282 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 324 ; N exclam ; B 67 -16 251 718 ;
+C 34 ; WX 405 ; N quotedbl ; B 60 460 353 718 ;
+C 35 ; WX 584 ; N numbersign ; B 35 0 549 701 ;
+C 36 ; WX 632 ; N dollar ; B 32 -126 595 814 ;
+C 37 ; WX 980 ; N percent ; B 35 -16 945 703 ;
+C 38 ; WX 776 ; N ampersand ; B 41 -17 811 670 ;
+C 39 ; WX 259 ; N quotesingle ; B 72 460 206 718 ;
+C 40 ; WX 299 ; N parenleft ; B 57 -119 299 785 ;
+C 41 ; WX 299 ; N parenright ; B 0 -119 242 785 ;
+C 42 ; WX 377 ; N asterisk ; B 35 407 342 714 ;
+C 43 ; WX 600 ; N plus ; B 47 0 553 506 ;
+C 44 ; WX 259 ; N comma ; B 35 -67 224 162 ;
+C 45 ; WX 432 ; N hyphen ; B 28 249 404 377 ;
+C 46 ; WX 254 ; N period ; B 43 -16 227 162 ;
+C 47 ; WX 597 ; N slash ; B 7 -14 591 714 ;
+C 48 ; WX 529 ; N zero ; B 21 -18 508 583 ;
+C 49 ; WX 298 ; N one ; B 8 -15 233 582 ;
+C 50 ; WX 451 ; N two ; B 17 -8 430 588 ;
+C 51 ; WX 359 ; N three ; B 11 -54 337 582 ;
+C 52 ; WX 525 ; N four ; B 18 -20 519 602 ;
+C 53 ; WX 423 ; N five ; B 10 -55 420 582 ;
+C 54 ; WX 464 ; N six ; B 23 -14 447 589 ;
+C 55 ; WX 417 ; N seven ; B 8 -18 415 589 ;
+C 56 ; WX 457 ; N eight ; B 19 -16 432 583 ;
+C 57 ; WX 479 ; N nine ; B 26 -16 450 588 ;
+C 58 ; WX 275 ; N colon ; B 59 -16 242 491 ;
+C 59 ; WX 282 ; N semicolon ; B 54 -67 245 491 ;
+C 60 ; WX 600 ; N less ; B 47 -8 553 514 ;
+C 61 ; WX 600 ; N equal ; B 47 98 553 408 ;
+C 62 ; WX 600 ; N greater ; B 47 -8 553 514 ;
+C 63 ; WX 501 ; N question ; B 21 -16 473 721 ;
+C 64 ; WX 800 ; N at ; B 29 -12 771 730 ;
+C 65 ; WX 743 ; N A ; B -23 -14 754 721 ;
+C 66 ; WX 636 ; N B ; B -42 -7 608 706 ;
+C 67 ; WX 598 ; N C ; B 27 -12 572 712 ;
+C 68 ; WX 712 ; N D ; B -42 -11 684 705 ;
+C 69 ; WX 608 ; N E ; B -21 0 608 708 ;
+C 70 ; WX 562 ; N F ; B -21 -18 584 716 ;
+C 71 ; WX 680 ; N G ; B 29 -8 668 714 ;
+C 72 ; WX 756 ; N H ; B 70 -17 777 728 ;
+C 73 ; WX 308 ; N I ; B 14 -15 238 718 ;
+C 74 ; WX 314 ; N J ; B 7 -223 244 727 ;
+C 75 ; WX 676 ; N K ; B 14 -16 683 725 ;
+C 76 ; WX 552 ; N L ; B 14 -8 580 713 ;
+C 77 ; WX 1041 ; N M ; B 42 -17 1017 739 ;
+C 78 ; WX 817 ; N N ; B -42 -17 747 736 ;
+C 79 ; WX 729 ; N O ; B 32 -16 698 709 ;
+C 80 ; WX 569 ; N P ; B -35 -15 570 716 ;
+C 81 ; WX 698 ; N Q ; B 27 -201 1328 715 ;
+C 82 ; WX 674 ; N R ; B -35 -20 696 712 ;
+C 83 ; WX 618 ; N S ; B 31 -16 589 709 ;
+C 84 ; WX 673 ; N T ; B -21 -20 702 714 ;
+C 85 ; WX 805 ; N U ; B 0 -19 804 722 ;
+C 86 ; WX 753 ; N V ; B -28 -20 788 729 ;
+C 87 ; WX 1238 ; N W ; B -28 -17 1273 736 ;
+C 88 ; WX 716 ; N X ; B 7 -38 709 731 ;
+C 89 ; WX 754 ; N Y ; B -35 -17 789 747 ;
+C 90 ; WX 599 ; N Z ; B 30 -5 584 748 ;
+C 91 ; WX 315 ; N bracketleft ; B 93 -124 322 718 ;
+C 92 ; WX 463 ; N backslash ; B -21 -18 484 736 ;
+C 93 ; WX 315 ; N bracketright ; B -7 -124 222 718 ;
+C 94 ; WX 600 ; N asciicircum ; B 63 266 537 658 ;
+C 95 ; WX 547 ; N underscore ; B -7 -198 554 -163 ;
+C 96 ; WX 278 ; N grave ; B -1 541 214 693 ;
+C 97 ; WX 581 ; N a ; B 21 -16 581 494 ;
+C 98 ; WX 564 ; N b ; B -24 -17 543 792 ;
+C 99 ; WX 440 ; N c ; B 21 -17 422 490 ;
+C 100 ; WX 571 ; N d ; B 0 -15 550 659 ;
+C 101 ; WX 450 ; N e ; B 28 -23 428 493 ;
+C 102 ; WX 347 ; N f ; B -35 -14 474 785 ;
+C 103 ; WX 628 ; N g ; B 19 -219 612 496 ;
+C 104 ; WX 611 ; N h ; B -29 -18 569 785 ;
+C 105 ; WX 283 ; N i ; B -14 -15 241 679 ;
+C 106 ; WX 283 ; N j ; B -14 -234 241 679 ;
+C 107 ; WX 560 ; N k ; B -24 -15 582 789 ;
+C 108 ; WX 252 ; N l ; B -28 -15 210 789 ;
+C 109 ; WX 976 ; N m ; B -21 -16 927 494 ;
+C 110 ; WX 595 ; N n ; B -28 -15 574 493 ;
+C 111 ; WX 508 ; N o ; B 27 -17 485 490 ;
+C 112 ; WX 549 ; N p ; B -28 -216 526 496 ;
+C 113 ; WX 540 ; N q ; B 28 -219 491 493 ;
+C 114 ; WX 395 ; N r ; B -21 -19 430 492 ;
+C 115 ; WX 441 ; N s ; B 34 -15 413 493 ;
+C 116 ; WX 307 ; N t ; B -21 -16 378 621 ;
+C 117 ; WX 614 ; N u ; B -14 -18 558 501 ;
+C 118 ; WX 556 ; N v ; B -28 -20 569 483 ;
+C 119 ; WX 915 ; N w ; B -28 -17 928 495 ;
+C 120 ; WX 559 ; N x ; B 14 -17 546 500 ;
+C 121 ; WX 597 ; N y ; B -21 -227 541 500 ;
+C 122 ; WX 452 ; N z ; B 28 -5 442 515 ;
+C 123 ; WX 315 ; N braceleft ; B 6 -118 309 718 ;
+C 124 ; WX 222 ; N bar ; B 63 -18 159 730 ;
+C 125 ; WX 315 ; N braceright ; B 6 -118 309 718 ;
+C 126 ; WX 600 ; N asciitilde ; B 69 166 531 340 ;
+C 160 ; WX 282 ; N nonbreakingspace ; B 0 0 0 0 ;
+C 161 ; WX 324 ; N exclamdown ; B 69 -203 253 531 ;
+C 162 ; WX 450 ; N cent ; B 27 -122 437 592 ;
+C 163 ; WX 640 ; N sterling ; B 0 -9 619 716 ;
+C 164 ; WX 518 ; N currency ; B 3 72 515 586 ;
+C 165 ; WX 603 ; N yen ; B -28 -65 631 747 ;
+C 166 ; WX 0 ; N brokenbar ; B 0 0 0 0 ;
+C 167 ; WX 519 ; N section ; B -50 -216 524 762 ;
+C 168 ; WX 254 ; N dieresis ; B -20 554 308 682 ;
+C 169 ; WX 800 ; N copyright ; B 29 -12 771 730 ;
+C 170 ; WX 349 ; N ordfeminine ; B 13 385 349 717 ;
+C 171 ; WX 0 ; N guillemotleft ; B 0 0 0 0 ;
+C 172 ; WX 0 ; N logicalnot ; B 0 0 0 0 ;
+C 173 ; WX 432 ; N hyphen ; B 28 249 404 377 ;
+C 174 ; WX 800 ; N registered ; B 29 -12 771 730 ;
+C 175 ; WX 278 ; N macron ; B -47 584 325 665 ;
+C 176 ; WX 0 ; N degree ; B 0 0 0 0 ;
+C 177 ; WX 0 ; N plusminus ; B 0 0 0 0 ;
+C 178 ; WX 0 ; N twosuperior ; B 0 0 0 0 ;
+C 179 ; WX 0 ; N threesuperior ; B 0 0 0 0 ;
+C 180 ; WX 278 ; N acute ; B 49 536 279 693 ;
+C 181 ; WX 614 ; N mu ; B -14 -231 558 501 ;
+C 182 ; WX 0 ; N paragraph ; B 0 0 0 0 ;
+C 183 ; WX 254 ; N periodcentered ; B 43 278 227 456 ;
+C 184 ; WX 278 ; N cedilla ; B -8 -216 231 6 ;
+C 185 ; WX 0 ; N onesuperior ; B 0 0 0 0 ;
+C 186 ; WX 305 ; N ordmasculine ; B 16 373 291 702 ;
+C 187 ; WX 0 ; N guillemotright ; B 0 0 0 0 ;
+C 188 ; WX 0 ; N onequarter ; B 0 0 0 0 ;
+C 189 ; WX 0 ; N onehalf ; B 0 0 0 0 ;
+C 190 ; WX 0 ; N threequarters ; B 0 0 0 0 ;
+C 191 ; WX 501 ; N questiondown ; B 15 -196 467 541 ;
+C 192 ; WX 743 ; N Agrave ; B -23 -14 754 893 ;
+C 193 ; WX 743 ; N Aacute ; B -23 -14 754 893 ;
+C 194 ; WX 743 ; N Acircumflex ; B -23 -14 754 877 ;
+C 195 ; WX 743 ; N Atilde ; B -23 -14 754 889 ;
+C 196 ; WX 743 ; N Adieresis ; B -23 -14 754 882 ;
+C 197 ; WX 743 ; N Aring ; B -23 -14 754 899 ;
+C 198 ; WX 1060 ; N AE ; B -29 -14 1053 708 ;
+C 199 ; WX 598 ; N Ccedilla ; B 27 -183 572 712 ;
+C 200 ; WX 608 ; N Egrave ; B -21 0 608 893 ;
+C 201 ; WX 608 ; N Eacute ; B -21 0 608 893 ;
+C 202 ; WX 608 ; N Ecircumflex ; B -21 0 608 877 ;
+C 203 ; WX 608 ; N Edieresis ; B -21 0 608 882 ;
+C 204 ; WX 308 ; N Igrave ; B 14 -15 264 893 ;
+C 205 ; WX 308 ; N Iacute ; B 14 -15 274 893 ;
+C 206 ; WX 308 ; N Icircumflex ; B 1 -15 307 877 ;
+C 207 ; WX 308 ; N Idieresis ; B -15 -15 313 882 ;
+C 208 ; WX 0 ; N Eth ; B 0 0 0 0 ;
+C 209 ; WX 817 ; N Ntilde ; B -42 -17 747 889 ;
+C 210 ; WX 729 ; N Ograve ; B 32 -16 698 893 ;
+C 211 ; WX 729 ; N Oacute ; B 32 -16 698 893 ;
+C 212 ; WX 729 ; N Ocircumflex ; B 32 -16 698 877 ;
+C 213 ; WX 729 ; N Otilde ; B 32 -16 698 889 ;
+C 214 ; WX 729 ; N Odieresis ; B 32 -16 698 882 ;
+C 215 ; WX 0 ; N multiply ; B 0 0 0 0 ;
+C 216 ; WX 729 ; N Oslash ; B 14 -24 724 709 ;
+C 217 ; WX 805 ; N Ugrave ; B 0 -19 804 893 ;
+C 218 ; WX 805 ; N Uacute ; B 0 -19 804 893 ;
+C 219 ; WX 805 ; N Ucircumflex ; B 0 -19 804 877 ;
+C 220 ; WX 805 ; N Udieresis ; B 0 -19 804 882 ;
+C 221 ; WX 0 ; N Yacute ; B 0 0 0 0 ;
+C 222 ; WX 0 ; N Thorn ; B 0 0 0 0 ;
+C 223 ; WX 688 ; N germandbls ; B -35 -15 668 785 ;
+C 224 ; WX 581 ; N agrave ; B 21 -16 581 693 ;
+C 225 ; WX 581 ; N aacute ; B 21 -16 581 693 ;
+C 226 ; WX 581 ; N acircumflex ; B 21 -16 581 677 ;
+C 227 ; WX 581 ; N atilde ; B 21 -16 581 689 ;
+C 228 ; WX 581 ; N adieresis ; B 21 -16 581 682 ;
+C 229 ; WX 581 ; N aring ; B 21 -16 581 734 ;
+C 230 ; WX 792 ; N ae ; B 21 -23 773 494 ;
+C 231 ; WX 440 ; N ccedilla ; B 21 -183 422 490 ;
+C 232 ; WX 450 ; N egrave ; B 28 -23 428 693 ;
+C 233 ; WX 450 ; N eacute ; B 28 -23 428 693 ;
+C 234 ; WX 450 ; N ecircumflex ; B 28 -23 432 677 ;
+C 235 ; WX 450 ; N edieresis ; B 28 -23 428 682 ;
+C 236 ; WX 283 ; N igrave ; B -14 -15 244 693 ;
+C 237 ; WX 283 ; N iacute ; B -14 -15 269 693 ;
+C 238 ; WX 283 ; N icircumflex ; B -14 -15 297 677 ;
+C 239 ; WX 283 ; N idieresis ; B -25 -15 303 682 ;
+C 240 ; WX 0 ; N eth ; B 0 0 0 0 ;
+C 241 ; WX 595 ; N ntilde ; B -28 -15 574 689 ;
+C 242 ; WX 508 ; N ograve ; B 27 -17 485 693 ;
+C 243 ; WX 508 ; N oacute ; B 27 -17 485 693 ;
+C 244 ; WX 508 ; N ocircumflex ; B 27 -17 485 677 ;
+C 245 ; WX 508 ; N otilde ; B 27 -17 485 689 ;
+C 246 ; WX 508 ; N odieresis ; B 27 -17 485 682 ;
+C 247 ; WX 0 ; N divide ; B 0 0 0 0 ;
+C 248 ; WX 508 ; N oslash ; B -8 -54 496 589 ;
+C 249 ; WX 614 ; N ugrave ; B -14 -18 558 693 ;
+C 250 ; WX 614 ; N uacute ; B -14 -18 558 693 ;
+C 251 ; WX 614 ; N ucircumflex ; B -14 -18 558 677 ;
+C 252 ; WX 614 ; N udieresis ; B -14 -18 558 682 ;
+C 253 ; WX 0 ; N yacute ; B 0 0 0 0 ;
+C 254 ; WX 0 ; N thorn ; B 0 0 0 0 ;
+C 255 ; WX 597 ; N ydieresis ; B -21 -227 541 682 ;
+C -1 ; WX 283 ; N dotlessi ; B -14 -15 227 499 ;
+C -1 ; WX 0 ; N Lslash ; B 0 0 0 0 ;
+C -1 ; WX 0 ; N lslash ; B 0 0 0 0 ;
+C -1 ; WX 1064 ; N OE ; B 32 -16 1055 709 ;
+C -1 ; WX 790 ; N oe ; B 27 -23 764 493 ;
+C -1 ; WX 0 ; N Scaron ; B 0 0 0 0 ;
+C -1 ; WX 0 ; N scaron ; B 0 0 0 0 ;
+C -1 ; WX 754 ; N Ydieresis ; B -35 -17 789 882 ;
+C -1 ; WX 0 ; N Zcaron ; B 0 0 0 0 ;
+C -1 ; WX 0 ; N zcaron ; B 0 0 0 0 ;
+C -1 ; WX 0 ; N florin ; B 0 0 0 0 ;
+C -1 ; WX 278 ; N hungarumlaut ; B -51 531 379 693 ;
+C -1 ; WX 278 ; N circumflex ; B -14 557 292 677 ;
+C -1 ; WX 278 ; N caron ; B -14 557 292 677 ;
+C -1 ; WX 278 ; N macron ; B -47 584 325 665 ;
+C -1 ; WX 278 ; N breve ; B -32 545 310 698 ;
+C -1 ; WX 254 ; N dotaccent ; B 88 554 220 682 ;
+C -1 ; WX 278 ; N ring ; B 11 532 267 734 ;
+C -1 ; WX 278 ; N ogonek ; B 32 -216 226 6 ;
+C -1 ; WX 278 ; N tilde ; B -44 563 326 689 ;
+C -1 ; WX 611 ; N summation ; B -29 -18 569 785 ;
+C -1 ; WX 411 ; N Omega ; B 34 -15 413 677 ;
+C -1 ; WX 283 ; N pi ; B -14 -234 297 677 ;
+C -1 ; WX 300 ; N endash ; B 0 245 300 350 ;
+C -1 ; WX 600 ; N emdash ; B 0 245 600 350 ;
+C -1 ; WX 259 ; N quoteleft ; B 35 489 224 717 ;
+C -1 ; WX 259 ; N quoteright ; B 35 489 224 717 ;
+C -1 ; WX 0 ; N quotesinglbase ; B 0 0 0 0 ;
+C -1 ; WX 470 ; N quotedblleft ; B 35 489 443 717 ;
+C -1 ; WX 470 ; N quotedblright ; B 35 487 443 717 ;
+C -1 ; WX 0 ; N quotedblbase ; B 0 0 0 0 ;
+C -1 ; WX 0 ; N dagger ; B 0 0 0 0 ;
+C -1 ; WX 0 ; N daggerdbl ; B 0 0 0 0 ;
+C -1 ; WX 500 ; N bullet ; B 70 179 430 539 ;
+C -1 ; WX 780 ; N ellipsis ; B 43 -16 747 162 ;
+C -1 ; WX 0 ; N perthousand ; B 0 0 0 0 ;
+C -1 ; WX 0 ; N guilsinglleft ; B 0 0 0 0 ;
+C -1 ; WX 0 ; N guilsinglright ; B 0 0 0 0 ;
+C -1 ; WX 990 ; N trademark ; B 62 306 928 718 ;
+C -1 ; WX 756 ; N partialdiff ; B 70 -17 777 877 ;
+C -1 ; WX 614 ; N Delta ; B -14 -18 558 698 ;
+C -1 ; WX 314 ; N product ; B 7 -223 317 877 ;
+C -1 ; WX 0 ; N minus ; B 0 0 0 0 ;
+C -1 ; WX 167 ; N fraction ; B -173 -28 310 686 ;
+C -1 ; WX 254 ; N periodcentered ; B 43 278 227 456 ;
+C -1 ; WX 760 ; N radical ; B 30 0 730 700 ;
+C -1 ; WX 440 ; N infinity ; B 21 -17 422 677 ;
+C -1 ; WX 618 ; N integral ; B 31 -16 589 877 ;
+C -1 ; WX 805 ; N approxequal ; B 0 -19 804 854 ;
+C -1 ; WX 598 ; N notequal ; B 27 -12 572 877 ;
+C -1 ; WX 680 ; N lessequal ; B 29 -8 668 877 ;
+C -1 ; WX 628 ; N greaterequal ; B 19 -219 612 677 ;
+C -1 ; WX 795 ; N lozenge ; B 35 0 760 727 ;
+C -1 ; WX 795 ; N apple ; B 35 0 760 727 ;
+C -1 ; WX 0 ; N fi ; B 0 0 0 0 ;
+C -1 ; WX 0 ; N fl ; B 0 0 0 0 ;
+C -1 ; WX 800 ; N .notdef ; B 50 0 750 800 ;
+C -1 ; WX 0 ; N .null ; B 0 0 0 0 ;
+C -1 ; WX 282 ; N nonmarkingreturn ; B 0 0 0 0 ;
+EndCharMetrics
+EndFontMetrics

BIN
font/CalligrapherRegular.pfb


BIN
font/DejaVuSansCondensed-Bold.ttf


BIN
font/DejaVuSansCondensed-BoldOblique.ttf


BIN
font/DejaVuSansCondensed-Oblique.ttf


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
font/DejaVuSansCondensed.json


BIN
font/DejaVuSansCondensed.ttf


+ 1 - 0
font/calligra.json

@@ -0,0 +1 @@
+{"Tp":"TrueType","Name":"CalligrapherRegular","Desc":{"Ascent":899,"Descent":-234,"CapHeight":899,"Flags":32,"FontBBox":{"Xmin":-173,"Ymin":-234,"Xmax":1328,"Ymax":899},"ItalicAngle":0,"StemV":70,"MissingWidth":800},"Up":-200,"Ut":20,"Cw":[800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,282,324,405,584,632,980,776,259,299,299,377,600,259,432,254,597,529,298,451,359,525,423,464,417,457,479,275,282,600,600,600,501,800,743,636,598,712,608,562,680,756,308,314,676,552,1041,817,729,569,698,674,618,673,805,753,1238,716,754,599,315,463,315,600,547,278,581,564,440,571,450,347,628,611,283,283,560,252,976,595,508,549,540,395,441,307,614,556,915,559,597,452,315,222,315,600,800,800,800,0,0,0,780,0,0,278,0,0,0,1064,800,0,800,800,259,259,470,470,500,300,600,278,990,0,0,790,800,800,754,282,324,450,640,518,603,0,519,254,800,349,0,0,432,800,278,0,0,0,0,278,614,0,254,278,0,305,0,0,0,0,501,743,743,743,743,743,743,1060,598,608,608,608,608,308,308,308,308,0,817,729,729,729,729,729,0,729,805,805,805,805,0,0,688,581,581,581,581,581,581,792,440,450,450,450,450,283,283,283,283,0,595,508,508,508,508,508,0,508,614,614,614,614,0,0,597],"Enc":"cp1252","Diff":"","File":"calligra.z","Size1":0,"Size2":0,"OriginalSize":40120,"N":0,"DiffN":0}

BIN
font/calligra.ttf


BIN
font/calligra.z


+ 1 - 0
font/courier.json

@@ -0,0 +1 @@
+{"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]}

+ 1 - 0
font/courierb.json

@@ -0,0 +1 @@
+{"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]}

+ 1 - 0
font/courierbi.json

@@ -0,0 +1 @@
+{"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]}

+ 1 - 0
font/courieri.json

@@ -0,0 +1 @@
+{"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]}

+ 251 - 0
font/cp1250.map

@@ -0,0 +1,251 @@
+!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

+ 255 - 0
font/cp1251.map

@@ -0,0 +1,255 @@
+!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+0402 afii10051
+!81 U+0403 afii10052
+!82 U+201A quotesinglbase
+!83 U+0453 afii10100
+!84 U+201E quotedblbase
+!85 U+2026 ellipsis
+!86 U+2020 dagger
+!87 U+2021 daggerdbl
+!88 U+20AC Euro
+!89 U+2030 perthousand
+!8A U+0409 afii10058
+!8B U+2039 guilsinglleft
+!8C U+040A afii10059
+!8D U+040C afii10061
+!8E U+040B afii10060
+!8F U+040F afii10145
+!90 U+0452 afii10099
+!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+0459 afii10106
+!9B U+203A guilsinglright
+!9C U+045A afii10107
+!9D U+045C afii10109
+!9E U+045B afii10108
+!9F U+045F afii10193
+!A0 U+00A0 space
+!A1 U+040E afii10062
+!A2 U+045E afii10110
+!A3 U+0408 afii10057
+!A4 U+00A4 currency
+!A5 U+0490 afii10050
+!A6 U+00A6 brokenbar
+!A7 U+00A7 section
+!A8 U+0401 afii10023
+!A9 U+00A9 copyright
+!AA U+0404 afii10053
+!AB U+00AB guillemotleft
+!AC U+00AC logicalnot
+!AD U+00AD hyphen
+!AE U+00AE registered
+!AF U+0407 afii10056
+!B0 U+00B0 degree
+!B1 U+00B1 plusminus
+!B2 U+0406 afii10055
+!B3 U+0456 afii10103
+!B4 U+0491 afii10098
+!B5 U+00B5 mu
+!B6 U+00B6 paragraph
+!B7 U+00B7 periodcentered
+!B8 U+0451 afii10071
+!B9 U+2116 afii61352
+!BA U+0454 afii10101
+!BB U+00BB guillemotright
+!BC U+0458 afii10105
+!BD U+0405 afii10054
+!BE U+0455 afii10102
+!BF U+0457 afii10104
+!C0 U+0410 afii10017
+!C1 U+0411 afii10018
+!C2 U+0412 afii10019
+!C3 U+0413 afii10020
+!C4 U+0414 afii10021
+!C5 U+0415 afii10022
+!C6 U+0416 afii10024
+!C7 U+0417 afii10025
+!C8 U+0418 afii10026
+!C9 U+0419 afii10027
+!CA U+041A afii10028
+!CB U+041B afii10029
+!CC U+041C afii10030
+!CD U+041D afii10031
+!CE U+041E afii10032
+!CF U+041F afii10033
+!D0 U+0420 afii10034
+!D1 U+0421 afii10035
+!D2 U+0422 afii10036
+!D3 U+0423 afii10037
+!D4 U+0424 afii10038
+!D5 U+0425 afii10039
+!D6 U+0426 afii10040
+!D7 U+0427 afii10041
+!D8 U+0428 afii10042
+!D9 U+0429 afii10043
+!DA U+042A afii10044
+!DB U+042B afii10045
+!DC U+042C afii10046
+!DD U+042D afii10047
+!DE U+042E afii10048
+!DF U+042F afii10049
+!E0 U+0430 afii10065
+!E1 U+0431 afii10066
+!E2 U+0432 afii10067
+!E3 U+0433 afii10068
+!E4 U+0434 afii10069
+!E5 U+0435 afii10070
+!E6 U+0436 afii10072
+!E7 U+0437 afii10073
+!E8 U+0438 afii10074
+!E9 U+0439 afii10075
+!EA U+043A afii10076
+!EB U+043B afii10077
+!EC U+043C afii10078
+!ED U+043D afii10079
+!EE U+043E afii10080
+!EF U+043F afii10081
+!F0 U+0440 afii10082
+!F1 U+0441 afii10083
+!F2 U+0442 afii10084
+!F3 U+0443 afii10085
+!F4 U+0444 afii10086
+!F5 U+0445 afii10087
+!F6 U+0446 afii10088
+!F7 U+0447 afii10089
+!F8 U+0448 afii10090
+!F9 U+0449 afii10091
+!FA U+044A afii10092
+!FB U+044B afii10093
+!FC U+044C afii10094
+!FD U+044D afii10095
+!FE U+044E afii10096
+!FF U+044F afii10097

+ 251 - 0
font/cp1252.map

@@ -0,0 +1,251 @@
+!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

+ 239 - 0
font/cp1253.map

@@ -0,0 +1,239 @@
+!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
+!89 U+2030 perthousand
+!8B U+2039 guilsinglleft
+!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
+!9B U+203A guilsinglright
+!A0 U+00A0 space
+!A1 U+0385 dieresistonos
+!A2 U+0386 Alphatonos
+!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
+!AB U+00AB guillemotleft
+!AC U+00AC logicalnot
+!AD U+00AD hyphen
+!AE U+00AE registered
+!AF U+2015 afii00208
+!B0 U+00B0 degree
+!B1 U+00B1 plusminus
+!B2 U+00B2 twosuperior
+!B3 U+00B3 threesuperior
+!B4 U+0384 tonos
+!B5 U+00B5 mu
+!B6 U+00B6 paragraph
+!B7 U+00B7 periodcentered
+!B8 U+0388 Epsilontonos
+!B9 U+0389 Etatonos
+!BA U+038A Iotatonos
+!BB U+00BB guillemotright
+!BC U+038C Omicrontonos
+!BD U+00BD onehalf
+!BE U+038E Upsilontonos
+!BF U+038F Omegatonos
+!C0 U+0390 iotadieresistonos
+!C1 U+0391 Alpha
+!C2 U+0392 Beta
+!C3 U+0393 Gamma
+!C4 U+0394 Delta
+!C5 U+0395 Epsilon
+!C6 U+0396 Zeta
+!C7 U+0397 Eta
+!C8 U+0398 Theta
+!C9 U+0399 Iota
+!CA U+039A Kappa
+!CB U+039B Lambda
+!CC U+039C Mu
+!CD U+039D Nu
+!CE U+039E Xi
+!CF U+039F Omicron
+!D0 U+03A0 Pi
+!D1 U+03A1 Rho
+!D3 U+03A3 Sigma
+!D4 U+03A4 Tau
+!D5 U+03A5 Upsilon
+!D6 U+03A6 Phi
+!D7 U+03A7 Chi
+!D8 U+03A8 Psi
+!D9 U+03A9 Omega
+!DA U+03AA Iotadieresis
+!DB U+03AB Upsilondieresis
+!DC U+03AC alphatonos
+!DD U+03AD epsilontonos
+!DE U+03AE etatonos
+!DF U+03AF iotatonos
+!E0 U+03B0 upsilondieresistonos
+!E1 U+03B1 alpha
+!E2 U+03B2 beta
+!E3 U+03B3 gamma
+!E4 U+03B4 delta
+!E5 U+03B5 epsilon
+!E6 U+03B6 zeta
+!E7 U+03B7 eta
+!E8 U+03B8 theta
+!E9 U+03B9 iota
+!EA U+03BA kappa
+!EB U+03BB lambda
+!EC U+03BC mu
+!ED U+03BD nu
+!EE U+03BE xi
+!EF U+03BF omicron
+!F0 U+03C0 pi
+!F1 U+03C1 rho
+!F2 U+03C2 sigma1
+!F3 U+03C3 sigma
+!F4 U+03C4 tau
+!F5 U+03C5 upsilon
+!F6 U+03C6 phi
+!F7 U+03C7 chi
+!F8 U+03C8 psi
+!F9 U+03C9 omega
+!FA U+03CA iotadieresis
+!FB U+03CB upsilondieresis
+!FC U+03CC omicrontonos
+!FD U+03CD upsilontonos
+!FE U+03CE omegatonos

+ 249 - 0
font/cp1254.map

@@ -0,0 +1,249 @@
+!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
+!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
+!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+011E Gbreve
+!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+0130 Idotaccent
+!DE U+015E Scedilla
+!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+011F gbreve
+!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+0131 dotlessi
+!FE U+015F scedilla
+!FF U+00FF ydieresis

+ 233 - 0
font/cp1255.map

@@ -0,0 +1,233 @@
+!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
+!8B U+2039 guilsinglleft
+!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
+!9B U+203A guilsinglright
+!A0 U+00A0 space
+!A1 U+00A1 exclamdown
+!A2 U+00A2 cent
+!A3 U+00A3 sterling
+!A4 U+20AA afii57636
+!A5 U+00A5 yen
+!A6 U+00A6 brokenbar
+!A7 U+00A7 section
+!A8 U+00A8 dieresis
+!A9 U+00A9 copyright
+!AA U+00D7 multiply
+!AB U+00AB guillemotleft
+!AC U+00AC logicalnot
+!AD U+00AD sfthyphen
+!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 middot
+!B8 U+00B8 cedilla
+!B9 U+00B9 onesuperior
+!BA U+00F7 divide
+!BB U+00BB guillemotright
+!BC U+00BC onequarter
+!BD U+00BD onehalf
+!BE U+00BE threequarters
+!BF U+00BF questiondown
+!C0 U+05B0 afii57799
+!C1 U+05B1 afii57801
+!C2 U+05B2 afii57800
+!C3 U+05B3 afii57802
+!C4 U+05B4 afii57793
+!C5 U+05B5 afii57794
+!C6 U+05B6 afii57795
+!C7 U+05B7 afii57798
+!C8 U+05B8 afii57797
+!C9 U+05B9 afii57806
+!CB U+05BB afii57796
+!CC U+05BC afii57807
+!CD U+05BD afii57839
+!CE U+05BE afii57645
+!CF U+05BF afii57841
+!D0 U+05C0 afii57842
+!D1 U+05C1 afii57804
+!D2 U+05C2 afii57803
+!D3 U+05C3 afii57658
+!D4 U+05F0 afii57716
+!D5 U+05F1 afii57717
+!D6 U+05F2 afii57718
+!D7 U+05F3 gereshhebrew
+!D8 U+05F4 gershayimhebrew
+!E0 U+05D0 afii57664
+!E1 U+05D1 afii57665
+!E2 U+05D2 afii57666
+!E3 U+05D3 afii57667
+!E4 U+05D4 afii57668
+!E5 U+05D5 afii57669
+!E6 U+05D6 afii57670
+!E7 U+05D7 afii57671
+!E8 U+05D8 afii57672
+!E9 U+05D9 afii57673
+!EA U+05DA afii57674
+!EB U+05DB afii57675
+!EC U+05DC afii57676
+!ED U+05DD afii57677
+!EE U+05DE afii57678
+!EF U+05DF afii57679
+!F0 U+05E0 afii57680
+!F1 U+05E1 afii57681
+!F2 U+05E2 afii57682
+!F3 U+05E3 afii57683
+!F4 U+05E4 afii57684
+!F5 U+05E5 afii57685
+!F6 U+05E6 afii57686
+!F7 U+05E7 afii57687
+!F8 U+05E8 afii57688
+!F9 U+05E9 afii57689
+!FA U+05EA afii57690
+!FD U+200E afii299
+!FE U+200F afii300

+ 244 - 0
font/cp1257.map

@@ -0,0 +1,244 @@
+!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
+!8B U+2039 guilsinglleft
+!8D U+00A8 dieresis
+!8E U+02C7 caron
+!8F U+00B8 cedilla
+!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
+!9B U+203A guilsinglright
+!9D U+00AF macron
+!9E U+02DB ogonek
+!A0 U+00A0 space
+!A2 U+00A2 cent
+!A3 U+00A3 sterling
+!A4 U+00A4 currency
+!A6 U+00A6 brokenbar
+!A7 U+00A7 section
+!A8 U+00D8 Oslash
+!A9 U+00A9 copyright
+!AA U+0156 Rcommaaccent
+!AB U+00AB guillemotleft
+!AC U+00AC logicalnot
+!AD U+00AD hyphen
+!AE U+00AE registered
+!AF U+00C6 AE
+!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+00F8 oslash
+!B9 U+00B9 onesuperior
+!BA U+0157 rcommaaccent
+!BB U+00BB guillemotright
+!BC U+00BC onequarter
+!BD U+00BD onehalf
+!BE U+00BE threequarters
+!BF U+00E6 ae
+!C0 U+0104 Aogonek
+!C1 U+012E Iogonek
+!C2 U+0100 Amacron
+!C3 U+0106 Cacute
+!C4 U+00C4 Adieresis
+!C5 U+00C5 Aring
+!C6 U+0118 Eogonek
+!C7 U+0112 Emacron
+!C8 U+010C Ccaron
+!C9 U+00C9 Eacute
+!CA U+0179 Zacute
+!CB U+0116 Edotaccent
+!CC U+0122 Gcommaaccent
+!CD U+0136 Kcommaaccent
+!CE U+012A Imacron
+!CF U+013B Lcommaaccent
+!D0 U+0160 Scaron
+!D1 U+0143 Nacute
+!D2 U+0145 Ncommaaccent
+!D3 U+00D3 Oacute
+!D4 U+014C Omacron
+!D5 U+00D5 Otilde
+!D6 U+00D6 Odieresis
+!D7 U+00D7 multiply
+!D8 U+0172 Uogonek
+!D9 U+0141 Lslash
+!DA U+015A Sacute
+!DB U+016A Umacron
+!DC U+00DC Udieresis
+!DD U+017B Zdotaccent
+!DE U+017D Zcaron
+!DF U+00DF germandbls
+!E0 U+0105 aogonek
+!E1 U+012F iogonek
+!E2 U+0101 amacron
+!E3 U+0107 cacute
+!E4 U+00E4 adieresis
+!E5 U+00E5 aring
+!E6 U+0119 eogonek
+!E7 U+0113 emacron
+!E8 U+010D ccaron
+!E9 U+00E9 eacute
+!EA U+017A zacute
+!EB U+0117 edotaccent
+!EC U+0123 gcommaaccent
+!ED U+0137 kcommaaccent
+!EE U+012B imacron
+!EF U+013C lcommaaccent
+!F0 U+0161 scaron
+!F1 U+0144 nacute
+!F2 U+0146 ncommaaccent
+!F3 U+00F3 oacute
+!F4 U+014D omacron
+!F5 U+00F5 otilde
+!F6 U+00F6 odieresis
+!F7 U+00F7 divide
+!F8 U+0173 uogonek
+!F9 U+0142 lslash
+!FA U+015B sacute
+!FB U+016B umacron
+!FC U+00FC udieresis
+!FD U+017C zdotaccent
+!FE U+017E zcaron
+!FF U+02D9 dotaccent

+ 247 - 0
font/cp1258.map

@@ -0,0 +1,247 @@
+!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
+!8B U+2039 guilsinglleft
+!8C U+0152 OE
+!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
+!9B U+203A guilsinglright
+!9C U+0153 oe
+!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+0102 Abreve
+!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+0300 gravecomb
+!CD U+00CD Iacute
+!CE U+00CE Icircumflex
+!CF U+00CF Idieresis
+!D0 U+0110 Dcroat
+!D1 U+00D1 Ntilde
+!D2 U+0309 hookabovecomb
+!D3 U+00D3 Oacute
+!D4 U+00D4 Ocircumflex
+!D5 U+01A0 Ohorn
+!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+01AF Uhorn
+!DE U+0303 tildecomb
+!DF U+00DF germandbls
+!E0 U+00E0 agrave
+!E1 U+00E1 aacute
+!E2 U+00E2 acircumflex
+!E3 U+0103 abreve
+!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+0301 acutecomb
+!ED U+00ED iacute
+!EE U+00EE icircumflex
+!EF U+00EF idieresis
+!F0 U+0111 dcroat
+!F1 U+00F1 ntilde
+!F2 U+0323 dotbelowcomb
+!F3 U+00F3 oacute
+!F4 U+00F4 ocircumflex
+!F5 U+01A1 ohorn
+!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+01B0 uhorn
+!FE U+20AB dong
+!FF U+00FF ydieresis

+ 225 - 0
font/cp874.map

@@ -0,0 +1,225 @@
+!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
+!85 U+2026 ellipsis
+!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
+!A0 U+00A0 space
+!A1 U+0E01 kokaithai
+!A2 U+0E02 khokhaithai
+!A3 U+0E03 khokhuatthai
+!A4 U+0E04 khokhwaithai
+!A5 U+0E05 khokhonthai
+!A6 U+0E06 khorakhangthai
+!A7 U+0E07 ngonguthai
+!A8 U+0E08 chochanthai
+!A9 U+0E09 chochingthai
+!AA U+0E0A chochangthai
+!AB U+0E0B sosothai
+!AC U+0E0C chochoethai
+!AD U+0E0D yoyingthai
+!AE U+0E0E dochadathai
+!AF U+0E0F topatakthai
+!B0 U+0E10 thothanthai
+!B1 U+0E11 thonangmonthothai
+!B2 U+0E12 thophuthaothai
+!B3 U+0E13 nonenthai
+!B4 U+0E14 dodekthai
+!B5 U+0E15 totaothai
+!B6 U+0E16 thothungthai
+!B7 U+0E17 thothahanthai
+!B8 U+0E18 thothongthai
+!B9 U+0E19 nonuthai
+!BA U+0E1A bobaimaithai
+!BB U+0E1B poplathai
+!BC U+0E1C phophungthai
+!BD U+0E1D fofathai
+!BE U+0E1E phophanthai
+!BF U+0E1F fofanthai
+!C0 U+0E20 phosamphaothai
+!C1 U+0E21 momathai
+!C2 U+0E22 yoyakthai
+!C3 U+0E23 roruathai
+!C4 U+0E24 ruthai
+!C5 U+0E25 lolingthai
+!C6 U+0E26 luthai
+!C7 U+0E27 wowaenthai
+!C8 U+0E28 sosalathai
+!C9 U+0E29 sorusithai
+!CA U+0E2A sosuathai
+!CB U+0E2B hohipthai
+!CC U+0E2C lochulathai
+!CD U+0E2D oangthai
+!CE U+0E2E honokhukthai
+!CF U+0E2F paiyannoithai
+!D0 U+0E30 saraathai
+!D1 U+0E31 maihanakatthai
+!D2 U+0E32 saraaathai
+!D3 U+0E33 saraamthai
+!D4 U+0E34 saraithai
+!D5 U+0E35 saraiithai
+!D6 U+0E36 sarauethai
+!D7 U+0E37 saraueethai
+!D8 U+0E38 sarauthai
+!D9 U+0E39 sarauuthai
+!DA U+0E3A phinthuthai
+!DF U+0E3F bahtthai
+!E0 U+0E40 saraethai
+!E1 U+0E41 saraaethai
+!E2 U+0E42 saraothai
+!E3 U+0E43 saraaimaimuanthai
+!E4 U+0E44 saraaimaimalaithai
+!E5 U+0E45 lakkhangyaothai
+!E6 U+0E46 maiyamokthai
+!E7 U+0E47 maitaikhuthai
+!E8 U+0E48 maiekthai
+!E9 U+0E49 maithothai
+!EA U+0E4A maitrithai
+!EB U+0E4B maichattawathai
+!EC U+0E4C thanthakhatthai
+!ED U+0E4D nikhahitthai
+!EE U+0E4E yamakkanthai
+!EF U+0E4F fongmanthai
+!F0 U+0E50 zerothai
+!F1 U+0E51 onethai
+!F2 U+0E52 twothai
+!F3 U+0E53 threethai
+!F4 U+0E54 fourthai
+!F5 U+0E55 fivethai
+!F6 U+0E56 sixthai
+!F7 U+0E57 seventhai
+!F8 U+0E58 eightthai
+!F9 U+0E59 ninethai
+!FA U+0E5A angkhankhuthai
+!FB U+0E5B khomutthai

+ 1 - 0
font/helvetica.json

@@ -0,0 +1 @@
+{"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]}

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
font/helvetica_1251.json


BIN
font/helvetica_1251.z


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
font/helvetica_1253.json


BIN
font/helvetica_1253.z


+ 1 - 0
font/helveticab.json

@@ -0,0 +1 @@
+{"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]}

+ 1 - 0
font/helveticabi.json

@@ -0,0 +1 @@
+{"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]}

+ 1 - 0
font/helveticai.json

@@ -0,0 +1 @@
+{"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]}

+ 256 - 0
font/iso-8859-1.map

@@ -0,0 +1,256 @@
+!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+0080 .notdef
+!81 U+0081 .notdef
+!82 U+0082 .notdef
+!83 U+0083 .notdef
+!84 U+0084 .notdef
+!85 U+0085 .notdef
+!86 U+0086 .notdef
+!87 U+0087 .notdef
+!88 U+0088 .notdef
+!89 U+0089 .notdef
+!8A U+008A .notdef
+!8B U+008B .notdef
+!8C U+008C .notdef
+!8D U+008D .notdef
+!8E U+008E .notdef
+!8F U+008F .notdef
+!90 U+0090 .notdef
+!91 U+0091 .notdef
+!92 U+0092 .notdef
+!93 U+0093 .notdef
+!94 U+0094 .notdef
+!95 U+0095 .notdef
+!96 U+0096 .notdef
+!97 U+0097 .notdef
+!98 U+0098 .notdef
+!99 U+0099 .notdef
+!9A U+009A .notdef
+!9B U+009B .notdef
+!9C U+009C .notdef
+!9D U+009D .notdef
+!9E U+009E .notdef
+!9F U+009F .notdef
+!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

+ 248 - 0
font/iso-8859-11.map

@@ -0,0 +1,248 @@
+!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+0080 .notdef
+!81 U+0081 .notdef
+!82 U+0082 .notdef
+!83 U+0083 .notdef
+!84 U+0084 .notdef
+!85 U+0085 .notdef
+!86 U+0086 .notdef
+!87 U+0087 .notdef
+!88 U+0088 .notdef
+!89 U+0089 .notdef
+!8A U+008A .notdef
+!8B U+008B .notdef
+!8C U+008C .notdef
+!8D U+008D .notdef
+!8E U+008E .notdef
+!8F U+008F .notdef
+!90 U+0090 .notdef
+!91 U+0091 .notdef
+!92 U+0092 .notdef
+!93 U+0093 .notdef
+!94 U+0094 .notdef
+!95 U+0095 .notdef
+!96 U+0096 .notdef
+!97 U+0097 .notdef
+!98 U+0098 .notdef
+!99 U+0099 .notdef
+!9A U+009A .notdef
+!9B U+009B .notdef
+!9C U+009C .notdef
+!9D U+009D .notdef
+!9E U+009E .notdef
+!9F U+009F .notdef
+!A0 U+00A0 space
+!A1 U+0E01 kokaithai
+!A2 U+0E02 khokhaithai
+!A3 U+0E03 khokhuatthai
+!A4 U+0E04 khokhwaithai
+!A5 U+0E05 khokhonthai
+!A6 U+0E06 khorakhangthai
+!A7 U+0E07 ngonguthai
+!A8 U+0E08 chochanthai
+!A9 U+0E09 chochingthai
+!AA U+0E0A chochangthai
+!AB U+0E0B sosothai
+!AC U+0E0C chochoethai
+!AD U+0E0D yoyingthai
+!AE U+0E0E dochadathai
+!AF U+0E0F topatakthai
+!B0 U+0E10 thothanthai
+!B1 U+0E11 thonangmonthothai
+!B2 U+0E12 thophuthaothai
+!B3 U+0E13 nonenthai
+!B4 U+0E14 dodekthai
+!B5 U+0E15 totaothai
+!B6 U+0E16 thothungthai
+!B7 U+0E17 thothahanthai
+!B8 U+0E18 thothongthai
+!B9 U+0E19 nonuthai
+!BA U+0E1A bobaimaithai
+!BB U+0E1B poplathai
+!BC U+0E1C phophungthai
+!BD U+0E1D fofathai
+!BE U+0E1E phophanthai
+!BF U+0E1F fofanthai
+!C0 U+0E20 phosamphaothai
+!C1 U+0E21 momathai
+!C2 U+0E22 yoyakthai
+!C3 U+0E23 roruathai
+!C4 U+0E24 ruthai
+!C5 U+0E25 lolingthai
+!C6 U+0E26 luthai
+!C7 U+0E27 wowaenthai
+!C8 U+0E28 sosalathai
+!C9 U+0E29 sorusithai
+!CA U+0E2A sosuathai
+!CB U+0E2B hohipthai
+!CC U+0E2C lochulathai
+!CD U+0E2D oangthai
+!CE U+0E2E honokhukthai
+!CF U+0E2F paiyannoithai
+!D0 U+0E30 saraathai
+!D1 U+0E31 maihanakatthai
+!D2 U+0E32 saraaathai
+!D3 U+0E33 saraamthai
+!D4 U+0E34 saraithai
+!D5 U+0E35 saraiithai
+!D6 U+0E36 sarauethai
+!D7 U+0E37 saraueethai
+!D8 U+0E38 sarauthai
+!D9 U+0E39 sarauuthai
+!DA U+0E3A phinthuthai
+!DF U+0E3F bahtthai
+!E0 U+0E40 saraethai
+!E1 U+0E41 saraaethai
+!E2 U+0E42 saraothai
+!E3 U+0E43 saraaimaimuanthai
+!E4 U+0E44 saraaimaimalaithai
+!E5 U+0E45 lakkhangyaothai
+!E6 U+0E46 maiyamokthai
+!E7 U+0E47 maitaikhuthai
+!E8 U+0E48 maiekthai
+!E9 U+0E49 maithothai
+!EA U+0E4A maitrithai
+!EB U+0E4B maichattawathai
+!EC U+0E4C thanthakhatthai
+!ED U+0E4D nikhahitthai
+!EE U+0E4E yamakkanthai
+!EF U+0E4F fongmanthai
+!F0 U+0E50 zerothai
+!F1 U+0E51 onethai
+!F2 U+0E52 twothai
+!F3 U+0E53 threethai
+!F4 U+0E54 fourthai
+!F5 U+0E55 fivethai
+!F6 U+0E56 sixthai
+!F7 U+0E57 seventhai
+!F8 U+0E58 eightthai
+!F9 U+0E59 ninethai
+!FA U+0E5A angkhankhuthai
+!FB U+0E5B khomutthai

+ 256 - 0
font/iso-8859-15.map

@@ -0,0 +1,256 @@
+!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+0080 .notdef
+!81 U+0081 .notdef
+!82 U+0082 .notdef
+!83 U+0083 .notdef
+!84 U+0084 .notdef
+!85 U+0085 .notdef
+!86 U+0086 .notdef
+!87 U+0087 .notdef
+!88 U+0088 .notdef
+!89 U+0089 .notdef
+!8A U+008A .notdef
+!8B U+008B .notdef
+!8C U+008C .notdef
+!8D U+008D .notdef
+!8E U+008E .notdef
+!8F U+008F .notdef
+!90 U+0090 .notdef
+!91 U+0091 .notdef
+!92 U+0092 .notdef
+!93 U+0093 .notdef
+!94 U+0094 .notdef
+!95 U+0095 .notdef
+!96 U+0096 .notdef
+!97 U+0097 .notdef
+!98 U+0098 .notdef
+!99 U+0099 .notdef
+!9A U+009A .notdef
+!9B U+009B .notdef
+!9C U+009C .notdef
+!9D U+009D .notdef
+!9E U+009E .notdef
+!9F U+009F .notdef
+!A0 U+00A0 space
+!A1 U+00A1 exclamdown
+!A2 U+00A2 cent
+!A3 U+00A3 sterling
+!A4 U+20AC Euro
+!A5 U+00A5 yen
+!A6 U+0160 Scaron
+!A7 U+00A7 section
+!A8 U+0161 scaron
+!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+017D Zcaron
+!B5 U+00B5 mu
+!B6 U+00B6 paragraph
+!B7 U+00B7 periodcentered
+!B8 U+017E zcaron
+!B9 U+00B9 onesuperior
+!BA U+00BA ordmasculine
+!BB U+00BB guillemotright
+!BC U+0152 OE
+!BD U+0153 oe
+!BE U+0178 Ydieresis
+!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

+ 256 - 0
font/iso-8859-16.map

@@ -0,0 +1,256 @@
+!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+0080 .notdef
+!81 U+0081 .notdef
+!82 U+0082 .notdef
+!83 U+0083 .notdef
+!84 U+0084 .notdef
+!85 U+0085 .notdef
+!86 U+0086 .notdef
+!87 U+0087 .notdef
+!88 U+0088 .notdef
+!89 U+0089 .notdef
+!8A U+008A .notdef
+!8B U+008B .notdef
+!8C U+008C .notdef
+!8D U+008D .notdef
+!8E U+008E .notdef
+!8F U+008F .notdef
+!90 U+0090 .notdef
+!91 U+0091 .notdef
+!92 U+0092 .notdef
+!93 U+0093 .notdef
+!94 U+0094 .notdef
+!95 U+0095 .notdef
+!96 U+0096 .notdef
+!97 U+0097 .notdef
+!98 U+0098 .notdef
+!99 U+0099 .notdef
+!9A U+009A .notdef
+!9B U+009B .notdef
+!9C U+009C .notdef
+!9D U+009D .notdef
+!9E U+009E .notdef
+!9F U+009F .notdef
+!A0 U+00A0 space
+!A1 U+0104 Aogonek
+!A2 U+0105 aogonek
+!A3 U+0141 Lslash
+!A4 U+20AC Euro
+!A5 U+201E quotedblbase
+!A6 U+0160 Scaron
+!A7 U+00A7 section
+!A8 U+0161 scaron
+!A9 U+00A9 copyright
+!AA U+0218 Scommaaccent
+!AB U+00AB guillemotleft
+!AC U+0179 Zacute
+!AD U+00AD hyphen
+!AE U+017A zacute
+!AF U+017B Zdotaccent
+!B0 U+00B0 degree
+!B1 U+00B1 plusminus
+!B2 U+010C Ccaron
+!B3 U+0142 lslash
+!B4 U+017D Zcaron
+!B5 U+201D quotedblright
+!B6 U+00B6 paragraph
+!B7 U+00B7 periodcentered
+!B8 U+017E zcaron
+!B9 U+010D ccaron
+!BA U+0219 scommaaccent
+!BB U+00BB guillemotright
+!BC U+0152 OE
+!BD U+0153 oe
+!BE U+0178 Ydieresis
+!BF U+017C zdotaccent
+!C0 U+00C0 Agrave
+!C1 U+00C1 Aacute
+!C2 U+00C2 Acircumflex
+!C3 U+0102 Abreve
+!C4 U+00C4 Adieresis
+!C5 U+0106 Cacute
+!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+0110 Dcroat
+!D1 U+0143 Nacute
+!D2 U+00D2 Ograve
+!D3 U+00D3 Oacute
+!D4 U+00D4 Ocircumflex
+!D5 U+0150 Ohungarumlaut
+!D6 U+00D6 Odieresis
+!D7 U+015A Sacute
+!D8 U+0170 Uhungarumlaut
+!D9 U+00D9 Ugrave
+!DA U+00DA Uacute
+!DB U+00DB Ucircumflex
+!DC U+00DC Udieresis
+!DD U+0118 Eogonek
+!DE U+021A Tcommaaccent
+!DF U+00DF germandbls
+!E0 U+00E0 agrave
+!E1 U+00E1 aacute
+!E2 U+00E2 acircumflex
+!E3 U+0103 abreve
+!E4 U+00E4 adieresis
+!E5 U+0107 cacute
+!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+0111 dcroat
+!F1 U+0144 nacute
+!F2 U+00F2 ograve
+!F3 U+00F3 oacute
+!F4 U+00F4 ocircumflex
+!F5 U+0151 ohungarumlaut
+!F6 U+00F6 odieresis
+!F7 U+015B sacute
+!F8 U+0171 uhungarumlaut
+!F9 U+00F9 ugrave
+!FA U+00FA uacute
+!FB U+00FB ucircumflex
+!FC U+00FC udieresis
+!FD U+0119 eogonek
+!FE U+021B tcommaaccent
+!FF U+00FF ydieresis

+ 256 - 0
font/iso-8859-2.map

@@ -0,0 +1,256 @@
+!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+0080 .notdef
+!81 U+0081 .notdef
+!82 U+0082 .notdef
+!83 U+0083 .notdef
+!84 U+0084 .notdef
+!85 U+0085 .notdef
+!86 U+0086 .notdef
+!87 U+0087 .notdef
+!88 U+0088 .notdef
+!89 U+0089 .notdef
+!8A U+008A .notdef
+!8B U+008B .notdef
+!8C U+008C .notdef
+!8D U+008D .notdef
+!8E U+008E .notdef
+!8F U+008F .notdef
+!90 U+0090 .notdef
+!91 U+0091 .notdef
+!92 U+0092 .notdef
+!93 U+0093 .notdef
+!94 U+0094 .notdef
+!95 U+0095 .notdef
+!96 U+0096 .notdef
+!97 U+0097 .notdef
+!98 U+0098 .notdef
+!99 U+0099 .notdef
+!9A U+009A .notdef
+!9B U+009B .notdef
+!9C U+009C .notdef
+!9D U+009D .notdef
+!9E U+009E .notdef
+!9F U+009F .notdef
+!A0 U+00A0 space
+!A1 U+0104 Aogonek
+!A2 U+02D8 breve
+!A3 U+0141 Lslash
+!A4 U+00A4 currency
+!A5 U+013D Lcaron
+!A6 U+015A Sacute
+!A7 U+00A7 section
+!A8 U+00A8 dieresis
+!A9 U+0160 Scaron
+!AA U+015E Scedilla
+!AB U+0164 Tcaron
+!AC U+0179 Zacute
+!AD U+00AD hyphen
+!AE U+017D Zcaron
+!AF U+017B Zdotaccent
+!B0 U+00B0 degree
+!B1 U+0105 aogonek
+!B2 U+02DB ogonek
+!B3 U+0142 lslash
+!B4 U+00B4 acute
+!B5 U+013E lcaron
+!B6 U+015B sacute
+!B7 U+02C7 caron
+!B8 U+00B8 cedilla
+!B9 U+0161 scaron
+!BA U+015F scedilla
+!BB U+0165 tcaron
+!BC U+017A zacute
+!BD U+02DD hungarumlaut
+!BE U+017E zcaron
+!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

+ 256 - 0
font/iso-8859-4.map

@@ -0,0 +1,256 @@
+!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+0080 .notdef
+!81 U+0081 .notdef
+!82 U+0082 .notdef
+!83 U+0083 .notdef
+!84 U+0084 .notdef
+!85 U+0085 .notdef
+!86 U+0086 .notdef
+!87 U+0087 .notdef
+!88 U+0088 .notdef
+!89 U+0089 .notdef
+!8A U+008A .notdef
+!8B U+008B .notdef
+!8C U+008C .notdef
+!8D U+008D .notdef
+!8E U+008E .notdef
+!8F U+008F .notdef
+!90 U+0090 .notdef
+!91 U+0091 .notdef
+!92 U+0092 .notdef
+!93 U+0093 .notdef
+!94 U+0094 .notdef
+!95 U+0095 .notdef
+!96 U+0096 .notdef
+!97 U+0097 .notdef
+!98 U+0098 .notdef
+!99 U+0099 .notdef
+!9A U+009A .notdef
+!9B U+009B .notdef
+!9C U+009C .notdef
+!9D U+009D .notdef
+!9E U+009E .notdef
+!9F U+009F .notdef
+!A0 U+00A0 space
+!A1 U+0104 Aogonek
+!A2 U+0138 kgreenlandic
+!A3 U+0156 Rcommaaccent
+!A4 U+00A4 currency
+!A5 U+0128 Itilde
+!A6 U+013B Lcommaaccent
+!A7 U+00A7 section
+!A8 U+00A8 dieresis
+!A9 U+0160 Scaron
+!AA U+0112 Emacron
+!AB U+0122 Gcommaaccent
+!AC U+0166 Tbar
+!AD U+00AD hyphen
+!AE U+017D Zcaron
+!AF U+00AF macron
+!B0 U+00B0 degree
+!B1 U+0105 aogonek
+!B2 U+02DB ogonek
+!B3 U+0157 rcommaaccent
+!B4 U+00B4 acute
+!B5 U+0129 itilde
+!B6 U+013C lcommaaccent
+!B7 U+02C7 caron
+!B8 U+00B8 cedilla
+!B9 U+0161 scaron
+!BA U+0113 emacron
+!BB U+0123 gcommaaccent
+!BC U+0167 tbar
+!BD U+014A Eng
+!BE U+017E zcaron
+!BF U+014B eng
+!C0 U+0100 Amacron
+!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+012E Iogonek
+!C8 U+010C Ccaron
+!C9 U+00C9 Eacute
+!CA U+0118 Eogonek
+!CB U+00CB Edieresis
+!CC U+0116 Edotaccent
+!CD U+00CD Iacute
+!CE U+00CE Icircumflex
+!CF U+012A Imacron
+!D0 U+0110 Dcroat
+!D1 U+0145 Ncommaaccent
+!D2 U+014C Omacron
+!D3 U+0136 Kcommaaccent
+!D4 U+00D4 Ocircumflex
+!D5 U+00D5 Otilde
+!D6 U+00D6 Odieresis
+!D7 U+00D7 multiply
+!D8 U+00D8 Oslash
+!D9 U+0172 Uogonek
+!DA U+00DA Uacute
+!DB U+00DB Ucircumflex
+!DC U+00DC Udieresis
+!DD U+0168 Utilde
+!DE U+016A Umacron
+!DF U+00DF germandbls
+!E0 U+0101 amacron
+!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+012F iogonek
+!E8 U+010D ccaron
+!E9 U+00E9 eacute
+!EA U+0119 eogonek
+!EB U+00EB edieresis
+!EC U+0117 edotaccent
+!ED U+00ED iacute
+!EE U+00EE icircumflex
+!EF U+012B imacron
+!F0 U+0111 dcroat
+!F1 U+0146 ncommaaccent
+!F2 U+014D omacron
+!F3 U+0137 kcommaaccent
+!F4 U+00F4 ocircumflex
+!F5 U+00F5 otilde
+!F6 U+00F6 odieresis
+!F7 U+00F7 divide
+!F8 U+00F8 oslash
+!F9 U+0173 uogonek
+!FA U+00FA uacute
+!FB U+00FB ucircumflex
+!FC U+00FC udieresis
+!FD U+0169 utilde
+!FE U+016B umacron
+!FF U+02D9 dotaccent

+ 256 - 0
font/iso-8859-5.map

@@ -0,0 +1,256 @@
+!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+0080 .notdef
+!81 U+0081 .notdef
+!82 U+0082 .notdef
+!83 U+0083 .notdef
+!84 U+0084 .notdef
+!85 U+0085 .notdef
+!86 U+0086 .notdef
+!87 U+0087 .notdef
+!88 U+0088 .notdef
+!89 U+0089 .notdef
+!8A U+008A .notdef
+!8B U+008B .notdef
+!8C U+008C .notdef
+!8D U+008D .notdef
+!8E U+008E .notdef
+!8F U+008F .notdef
+!90 U+0090 .notdef
+!91 U+0091 .notdef
+!92 U+0092 .notdef
+!93 U+0093 .notdef
+!94 U+0094 .notdef
+!95 U+0095 .notdef
+!96 U+0096 .notdef
+!97 U+0097 .notdef
+!98 U+0098 .notdef
+!99 U+0099 .notdef
+!9A U+009A .notdef
+!9B U+009B .notdef
+!9C U+009C .notdef
+!9D U+009D .notdef
+!9E U+009E .notdef
+!9F U+009F .notdef
+!A0 U+00A0 space
+!A1 U+0401 afii10023
+!A2 U+0402 afii10051
+!A3 U+0403 afii10052
+!A4 U+0404 afii10053
+!A5 U+0405 afii10054
+!A6 U+0406 afii10055
+!A7 U+0407 afii10056
+!A8 U+0408 afii10057
+!A9 U+0409 afii10058
+!AA U+040A afii10059
+!AB U+040B afii10060
+!AC U+040C afii10061
+!AD U+00AD hyphen
+!AE U+040E afii10062
+!AF U+040F afii10145
+!B0 U+0410 afii10017
+!B1 U+0411 afii10018
+!B2 U+0412 afii10019
+!B3 U+0413 afii10020
+!B4 U+0414 afii10021
+!B5 U+0415 afii10022
+!B6 U+0416 afii10024
+!B7 U+0417 afii10025
+!B8 U+0418 afii10026
+!B9 U+0419 afii10027
+!BA U+041A afii10028
+!BB U+041B afii10029
+!BC U+041C afii10030
+!BD U+041D afii10031
+!BE U+041E afii10032
+!BF U+041F afii10033
+!C0 U+0420 afii10034
+!C1 U+0421 afii10035
+!C2 U+0422 afii10036
+!C3 U+0423 afii10037
+!C4 U+0424 afii10038
+!C5 U+0425 afii10039
+!C6 U+0426 afii10040
+!C7 U+0427 afii10041
+!C8 U+0428 afii10042
+!C9 U+0429 afii10043
+!CA U+042A afii10044
+!CB U+042B afii10045
+!CC U+042C afii10046
+!CD U+042D afii10047
+!CE U+042E afii10048
+!CF U+042F afii10049
+!D0 U+0430 afii10065
+!D1 U+0431 afii10066
+!D2 U+0432 afii10067
+!D3 U+0433 afii10068
+!D4 U+0434 afii10069
+!D5 U+0435 afii10070
+!D6 U+0436 afii10072
+!D7 U+0437 afii10073
+!D8 U+0438 afii10074
+!D9 U+0439 afii10075
+!DA U+043A afii10076
+!DB U+043B afii10077
+!DC U+043C afii10078
+!DD U+043D afii10079
+!DE U+043E afii10080
+!DF U+043F afii10081
+!E0 U+0440 afii10082
+!E1 U+0441 afii10083
+!E2 U+0442 afii10084
+!E3 U+0443 afii10085
+!E4 U+0444 afii10086
+!E5 U+0445 afii10087
+!E6 U+0446 afii10088
+!E7 U+0447 afii10089
+!E8 U+0448 afii10090
+!E9 U+0449 afii10091
+!EA U+044A afii10092
+!EB U+044B afii10093
+!EC U+044C afii10094
+!ED U+044D afii10095
+!EE U+044E afii10096
+!EF U+044F afii10097
+!F0 U+2116 afii61352
+!F1 U+0451 afii10071
+!F2 U+0452 afii10099
+!F3 U+0453 afii10100
+!F4 U+0454 afii10101
+!F5 U+0455 afii10102
+!F6 U+0456 afii10103
+!F7 U+0457 afii10104
+!F8 U+0458 afii10105
+!F9 U+0459 afii10106
+!FA U+045A afii10107
+!FB U+045B afii10108
+!FC U+045C afii10109
+!FD U+00A7 section
+!FE U+045E afii10110
+!FF U+045F afii10193

+ 250 - 0
font/iso-8859-7.map

@@ -0,0 +1,250 @@
+!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+0080 .notdef
+!81 U+0081 .notdef
+!82 U+0082 .notdef
+!83 U+0083 .notdef
+!84 U+0084 .notdef
+!85 U+0085 .notdef
+!86 U+0086 .notdef
+!87 U+0087 .notdef
+!88 U+0088 .notdef
+!89 U+0089 .notdef
+!8A U+008A .notdef
+!8B U+008B .notdef
+!8C U+008C .notdef
+!8D U+008D .notdef
+!8E U+008E .notdef
+!8F U+008F .notdef
+!90 U+0090 .notdef
+!91 U+0091 .notdef
+!92 U+0092 .notdef
+!93 U+0093 .notdef
+!94 U+0094 .notdef
+!95 U+0095 .notdef
+!96 U+0096 .notdef
+!97 U+0097 .notdef
+!98 U+0098 .notdef
+!99 U+0099 .notdef
+!9A U+009A .notdef
+!9B U+009B .notdef
+!9C U+009C .notdef
+!9D U+009D .notdef
+!9E U+009E .notdef
+!9F U+009F .notdef
+!A0 U+00A0 space
+!A1 U+2018 quoteleft
+!A2 U+2019 quoteright
+!A3 U+00A3 sterling
+!A6 U+00A6 brokenbar
+!A7 U+00A7 section
+!A8 U+00A8 dieresis
+!A9 U+00A9 copyright
+!AB U+00AB guillemotleft
+!AC U+00AC logicalnot
+!AD U+00AD hyphen
+!AF U+2015 afii00208
+!B0 U+00B0 degree
+!B1 U+00B1 plusminus
+!B2 U+00B2 twosuperior
+!B3 U+00B3 threesuperior
+!B4 U+0384 tonos
+!B5 U+0385 dieresistonos
+!B6 U+0386 Alphatonos
+!B7 U+00B7 periodcentered
+!B8 U+0388 Epsilontonos
+!B9 U+0389 Etatonos
+!BA U+038A Iotatonos
+!BB U+00BB guillemotright
+!BC U+038C Omicrontonos
+!BD U+00BD onehalf
+!BE U+038E Upsilontonos
+!BF U+038F Omegatonos
+!C0 U+0390 iotadieresistonos
+!C1 U+0391 Alpha
+!C2 U+0392 Beta
+!C3 U+0393 Gamma
+!C4 U+0394 Delta
+!C5 U+0395 Epsilon
+!C6 U+0396 Zeta
+!C7 U+0397 Eta
+!C8 U+0398 Theta
+!C9 U+0399 Iota
+!CA U+039A Kappa
+!CB U+039B Lambda
+!CC U+039C Mu
+!CD U+039D Nu
+!CE U+039E Xi
+!CF U+039F Omicron
+!D0 U+03A0 Pi
+!D1 U+03A1 Rho
+!D3 U+03A3 Sigma
+!D4 U+03A4 Tau
+!D5 U+03A5 Upsilon
+!D6 U+03A6 Phi
+!D7 U+03A7 Chi
+!D8 U+03A8 Psi
+!D9 U+03A9 Omega
+!DA U+03AA Iotadieresis
+!DB U+03AB Upsilondieresis
+!DC U+03AC alphatonos
+!DD U+03AD epsilontonos
+!DE U+03AE etatonos
+!DF U+03AF iotatonos
+!E0 U+03B0 upsilondieresistonos
+!E1 U+03B1 alpha
+!E2 U+03B2 beta
+!E3 U+03B3 gamma
+!E4 U+03B4 delta
+!E5 U+03B5 epsilon
+!E6 U+03B6 zeta
+!E7 U+03B7 eta
+!E8 U+03B8 theta
+!E9 U+03B9 iota
+!EA U+03BA kappa
+!EB U+03BB lambda
+!EC U+03BC mu
+!ED U+03BD nu
+!EE U+03BE xi
+!EF U+03BF omicron
+!F0 U+03C0 pi
+!F1 U+03C1 rho
+!F2 U+03C2 sigma1
+!F3 U+03C3 sigma
+!F4 U+03C4 tau
+!F5 U+03C5 upsilon
+!F6 U+03C6 phi
+!F7 U+03C7 chi
+!F8 U+03C8 psi
+!F9 U+03C9 omega
+!FA U+03CA iotadieresis
+!FB U+03CB upsilondieresis
+!FC U+03CC omicrontonos
+!FD U+03CD upsilontonos
+!FE U+03CE omegatonos

+ 256 - 0
font/iso-8859-9.map

@@ -0,0 +1,256 @@
+!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+0080 .notdef
+!81 U+0081 .notdef
+!82 U+0082 .notdef
+!83 U+0083 .notdef
+!84 U+0084 .notdef
+!85 U+0085 .notdef
+!86 U+0086 .notdef
+!87 U+0087 .notdef
+!88 U+0088 .notdef
+!89 U+0089 .notdef
+!8A U+008A .notdef
+!8B U+008B .notdef
+!8C U+008C .notdef
+!8D U+008D .notdef
+!8E U+008E .notdef
+!8F U+008F .notdef
+!90 U+0090 .notdef
+!91 U+0091 .notdef
+!92 U+0092 .notdef
+!93 U+0093 .notdef
+!94 U+0094 .notdef
+!95 U+0095 .notdef
+!96 U+0096 .notdef
+!97 U+0097 .notdef
+!98 U+0098 .notdef
+!99 U+0099 .notdef
+!9A U+009A .notdef
+!9B U+009B .notdef
+!9C U+009C .notdef
+!9D U+009D .notdef
+!9E U+009E .notdef
+!9F U+009F .notdef
+!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+011E Gbreve
+!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+0130 Idotaccent
+!DE U+015E Scedilla
+!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+011F gbreve
+!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+0131 dotlessi
+!FE U+015F scedilla
+!FF U+00FF ydieresis

+ 256 - 0
font/koi8-r.map

@@ -0,0 +1,256 @@
+!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+2500 SF100000
+!81 U+2502 SF110000
+!82 U+250C SF010000
+!83 U+2510 SF030000
+!84 U+2514 SF020000
+!85 U+2518 SF040000
+!86 U+251C SF080000
+!87 U+2524 SF090000
+!88 U+252C SF060000
+!89 U+2534 SF070000
+!8A U+253C SF050000
+!8B U+2580 upblock
+!8C U+2584 dnblock
+!8D U+2588 block
+!8E U+258C lfblock
+!8F U+2590 rtblock
+!90 U+2591 ltshade
+!91 U+2592 shade
+!92 U+2593 dkshade
+!93 U+2320 integraltp
+!94 U+25A0 filledbox
+!95 U+2219 periodcentered
+!96 U+221A radical
+!97 U+2248 approxequal
+!98 U+2264 lessequal
+!99 U+2265 greaterequal
+!9A U+00A0 space
+!9B U+2321 integralbt
+!9C U+00B0 degree
+!9D U+00B2 twosuperior
+!9E U+00B7 periodcentered
+!9F U+00F7 divide
+!A0 U+2550 SF430000
+!A1 U+2551 SF240000
+!A2 U+2552 SF510000
+!A3 U+0451 afii10071
+!A4 U+2553 SF520000
+!A5 U+2554 SF390000
+!A6 U+2555 SF220000
+!A7 U+2556 SF210000
+!A8 U+2557 SF250000
+!A9 U+2558 SF500000
+!AA U+2559 SF490000
+!AB U+255A SF380000
+!AC U+255B SF280000
+!AD U+255C SF270000
+!AE U+255D SF260000
+!AF U+255E SF360000
+!B0 U+255F SF370000
+!B1 U+2560 SF420000
+!B2 U+2561 SF190000
+!B3 U+0401 afii10023
+!B4 U+2562 SF200000
+!B5 U+2563 SF230000
+!B6 U+2564 SF470000
+!B7 U+2565 SF480000
+!B8 U+2566 SF410000
+!B9 U+2567 SF450000
+!BA U+2568 SF460000
+!BB U+2569 SF400000
+!BC U+256A SF540000
+!BD U+256B SF530000
+!BE U+256C SF440000
+!BF U+00A9 copyright
+!C0 U+044E afii10096
+!C1 U+0430 afii10065
+!C2 U+0431 afii10066
+!C3 U+0446 afii10088
+!C4 U+0434 afii10069
+!C5 U+0435 afii10070
+!C6 U+0444 afii10086
+!C7 U+0433 afii10068
+!C8 U+0445 afii10087
+!C9 U+0438 afii10074
+!CA U+0439 afii10075
+!CB U+043A afii10076
+!CC U+043B afii10077
+!CD U+043C afii10078
+!CE U+043D afii10079
+!CF U+043E afii10080
+!D0 U+043F afii10081
+!D1 U+044F afii10097
+!D2 U+0440 afii10082
+!D3 U+0441 afii10083
+!D4 U+0442 afii10084
+!D5 U+0443 afii10085
+!D6 U+0436 afii10072
+!D7 U+0432 afii10067
+!D8 U+044C afii10094
+!D9 U+044B afii10093
+!DA U+0437 afii10073
+!DB U+0448 afii10090
+!DC U+044D afii10095
+!DD U+0449 afii10091
+!DE U+0447 afii10089
+!DF U+044A afii10092
+!E0 U+042E afii10048
+!E1 U+0410 afii10017
+!E2 U+0411 afii10018
+!E3 U+0426 afii10040
+!E4 U+0414 afii10021
+!E5 U+0415 afii10022
+!E6 U+0424 afii10038
+!E7 U+0413 afii10020
+!E8 U+0425 afii10039
+!E9 U+0418 afii10026
+!EA U+0419 afii10027
+!EB U+041A afii10028
+!EC U+041B afii10029
+!ED U+041C afii10030
+!EE U+041D afii10031
+!EF U+041E afii10032
+!F0 U+041F afii10033
+!F1 U+042F afii10049
+!F2 U+0420 afii10034
+!F3 U+0421 afii10035
+!F4 U+0422 afii10036
+!F5 U+0423 afii10037
+!F6 U+0416 afii10024
+!F7 U+0412 afii10019
+!F8 U+042C afii10046
+!F9 U+042B afii10045
+!FA U+0417 afii10025
+!FB U+0428 afii10042
+!FC U+042D afii10047
+!FD U+0429 afii10043
+!FE U+0427 afii10041
+!FF U+042A afii10044

+ 256 - 0
font/koi8-u.map

@@ -0,0 +1,256 @@
+!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+2500 SF100000
+!81 U+2502 SF110000
+!82 U+250C SF010000
+!83 U+2510 SF030000
+!84 U+2514 SF020000
+!85 U+2518 SF040000
+!86 U+251C SF080000
+!87 U+2524 SF090000
+!88 U+252C SF060000
+!89 U+2534 SF070000
+!8A U+253C SF050000
+!8B U+2580 upblock
+!8C U+2584 dnblock
+!8D U+2588 block
+!8E U+258C lfblock
+!8F U+2590 rtblock
+!90 U+2591 ltshade
+!91 U+2592 shade
+!92 U+2593 dkshade
+!93 U+2320 integraltp
+!94 U+25A0 filledbox
+!95 U+2022 bullet
+!96 U+221A radical
+!97 U+2248 approxequal
+!98 U+2264 lessequal
+!99 U+2265 greaterequal
+!9A U+00A0 space
+!9B U+2321 integralbt
+!9C U+00B0 degree
+!9D U+00B2 twosuperior
+!9E U+00B7 periodcentered
+!9F U+00F7 divide
+!A0 U+2550 SF430000
+!A1 U+2551 SF240000
+!A2 U+2552 SF510000
+!A3 U+0451 afii10071
+!A4 U+0454 afii10101
+!A5 U+2554 SF390000
+!A6 U+0456 afii10103
+!A7 U+0457 afii10104
+!A8 U+2557 SF250000
+!A9 U+2558 SF500000
+!AA U+2559 SF490000
+!AB U+255A SF380000
+!AC U+255B SF280000
+!AD U+0491 afii10098
+!AE U+255D SF260000
+!AF U+255E SF360000
+!B0 U+255F SF370000
+!B1 U+2560 SF420000
+!B2 U+2561 SF190000
+!B3 U+0401 afii10023
+!B4 U+0404 afii10053
+!B5 U+2563 SF230000
+!B6 U+0406 afii10055
+!B7 U+0407 afii10056
+!B8 U+2566 SF410000
+!B9 U+2567 SF450000
+!BA U+2568 SF460000
+!BB U+2569 SF400000
+!BC U+256A SF540000
+!BD U+0490 afii10050
+!BE U+256C SF440000
+!BF U+00A9 copyright
+!C0 U+044E afii10096
+!C1 U+0430 afii10065
+!C2 U+0431 afii10066
+!C3 U+0446 afii10088
+!C4 U+0434 afii10069
+!C5 U+0435 afii10070
+!C6 U+0444 afii10086
+!C7 U+0433 afii10068
+!C8 U+0445 afii10087
+!C9 U+0438 afii10074
+!CA U+0439 afii10075
+!CB U+043A afii10076
+!CC U+043B afii10077
+!CD U+043C afii10078
+!CE U+043D afii10079
+!CF U+043E afii10080
+!D0 U+043F afii10081
+!D1 U+044F afii10097
+!D2 U+0440 afii10082
+!D3 U+0441 afii10083
+!D4 U+0442 afii10084
+!D5 U+0443 afii10085
+!D6 U+0436 afii10072
+!D7 U+0432 afii10067
+!D8 U+044C afii10094
+!D9 U+044B afii10093
+!DA U+0437 afii10073
+!DB U+0448 afii10090
+!DC U+044D afii10095
+!DD U+0449 afii10091
+!DE U+0447 afii10089
+!DF U+044A afii10092
+!E0 U+042E afii10048
+!E1 U+0410 afii10017
+!E2 U+0411 afii10018
+!E3 U+0426 afii10040
+!E4 U+0414 afii10021
+!E5 U+0415 afii10022
+!E6 U+0424 afii10038
+!E7 U+0413 afii10020
+!E8 U+0425 afii10039
+!E9 U+0418 afii10026
+!EA U+0419 afii10027
+!EB U+041A afii10028
+!EC U+041B afii10029
+!ED U+041C afii10030
+!EE U+041D afii10031
+!EF U+041E afii10032
+!F0 U+041F afii10033
+!F1 U+042F afii10049
+!F2 U+0420 afii10034
+!F3 U+0421 afii10035
+!F4 U+0422 afii10036
+!F5 U+0423 afii10037
+!F6 U+0416 afii10024
+!F7 U+0412 afii10019
+!F8 U+042C afii10046
+!F9 U+042B afii10045
+!FA U+0417 afii10025
+!FB U+0428 afii10042
+!FC U+042D afii10047
+!FD U+0429 afii10043
+!FE U+0427 afii10041
+!FF U+042A afii10044

+ 1 - 0
font/times.json

@@ -0,0 +1 @@
+{"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]}

+ 1 - 0
font/timesb.json

@@ -0,0 +1 @@
+{"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]}

+ 1 - 0
font/timesbi.json

@@ -0,0 +1 @@
+{"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]}

+ 1 - 0
font/timesi.json

@@ -0,0 +1 @@
+{"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]}

+ 1 - 0
font/zapfdingbats.json

@@ -0,0 +1 @@
+{"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]}

+ 5007 - 0
fpdf.go

@@ -0,0 +1,5007 @@
+/*
+ * 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
+	modDate      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"
+	} else {
+		orientationStr = strings.ToLower(orientationStr)
+	}
+	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.pageBoxes = make(map[int]map[string]PageBox)
+	f.defPageBoxes = make(map[string]PageBox)
+	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[string]Template)
+	f.templateObjects = make(map[string]int)
+	f.importedObjs = make(map[string][]byte, 0)
+	f.importedObjPos = make(map[string]map[int]string, 0)
+	f.importedTplObjs = make(map[string]string)
+	f.importedTplIDs = make(map[string]int, 0)
+	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.pageAttachments = make([][]annotationAttach, 0, 8)
+	f.pageAttachments = append(f.pageAttachments, []annotationAttach{}) //
+	f.aliasMap = make(map[string]string)
+	f.inHeader = false
+	f.inFooter = false
+	f.lasth = 0
+	f.fontFamily = ""
+	f.fontStyle = ""
+	f.SetFontSize(12)
+	f.underline = false
+	f.strikeout = 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["a6"] = SizeType{297.64, 420.94}
+	f.stdPageSizes["a2"] = SizeType{1190.55, 1683.78}
+	f.stdPageSizes["a1"] = SizeType{1683.78, 2383.94}
+	f.stdPageSizes["letter"] = SizeType{612, 792}
+	f.stdPageSizes["legal"] = SizeType{612, 1008}
+	f.stdPageSizes["tabloid"] = SizeType{792, 1224}
+	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
+	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.spotColorMap = make(map[string]spotColorType)
+	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.SetProducer("FPDF "+cnFpdfVersion, true)
+	f.layerInit()
+	f.catalogSort = gl.catalogSort
+	f.creationDate = gl.creationDate
+	f.modDate = gl.modDate
+	f.userUnderlineThickness = 1
+	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", "Legal", or "Tabloid". 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
+}
+
+// SetPageBoxRec sets the page box for the current page, and any following
+// pages. Allowable types are trim, trimbox, crop, cropbox, bleed, bleedbox,
+// art and artbox box types are case insensitive. See SetPageBox() for a method
+// that specifies the coordinates and extent of the page box individually.
+func (f *Fpdf) SetPageBoxRec(t string, pb PageBox) {
+	switch strings.ToLower(t) {
+	case "trim":
+		fallthrough
+	case "trimbox":
+		t = "TrimBox"
+	case "crop":
+		fallthrough
+	case "cropbox":
+		t = "CropBox"
+	case "bleed":
+		fallthrough
+	case "bleedbox":
+		t = "BleedBox"
+	case "art":
+		fallthrough
+	case "artbox":
+		t = "ArtBox"
+	default:
+		f.err = fmt.Errorf("%s is not a valid page box type", t)
+		return
+	}
+
+	pb.X = pb.X * f.k
+	pb.Y = pb.Y * f.k
+	pb.Wd = (pb.Wd * f.k) + pb.X
+	pb.Ht = (pb.Ht * f.k) + pb.Y
+
+	if f.page > 0 {
+		f.pageBoxes[f.page][t] = pb
+	}
+
+	// always override. page defaults are supplied in addPage function
+	f.defPageBoxes[t] = pb
+}
+
+// SetPageBox sets the page box for the current page, and any following pages.
+// Allowable types are trim, trimbox, crop, cropbox, bleed, bleedbox, art and
+// artbox box types are case insensitive.
+func (f *Fpdf) SetPageBox(t string, x, y, wd, ht float64) {
+	f.SetPageBoxRec(t, PageBox{SizeType{Wd: wd, Ht: ht}, PointType{X: x, Y: y}})
+}
+
+// SetPage sets the current page to that of a valid page in the PDF document.
+// pageNum is one-based. The SetPage() example demonstrates this method.
+func (f *Fpdf) SetPage(pageNum int) {
+	if (pageNum > 0) && (pageNum < len(f.pages)) {
+		f.page = pageNum
+	}
+}
+
+// PageCount returns the number of pages currently in the document. Since page
+// numbers in gofpdf are one-based, the page count is the same as the page
+// number of the current last page.
+func (f *Fpdf) PageCount() int {
+	return len(f.pages) - 1
+}
+
+// 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
+}
+
+// SetHeaderFuncMode sets the function that lets the application render the
+// page header. See SetHeaderFunc() for more details. The value for homeMode
+// should be set to true to have the current position set to the left and top
+// margin after the header function is called.
+func (f *Fpdf) SetHeaderFuncMode(fnc func(), homeMode bool) {
+	f.headerFnc = fnc
+	f.headerHomeMode = homeMode
+}
+
+// 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.
+//
+// A header is a convenient place to put background content that repeats on
+// each page such as a watermark. When this is done, remember to reset the X
+// and Y values so the normal content begins where expected. Including a
+// watermark on each page is demonstrated in the example for TransformRotate.
+//
+// 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. See
+// SetFooterFuncLpi for a similar function that passes a last page indicator.
+//
+// This method is demonstrated in the example for AddPage().
+func (f *Fpdf) SetFooterFunc(fnc func()) {
+	f.footerFnc = fnc
+	f.footerFncLpi = nil
+}
+
+// SetFooterFuncLpi 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. It is passed a
+// boolean that is true if the last page of the document is being rendered. 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.
+func (f *Fpdf) SetFooterFuncLpi(fnc func(lastPage bool)) {
+	f.footerFncLpi = fnc
+	f.footerFnc = nil
+}
+
+// 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
+}
+
+// GetAutoPageBreak returns true if automatic pages breaks are enabled, false
+// otherwise. This is followed by the triggering limit from the bottom of the
+// page. This value applies only if automatic page breaks are enabled.
+func (f *Fpdf) GetAutoPageBreak() (auto bool, margin float64) {
+	auto = f.autoPageBreak
+	margin = f.bMargin
+	return
+}
+
+// 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
+}
+
+// SetProducer defines the producer of the document. isUTF8 indicates if the string
+// is encoded in ISO-8859-1 (false) or UTF-8 (true).
+func (f *Fpdf) SetProducer(producerStr string, isUTF8 bool) {
+	if isUTF8 {
+		producerStr = utf8toutf16(producerStr)
+	}
+	f.producer = producerStr
+}
+
+// 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
+}
+
+// SetXmpMetadata defines XMP metadata that will be embedded with the document.
+func (f *Fpdf) SetXmpMetadata(xmpStream []byte) {
+	f.xmp = xmpStream
+}
+
+// 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
+}
+
+// RTL enables right-to-left mode
+func (f *Fpdf) RTL() {
+	f.isRTL = true
+}
+
+// LTR disables right-to-left mode
+func (f *Fpdf) LTR() {
+	f.isRTL = false
+}
+
+// open begins a 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
+	f.inFooter = true
+	if f.footerFnc != nil {
+		f.footerFnc()
+	} else if f.footerFncLpi != nil {
+		f.footerFncLpi(true)
+	}
+	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.page != len(f.pages)-1 {
+		f.page = len(f.pages) - 1
+	}
+	if f.state == 0 {
+		f.open()
+	}
+	familyStr := f.fontFamily
+	style := f.fontStyle
+	if f.underline {
+		style += "U"
+	}
+	if f.strikeout {
+		style += "S"
+	}
+	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 {
+		f.inFooter = true
+		// Page footer avoid double call on footer.
+		if f.footerFnc != nil {
+			f.footerFnc()
+
+		} else if f.footerFncLpi != nil {
+			f.footerFncLpi(false) // not last page.
+		}
+		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
+		if f.headerHomeMode {
+			f.SetHomeXY()
+		}
+	}
+	// 	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
+}
+
+func colorComp(v int) (int, float64) {
+	if v < 0 {
+		v = 0
+	} else if v > 255 {
+		v = 255
+	}
+	return v, float64(v) / 255.0
+}
+
+func rgbColorValue(r, g, b int, grayStr, fullStr string) (clr colorType) {
+	clr.ir, clr.r = colorComp(r)
+	clr.ig, clr.g = colorComp(g)
+	clr.ib, clr.b = colorComp(b)
+	clr.mode = colorModeRGB
+	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.setDrawColor(r, g, b)
+}
+
+func (f *Fpdf) setDrawColor(r, g, b int) {
+	f.color.draw = rgbColorValue(r, g, b, "G", "RG")
+	if f.page > 0 {
+		f.out(f.color.draw.str)
+	}
+}
+
+// GetDrawColor returns the most recently set draw color as RGB components (0 -
+// 255). This will not be the current value if a draw color of some other type
+// (for example, spot) has been more recently set.
+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.setFillColor(r, g, b)
+}
+
+func (f *Fpdf) setFillColor(r, g, b int) {
+	f.color.fill = rgbColorValue(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 most recently set fill color as RGB components (0 -
+// 255). This will not be the current value if a fill color of some other type
+// (for example, spot) has been more recently set.
+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.setTextColor(r, g, b)
+}
+
+func (f *Fpdf) setTextColor(r, g, b int) {
+	f.color.text = rgbColorValue(r, g, b, "g", "rg")
+	f.colorFlag = f.color.fill.str != f.color.text.str
+}
+
+// GetTextColor returns the most recently set text color as RGB components (0 -
+// 255). This will not be the current value if a text color of some other type
+// (for example, spot) has been more recently set.
+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 := f.GetStringSymbolWidth(s)
+	return float64(w) * f.fontSize / 1000
+}
+
+// GetStringSymbolWidth returns the length of a string in glyf units. A font must be
+// currently selected.
+func (f *Fpdf) GetStringSymbolWidth(s string) int {
+	if f.err != nil {
+		return 0
+	}
+	w := 0
+	if f.isCurrentUTF8 {
+		unicode := []rune(s)
+		for _, char := range unicode {
+			intChar := int(char)
+			if len(f.currentFont.Cw) >= intChar && f.currentFont.Cw[intChar] > 0 {
+				if f.currentFont.Cw[intChar] != 65535 {
+					w += f.currentFont.Cw[intChar]
+				}
+			} else if f.currentFont.Desc.MissingWidth != 0 {
+				w += f.currentFont.Desc.MissingWidth
+			} else {
+				w += 500
+			}
+		}
+	} else {
+		for _, ch := range []byte(s) {
+			if ch == 0 {
+				break
+			}
+			w += f.currentFont.Cw[ch]
+		}
+	}
+	return w
+}
+
+// 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.setLineWidth(width)
+}
+
+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
+	}
+	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
+	}
+	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
+
+	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))
+}
+
+// RoundedRect 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.
+// The rounded corners of the rectangle are specified by radius r. corners is a
+// string that includes "1" to round the upper left corner, "2" to round the
+// upper right corner, "3" to round the lower right corner, and "4" to round
+// the lower left corner. The RoundedRect example demonstrates this method.
+func (f *Fpdf) RoundedRect(x, y, w, h, r float64, corners string, stylestr string) {
+	// This routine was adapted by Brigham Thompson from a script by Christophe Prugnaud
+	var rTL, rTR, rBR, rBL float64 // zero means no rounded corner
+	if strings.Contains(corners, "1") {
+		rTL = r
+	}
+	if strings.Contains(corners, "2") {
+		rTR = r
+	}
+	if strings.Contains(corners, "3") {
+		rBR = r
+	}
+	if strings.Contains(corners, "4") {
+		rBL = r
+	}
+	f.RoundedRectExt(x, y, w, h, rTL, rTR, rBR, rBL, stylestr)
+}
+
+// RoundedRectExt behaves the same as RoundedRect() but supports a different
+// radius for each corner. A zero radius means squared corner. See
+// RoundedRect() for more details. This method is demonstrated in the
+// RoundedRect() example.
+func (f *Fpdf) RoundedRectExt(x, y, w, h, rTL, rTR, rBR, rBL float64, stylestr string) {
+	f.roundedRectPath(x, y, w, h, rTL, rTR, rBR, rBL)
+	f.out(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)
+}
+
+// point outputs current point
+func (f *Fpdf) point(x, y float64) {
+	f.outf("%.2f %.2f m", x*f.k, (f.h-y)*f.k)
+}
+
+// curve 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 {
+		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, r1, g1, b1, r2, g2, b2 int, x1, y1, x2, y2, r float64) {
+	pos := len(f.gradientList)
+	clr1 := rgbColorValue(r1, g1, b1, "", "")
+	clr2 := rgbColorValue(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, 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, 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.ClipRoundedRectExt(x, y, w, h, r, r, r, r, outline)
+}
+
+// ClipRoundedRectExt behaves the same as ClipRoundedRect() but supports a
+// different radius for each corner, given by rTL (top-left), rTR (top-right)
+// rBR (bottom-right), rBL (bottom-left). See ClipRoundedRect() for more
+// details. This method is demonstrated in the ClipText() example.
+func (f *Fpdf) ClipRoundedRectExt(x, y, w, h, rTL, rTR, rBR, rBL float64, outline bool) {
+	f.clipNest++
+	f.roundedRectPath(x, y, w, h, rTL, rTR, rBR, rBL)
+	f.outf(" W %s", strIf(outline, "S", "n"))
+}
+
+// add a rectangle path with rounded corners.
+// routine shared by RoundedRect() and ClipRoundedRect(), which add the
+// drawing operation
+func (f *Fpdf) roundedRectPath(x, y, w, h, rTL, rTR, rBR, rBL float64) {
+	k := f.k
+	hp := f.h
+	myArc := (4.0 / 3.0) * (math.Sqrt2 - 1.0)
+	f.outf("q %.5f %.5f m", (x+rTL)*k, (hp-y)*k)
+	xc := x + w - rTR
+	yc := y + rTR
+	f.outf("%.5f %.5f l", xc*k, (hp-y)*k)
+	if rTR != 0 {
+		f.clipArc(xc+rTR*myArc, yc-rTR, xc+rTR, yc-rTR*myArc, xc+rTR, yc)
+	}
+	xc = x + w - rBR
+	yc = y + h - rBR
+	f.outf("%.5f %.5f l", (x+w)*k, (hp-yc)*k)
+	if rBR != 0 {
+		f.clipArc(xc+rBR, yc+rBR*myArc, xc+rBR*myArc, yc+rBR, xc, yc+rBR)
+	}
+	xc = x + rBL
+	yc = y + h - rBL
+	f.outf("%.5f %.5f l", xc*k, (hp-(y+h))*k)
+	if rBL != 0 {
+		f.clipArc(xc-rBL*myArc, yc+rBL, xc-rBL, yc+rBL*myArc, xc-rBL, yc)
+	}
+	xc = x + rTL
+	yc = y + rTL
+	f.outf("%.5f %.5f l", x*k, (hp-yc)*k)
+	if rTL != 0 {
+		f.clipArc(xc-rTL, yc-rTL*myArc, xc-rTL*myArc, yc-rTL, xc, yc-rTL)
+	}
+}
+
+// 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) {
+	f.addFont(fontFamilyEscape(familyStr), styleStr, fileStr, false)
+}
+
+// AddUTF8Font imports a TrueType font with utf-8 symbols 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) AddUTF8Font(familyStr, styleStr, fileStr string) {
+	f.addFont(fontFamilyEscape(familyStr), styleStr, fileStr, true)
+}
+
+func (f *Fpdf) addFont(familyStr, styleStr, fileStr string, isUTF8 bool) {
+	if fileStr == "" {
+		if isUTF8 {
+			fileStr = strings.Replace(familyStr, " ", "", -1) + strings.ToLower(styleStr) + ".ttf"
+		} else {
+			fileStr = strings.Replace(familyStr, " ", "", -1) + strings.ToLower(styleStr) + ".json"
+		}
+	}
+	if isUTF8 {
+		fontKey := getFontKey(familyStr, styleStr)
+		_, ok := f.fonts[fontKey]
+		if ok {
+			return
+		}
+		var ttfStat os.FileInfo
+		var err error
+		fileStr = path.Join(f.fontpath, fileStr)
+		ttfStat, err = os.Stat(fileStr)
+		if err != nil {
+			f.SetError(err)
+			return
+		}
+		originalSize := ttfStat.Size()
+		Type := "UTF8"
+		var utf8Bytes []byte
+		utf8Bytes, err = ioutil.ReadFile(fileStr)
+		if err != nil {
+			f.SetError(err)
+			return
+		}
+		reader := fileReader{readerPosition: 0, array: utf8Bytes}
+		utf8File := newUTF8Font(&reader)
+		err = utf8File.parseFile()
+		if err != nil {
+			f.SetError(err)
+			return
+		}
+
+		desc := FontDescType{
+			Ascent:       int(utf8File.Ascent),
+			Descent:      int(utf8File.Descent),
+			CapHeight:    utf8File.CapHeight,
+			Flags:        utf8File.Flags,
+			FontBBox:     utf8File.Bbox,
+			ItalicAngle:  utf8File.ItalicAngle,
+			StemV:        utf8File.StemV,
+			MissingWidth: round(utf8File.DefaultWidth),
+		}
+
+		var sbarr map[int]int
+		if f.aliasNbPagesStr == "" {
+			sbarr = makeSubsetRange(57)
+		} else {
+			sbarr = makeSubsetRange(32)
+		}
+		def := fontDefType{
+			Tp:        Type,
+			Name:      fontKey,
+			Desc:      desc,
+			Up:        int(round(utf8File.UnderlinePosition)),
+			Ut:        round(utf8File.UnderlineThickness),
+			Cw:        utf8File.CharWidths,
+			usedRunes: sbarr,
+			File:      fileStr,
+			utf8File:  utf8File,
+		}
+		def.i, _ = generateFontID(def)
+		f.fonts[fontKey] = def
+		f.fontFiles[fontKey] = fontFileType{
+			length1:  originalSize,
+			fontType: "UTF8",
+		}
+		f.fontFiles[fileStr] = fontFileType{
+			fontType: "UTF8",
+		}
+	} else {
+		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)
+	}
+}
+
+func makeSubsetRange(end int) map[int]int {
+	answer := make(map[int]int)
+	for i := 0; i < end; i++ {
+		answer[i] = 0
+	}
+	return answer
+}
+
+// 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, styleStr string, jsonFileBytes, zFileBytes []byte) {
+	f.addFontFromBytes(fontFamilyEscape(familyStr), styleStr, jsonFileBytes, zFileBytes, nil)
+}
+
+// AddUTF8FontFromBytes  imports a TrueType font with utf-8 symbols 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) AddUTF8FontFromBytes(familyStr, styleStr string, utf8Bytes []byte) {
+	f.addFontFromBytes(fontFamilyEscape(familyStr), styleStr, nil, nil, utf8Bytes)
+}
+
+func (f *Fpdf) addFontFromBytes(familyStr, styleStr string, jsonFileBytes, zFileBytes, utf8Bytes []byte) {
+	if f.err != nil {
+		return
+	}
+
+	// load font key
+	var ok bool
+	fontkey := getFontKey(familyStr, styleStr)
+	_, ok = f.fonts[fontkey]
+
+	if ok {
+		return
+	}
+
+	if utf8Bytes != nil {
+
+		// if styleStr == "IB" {
+		// 	styleStr = "BI"
+		// }
+
+		Type := "UTF8"
+		reader := fileReader{readerPosition: 0, array: utf8Bytes}
+
+		utf8File := newUTF8Font(&reader)
+
+		err := utf8File.parseFile()
+		if err != nil {
+			fmt.Printf("get metrics Error: %e\n", err)
+			return
+		}
+		desc := FontDescType{
+			Ascent:       int(utf8File.Ascent),
+			Descent:      int(utf8File.Descent),
+			CapHeight:    utf8File.CapHeight,
+			Flags:        utf8File.Flags,
+			FontBBox:     utf8File.Bbox,
+			ItalicAngle:  utf8File.ItalicAngle,
+			StemV:        utf8File.StemV,
+			MissingWidth: round(utf8File.DefaultWidth),
+		}
+
+		var sbarr map[int]int
+		if f.aliasNbPagesStr == "" {
+			sbarr = makeSubsetRange(57)
+		} else {
+			sbarr = makeSubsetRange(32)
+		}
+		def := fontDefType{
+			Tp:        Type,
+			Name:      fontkey,
+			Desc:      desc,
+			Up:        int(round(utf8File.UnderlinePosition)),
+			Ut:        round(utf8File.UnderlineThickness),
+			Cw:        utf8File.CharWidths,
+			utf8File:  utf8File,
+			usedRunes: sbarr,
+		}
+		def.i, _ = generateFontID(def)
+		f.fonts[fontkey] = def
+	} else {
+		// load font definitions
+		var info fontDefType
+		err := json.Unmarshal(jsonFileBytes, &info)
+
+		if err != nil {
+			f.err = err
+		}
+
+		if f.err != nil {
+			return
+		}
+
+		if info.i, err = generateFontID(info); err != nil {
+			f.err = err
+			return
+		}
+
+		// search existing encodings
+		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)
+	familyStr = fontFamilyEscape(familyStr)
+	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
+	}
+	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(fontFamilyEscape(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), "S" (strike-out)
+// 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")
+	familyStr = fontFamilyEscape(familyStr)
+	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)
+	}
+	f.strikeout = strings.Contains(styleStr, "S")
+	if f.strikeout {
+		styleStr = strings.Replace(styleStr, "S", "", -1)
+	}
+	if styleStr == "IB" {
+		styleStr = "BI"
+	}
+	if size == 0.0 {
+		size = f.fontSizePt
+	}
+
+	// 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.currentFont.Tp == "UTF8" {
+		f.isCurrentUTF8 = true
+	} else {
+		f.isCurrentUTF8 = false
+	}
+	if f.page > 0 {
+		f.outf("BT /F%s %.2f Tf ET", f.currentFont.i, f.fontSizePt)
+	}
+	return
+}
+
+// SetFontStyle sets the style of the current font. See also SetFont()
+func (f *Fpdf) SetFontStyle(styleStr string) {
+	f.SetFont(f.fontFamily, styleStr, f.fontSizePt)
+}
+
+// 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) {
+	f.fontSizePt = size
+	f.fontSize = size / f.k
+	if f.page > 0 {
+		f.outf("BT /F%s %.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) {
+	f.fontSizePt = size * f.k
+	f.fontSize = size
+	if f.page > 0 {
+		f.outf("BT /F%s %.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}
+}
+
+// newLink adds 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
+	}
+	if f.isCurrentUTF8 {
+		txtStr = utf8toutf16(txtStr)
+	}
+	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) {
+	var txt2 string
+	if f.isCurrentUTF8 {
+		if f.isRTL {
+			txtStr = reverseText(txtStr)
+			x -= f.GetStringWidth(txtStr)
+		}
+		txt2 = f.escape(utf8toutf16(txtStr, false))
+		for _, uni := range []rune(txtStr) {
+			f.currentFont.usedRunes[int(uni)] = int(uni)
+		}
+	} else {
+		txt2 = f.escape(txtStr)
+	}
+	s := sprintf("BT %.2f %.2f Td (%s) Tj ET", x*f.k, (f.h-y)*f.k, txt2)
+	if f.underline && txtStr != "" {
+		s += " " + f.dounderline(x, y, txtStr)
+	}
+	if f.strikeout && txtStr != "" {
+		s += " " + f.dostrikeout(x, y, txtStr)
+	}
+	if f.colorFlag {
+		s = sprintf("q %s %s Q", f.color.text.str, s)
+	}
+	f.out(s)
+}
+
+// SetWordSpacing sets spacing between words of following text. See the
+// WriteAligned() example for a demonstration of its use.
+func (f *Fpdf) SetWordSpacing(space float64) {
+	f.out(sprintf("%.5f Tw", space*f.k))
+}
+
+// SetTextRenderingMode sets the rendering mode of following text.
+// The mode can be as follows:
+// 0: Fill text
+// 1: Stroke text
+// 2: Fill, then stroke text
+// 3: Neither fill nor stroke text (invisible)
+// 4: Fill text and add to path for clipping
+// 5: Stroke text and add to path for clipping
+// 6: Fills then stroke text and add to path for clipping
+// 7: Add text to path for clipping
+// This method is demonstrated in the SetTextRenderingMode example.
+func (f *Fpdf) SetTextRenderingMode(mode int) {
+	if mode >= 0 && mode <= 7 {
+		f.out(sprintf("%d Tr", mode))
+	}
+}
+
+// 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.
+//
+// An error will be returned if a call to SetFont() has not already taken
+// place before this method is called.
+//
+// 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, 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
+	}
+
+	if f.currentFont.Name == "" {
+		f.err = fmt.Errorf("font has not been set; unable to render text")
+		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
+		switch {
+		case strings.Contains(alignStr, "R"):
+			dx = w - f.cMargin - f.GetStringWidth(txtStr)
+		case strings.Contains(alignStr, "C"):
+			dx = (w - f.GetStringWidth(txtStr)) / 2
+		default:
+			dx = f.cMargin
+		}
+
+		// Vertical alignment
+		switch {
+		case strings.Contains(alignStr, "T"):
+			dy = (f.fontSize - h) / 2.0
+		case strings.Contains(alignStr, "B"):
+			dy = (h - f.fontSize) / 2.0
+		case strings.Contains(alignStr, "A"):
+			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
+		default:
+			dy = 0
+		}
+		if f.colorFlag {
+			s.printf("q %s ", f.color.text.str)
+		}
+		//If multibyte, Tw has no effect - do word spacing using an adjustment before each space
+		if (f.ws != 0 || alignStr == "J") && f.isCurrentUTF8 { // && f.ws != 0
+			if f.isRTL {
+				txtStr = reverseText(txtStr)
+			}
+			wmax := int(math.Ceil((w - 2*f.cMargin) * 1000 / f.fontSize))
+			for _, uni := range []rune(txtStr) {
+				f.currentFont.usedRunes[int(uni)] = int(uni)
+			}
+			space := f.escape(utf8toutf16(" ", false))
+			strSize := f.GetStringSymbolWidth(txtStr)
+			s.printf("BT 0 Tw %.2f %.2f Td [", (f.x+dx)*k, (f.h-(f.y+.5*h+.3*f.fontSize))*k)
+			t := strings.Split(txtStr, " ")
+			shift := float64((wmax - strSize)) / float64(len(t)-1)
+			numt := len(t)
+			for i := 0; i < numt; i++ {
+				tx := t[i]
+				tx = "(" + f.escape(utf8toutf16(tx, false)) + ")"
+				s.printf("%s ", tx)
+				if (i + 1) < numt {
+					s.printf("%.3f(%s) ", -shift, space)
+				}
+			}
+			s.printf("] TJ ET")
+		} else {
+			var txt2 string
+			if f.isCurrentUTF8 {
+				if f.isRTL {
+					txtStr = reverseText(txtStr)
+				}
+				txt2 = f.escape(utf8toutf16(txtStr, false))
+				for _, uni := range []rune(txtStr) {
+					f.currentFont.usedRunes[int(uni)] = int(uni)
+				}
+			} else {
+
+				txt2 = strings.Replace(txtStr, "\\", "\\\\", -1)
+				txt2 = strings.Replace(txt2, "(", "\\(", -1)
+				txt2 = strings.Replace(txt2, ")", "\\)", -1)
+			}
+			bt := (f.x + dx) * k
+			td := (f.h - (f.y + dy + .5*h + .3*f.fontSize)) * k
+			s.printf("BT %.2f %.2f Td (%s)Tj ET", bt, td, txt2)
+			//BT %.2F %.2F Td (%s) Tj ET',(f.x+dx)*k,(f.h-(f.y+.5*h+.3*f.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.strikeout {
+			s.printf(" %s", f.dostrikeout(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
+}
+
+// Revert string to use in RTL languages
+func reverseText(text string) string {
+	oldText := []rune(text)
+	newText := make([]rune, len(oldText))
+	length := len(oldText) - 1
+	for i, r := range oldText {
+		newText[length-i] = r
+	}
+	return string(newText)
+}
+
+// Cell is a simpler version of CellFormat with no fill, border, links or
+// special alignment. The Cell_strikeout() example demonstrates this method.
+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.
+//
+// This method is useful for codepage-based fonts only. For UTF-8 encoded text,
+// use SplitText().
+//
+// 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.
+//
+// The current position after calling MultiCell() is the beginning of the next
+// line, equivalent to calling CellFormat with ln equal to 1.
+//
+// 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().
+//
+// Note: this method has a known bug that treats UTF-8 fonts differently than
+// non-UTF-8 fonts. With UTF-8 fonts, all trailing newlines in txtStr are
+// removed. With a non-UTF-8 font, if txtStr has one or more trailing newlines,
+// only the last is removed. In the next major module version, the UTF-8 logic
+// will be changed to match the non-UTF-8 logic. To prepare for that change,
+// applications that use UTF-8 fonts and depend on having all trailing newlines
+// removed should call strings.TrimRight(txtStr, "\r\n") before calling this
+// method.
+func (f *Fpdf) MultiCell(w, h float64, txtStr, borderStr, alignStr string, fill bool) {
+	if f.err != nil {
+		return
+	}
+	// dbg("MultiCell")
+	if alignStr == "" {
+		alignStr = "J"
+	}
+	cw := f.currentFont.Cw
+	if w == 0 {
+		w = f.w - f.rMargin - f.x
+	}
+	wmax := int(math.Ceil((w - 2*f.cMargin) * 1000 / f.fontSize))
+	s := strings.Replace(txtStr, "\r", "", -1)
+	srune := []rune(s)
+
+	// remove extra line breaks
+	var nb int
+	if f.isCurrentUTF8 {
+		nb = len(srune)
+		for nb > 0 && srune[nb-1] == '\n' {
+			nb--
+		}
+		srune = srune[0:nb]
+	} else {
+		nb = len(s)
+		bytes2 := []byte(s)
+
+		// for nb > 0 && bytes2[nb-1] == '\n' {
+
+		// Prior to August 2019, if s ended with a newline, this code stripped it.
+		// After that date, to be compatible with the UTF-8 code above, *all*
+		// trailing newlines were removed. Because this regression caused at least
+		// one application to break (see issue #333), the original behavior has been
+		// reinstated with a caveat included in the documentation.
+		if nb > 0 && bytes2[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
+	ls := 0
+	ns := 0
+	nl := 1
+	for i < nb {
+		// Get next character
+		var c rune
+		if f.isCurrentUTF8 {
+			c = srune[i]
+		} else {
+			c = rune(s[i])
+		}
+		if c == '\n' {
+			// Explicit line break
+			if f.ws > 0 {
+				f.ws = 0
+				f.out("0 Tw")
+			}
+
+			if f.isCurrentUTF8 {
+				newAlignStr := alignStr
+				if newAlignStr == "J" {
+					if f.isRTL {
+						newAlignStr = "R"
+					} else {
+						newAlignStr = "L"
+					}
+				}
+				f.CellFormat(w, h, string(srune[j:i]), b, 2, newAlignStr, fill, 0, "")
+			} else {
+				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 == ' ' || isChinese(c) {
+			sep = i
+			ls = l
+			ns++
+		}
+		if int(c) >= len(cw) {
+			f.err = fmt.Errorf("character outside the supported range: %s", string(c))
+			return
+		}
+		if cw[int(c)] == 0 { //Marker width 0 used for missing symbols
+			l += f.currentFont.Desc.MissingWidth
+		} else if cw[int(c)] != 65535 { //Marker width 65535 used for zero width symbols
+			l += cw[int(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")
+				}
+				if f.isCurrentUTF8 {
+					f.CellFormat(w, h, string(srune[j:i]), b, 2, alignStr, fill, 0, "")
+				} else {
+					f.CellFormat(w, h, s[j:i], b, 2, alignStr, fill, 0, "")
+				}
+			} else {
+				///////////////
+				// 如果第一个字就超宽了,别循环了,会死循环
+				if i==0{
+					break
+				}
+
+				if alignStr == "J" {
+					if ns > 1 {
+						f.ws = float64((wmax-ls)/1000) * f.fontSize / float64(ns-1)
+					} else {
+						f.ws = 0
+					}
+					f.outf("%.3f Tw", f.ws*f.k)
+				}
+				if f.isCurrentUTF8 {
+					f.CellFormat(w, h, string(srune[j:sep]), b, 2, alignStr, fill, 0, "")
+				} else {
+					f.CellFormat(w, h, s[j:sep], b, 2, alignStr, fill, 0, "")
+				}
+				//////////
+				// i = sep + 1
+				/////////
+				i=sep
+			}
+			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"
+	}
+	if f.isCurrentUTF8 {
+		if alignStr == "J" {
+			if f.isRTL {
+				alignStr = "R"
+			} else {
+				alignStr = ""
+			}
+		}
+		f.CellFormat(w, h, string(srune[j:i]), b, 2, alignStr, fill, 0, "")
+	} else {
+		f.CellFormat(w, h, s[j:i], b, 2, alignStr, fill, 0, "")
+	}
+	f.x = f.lMargin
+}
+
+// write outputs 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)
+	var nb int
+	if f.isCurrentUTF8 {
+		nb = len([]rune(s))
+		if nb == 1 && s == " " {
+			f.x += f.GetStringWidth(s)
+			return
+		}
+	} else {
+		nb = len(s)
+	}
+	sep := -1
+	i := 0
+	j := 0
+	l := 0.0
+	nl := 1
+	for i < nb {
+		// Get next character
+		var c rune
+		if f.isCurrentUTF8 {
+			c = []rune(s)[i]
+		} else {
+			c = rune(byte(s[i]))
+		}
+		if c == '\n' {
+			// Explicit line break
+			if f.isCurrentUTF8 {
+				f.CellFormat(w, h, string([]rune(s)[j:i]), "", 2, "", false, link, linkStr)
+			} else {
+				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[int(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++
+				}
+				if f.isCurrentUTF8 {
+					f.CellFormat(w, h, string([]rune(s)[j:i]), "", 2, "", false, link, linkStr)
+				} else {
+					f.CellFormat(w, h, s[j:i], "", 2, "", false, link, linkStr)
+				}
+			} else {
+				if f.isCurrentUTF8 {
+					f.CellFormat(w, h, string([]rune(s)[j:sep]), "", 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 {
+		if f.isCurrentUTF8 {
+			f.CellFormat(l/1000*f.fontSize, h, string([]rune(s)[j:]), "", 0, "", false, link, linkStr)
+		} else {
+			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()
+
+	pageWidth, _ := f.GetPageSize()
+	if width == 0 {
+		width = pageWidth - (lMargin + rMargin)
+	}
+
+	var lines []string
+
+	if f.isCurrentUTF8 {
+		lines = f.SplitText(textStr, width)
+	} else {
+		for _, line := range f.SplitLines([]byte(textStr), width) {
+			lines = append(lines, string(line))
+		}
+	}
+
+	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) - 2.01*f.cMargin)
+			f.Write(lineHeight, lineStr)
+			f.SetLeftMargin(lMargin)
+		default:
+			f.SetRightMargin(pageWidth - lMargin - width)
+			f.Write(lineHeight, lineStr)
+			f.SetRightMargin(rMargin)
+		}
+	}
+}
+
+// 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, allowNegativeX, 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 !allowNegativeX {
+		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%s 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, options.AllowNegativePosition, 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.
+//
+// AllowNegativePosition can be set to true in order to prevent the default
+// coercion of negative x values to the current x position.
+type ImageOptions struct {
+	ImageType             string
+	ReadDpi               bool
+	AllowNegativePosition 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
+	}
+
+	if info.i, f.err = generateImageID(info); f.err != nil {
+		return
+	}
+	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]
+}
+
+// ImportObjects imports objects from gofpdi into current document
+func (f *Fpdf) ImportObjects(objs map[string][]byte) {
+	for k, v := range objs {
+		f.importedObjs[k] = v
+	}
+}
+
+// ImportObjPos imports object hash positions from gofpdi
+func (f *Fpdf) ImportObjPos(objPos map[string]map[int]string) {
+	for k, v := range objPos {
+		f.importedObjPos[k] = v
+	}
+}
+
+// putImportedTemplates writes the imported template objects to the PDF
+func (f *Fpdf) putImportedTemplates() {
+	nOffset := f.n + 1
+
+	// keep track of list of sha1 hashes (to be replaced with integers)
+	objsIDHash := make([]string, len(f.importedObjs))
+
+	// actual object data with new id
+	objsIDData := make([][]byte, len(f.importedObjs))
+
+	// Populate hash slice and data slice
+	i := 0
+	for k, v := range f.importedObjs {
+		objsIDHash[i] = k
+		objsIDData[i] = v
+
+		i++
+	}
+
+	// Populate a lookup table to get an object id from a hash
+	hashToObjID := make(map[string]int, len(f.importedObjs))
+	for i = 0; i < len(objsIDHash); i++ {
+		hashToObjID[objsIDHash[i]] = i + nOffset
+	}
+
+	// Now, replace hashes inside data with %040d object id
+	for i = 0; i < len(objsIDData); i++ {
+		// get hash
+		hash := objsIDHash[i]
+
+		for pos, h := range f.importedObjPos[hash] {
+			// Convert object id into a 40 character string padded with spaces
+			objIDPadded := fmt.Sprintf("%40s", fmt.Sprintf("%d", hashToObjID[h]))
+
+			// Convert objIDPadded into []byte
+			objIDBytes := []byte(objIDPadded)
+
+			// Replace sha1 hash with object id padded
+			for j := pos; j < pos+40; j++ {
+				objsIDData[i][j] = objIDBytes[j-pos]
+			}
+		}
+
+		// Save objsIDHash so that procset dictionary has the correct object ids
+		f.importedTplIDs[hash] = i + nOffset
+	}
+
+	// Now, put objects
+	for i = 0; i < len(objsIDData); i++ {
+		f.newobj()
+		f.out(string(objsIDData[i]))
+	}
+}
+
+// UseImportedTemplate uses imported template from gofpdi. It draws imported
+// PDF page onto page.
+func (f *Fpdf) UseImportedTemplate(tplName string, scaleX float64, scaleY float64, tX float64, tY float64) {
+	f.outf("q 0 J 1 w 0 j 0 G 0 g q %.4F 0 0 %.4F %.4F %.4F cm %s Do Q Q\n", scaleX*f.k, scaleY*f.k, tX*f.k, (tY+f.h)*f.k, tplName)
+}
+
+// ImportTemplates imports gofpdi template names into importedTplObjs for
+// inclusion in the procset dictionary
+func (f *Fpdf) ImportTemplates(tpls map[string]string) {
+	for tplName, tplID := range tpls {
+		f.importedTplObjs[tplName] = tplID
+	}
+}
+
+// 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
+	}
+}
+
+// SetHomeXY is a convenience method that sets the current position to the left
+// and top margins.
+func (f *Fpdf) SetHomeXY() {
+	f.SetY(f.tMargin)
+	f.SetX(f.lMargin)
+}
+
+// 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
+}
+
+// GetPageSizeStr returns the SizeType for the given sizeStr (that is A4, A3, etc..)
+func (f *Fpdf) GetPageSizeStr(sizeStr string) (size SizeType) {
+	return f.getpagesizestr(sizeStr)
+}
+
+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++
+	// add the default page boxes, if any exist, to the page
+	f.pageBoxes[f.page] = make(map[string]PageBox)
+	for box, pb := range f.defPageBoxes {
+		f.pageBoxes[f.page][box] = pb
+	}
+	f.pages = append(f.pages, bytes.NewBufferString(""))
+	f.pageLinks = append(f.pageLinks, make([]linkType, 0, 0))
+	f.pageAttachments = append(f.pageAttachments, []annotationAttach{})
+	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
+		return
+	}
+
+	if def.i, err = generateFontID(def); 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
+}
+
+// textstring formats 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
+}
+
+// SetUnderlineThickness accepts a multiplier for adjusting the text underline
+// thickness, defaulting to 1. See SetUnderlineThickness example.
+func (f *Fpdf) SetUnderlineThickness(thickness float64) {
+	f.userUnderlineThickness = thickness
+}
+
+// Underline text
+func (f *Fpdf) dounderline(x, y float64, txt string) string {
+	up := float64(f.currentFont.Up)
+	ut := float64(f.currentFont.Ut) * f.userUnderlineThickness
+	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 (f *Fpdf) dostrikeout(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+4*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}
+}
+
+// parsejpg extracts 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
+}
+
+// parsepng extracts 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(r io.Reader) (val int32) {
+	err := binary.Read(r, binary.BigEndian, &val)
+	if err != nil && err != io.EOF {
+		f.err = err
+	}
+	return
+}
+
+func (f *Fpdf) readByte(r io.Reader) (val byte) {
+	err := binary.Read(r, binary.BigEndian, &val)
+	if err != nil {
+		f.err = err
+	}
+	return
+}
+
+// parsegif extracts 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)
+}
+
+// newobj begins 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")
+}
+
+// out; 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")
+	}
+}
+
+// outbuf adds a buffered line to the document
+func (f *Fpdf) outbuf(r io.Reader) {
+	if f.state == 2 {
+		f.pages[f.page].ReadFrom(r)
+		f.pages[f.page].WriteString("\n")
+	} else {
+		f.buffer.ReadFrom(r)
+		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(r io.Reader) {
+	f.outbuf(r)
+}
+
+// outf adds 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
+}
+
+// SetDefaultModificationDate sets the default value of the document modification date
+// that will be used when initializing a new Fpdf instance. See
+// SetCreationDate() for more details.
+func SetDefaultModificationDate(tm time.Time) {
+	gl.modDate = 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
+// comparison. Specify a zero-value time to revert to the default behavior.
+func (f *Fpdf) SetCreationDate(tm time.Time) {
+	f.creationDate = tm
+}
+
+// SetModificationDate fixes the document's internal ModDate value.
+// See `SetCreationDate` for more details.
+func (f *Fpdf) SetModificationDate(tm time.Time) {
+	f.modDate = tm
+}
+
+// SetJavascript adds Adobe JavaScript to the document.
+func (f *Fpdf) SetJavascript(script string) {
+	f.javascript = &script
+}
+
+// RegisterAlias adds an (alias, replacement) pair to the document so we can
+// replace all occurrences of that alias after writing but before the document
+// is closed. Functions ExampleFpdf_RegisterAlias() and
+// ExampleFpdf_RegisterAlias_utf8() in fpdf_test.go demonstrate this method.
+func (f *Fpdf) RegisterAlias(alias, replacement string) {
+	// Note: map[string]string assignments embed literal escape ("\00") sequences
+	// into utf16 key and value strings. Consequently, subsequent search/replace
+	// operations will fail unexpectedly if utf8toutf16() conversions take place
+	// here. Instead, conversions are deferred until the actual search/replace
+	// operation takes place when the PDF output is generated.
+	f.aliasMap[alias] = replacement
+}
+
+func (f *Fpdf) replaceAliases() {
+	for mode := 0; mode < 2; mode++ {
+		for alias, replacement := range f.aliasMap {
+			if mode == 1 {
+				alias = utf8toutf16(alias, false)
+				replacement = utf8toutf16(replacement, false)
+			}
+			for n := 1; n <= f.page; n++ {
+				s := f.pages[n].String()
+				if strings.Contains(s, alias) {
+					s = strings.Replace(s, alias, replacement, -1)
+					f.pages[n].Truncate(0)
+					f.pages[n].WriteString(s)
+				}
+			}
+		}
+	}
+}
+
+func (f *Fpdf) putpages() {
+	var wPt, hPt float64
+	var pageSize SizeType
+	var ok bool
+	nb := f.page
+	if len(f.aliasNbPagesStr) > 0 {
+		// Replace number of pages
+		f.RegisterAlias(f.aliasNbPagesStr, sprintf("%d", nb))
+	}
+	f.replaceAliases()
+	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
+	}
+	pagesObjectNumbers := make([]int, nb+1) // 1-based
+	for n := 1; n <= nb; n++ {
+		// Page
+		f.newobj()
+		pagesObjectNumbers[n] = f.n // save for /Kids
+		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)
+		}
+		for t, pb := range f.pageBoxes[n] {
+			f.outf("/%s [%.2f %.2f %.2f %.2f]", t, pb.X, pb.Y, pb.Wd, pb.Ht)
+		}
+		f.out("/Resources 2 0 R")
+		// Links
+		if len(f.pageLinks[n])+len(f.pageAttachments[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)
+				}
+			}
+			f.putAttachmentAnnotationLinks(&annots, n)
+			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 := 1; i <= nb; i++ {
+		kids.printf("%d 0 R ", pagesObjectNumbers[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.SliceStable(fileList, func(i, j int) bool { return fileList[i] < fileList[j] })
+		}
+		for _, file = range fileList {
+			info = f.fontFiles[file]
+			if info.fontType != "UTF8" {
+				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
+					}
+				}
+				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.SliceStable(keyList, func(i, j int) bool { return keyList[i] < keyList[j] })
+		}
+		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
+			switch tp {
+			case "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")
+			case "Type1":
+				fallthrough
+			case "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")
+			case "UTF8":
+				fontName := "utf8" + font.Name
+				usedRunes := font.usedRunes
+				delete(usedRunes, 0)
+				utf8FontStream := font.utf8File.GenerateCutFont(usedRunes)
+				utf8FontSize := len(utf8FontStream)
+				compressedFontStream := sliceCompress(utf8FontStream)
+				CodeSignDictionary := font.utf8File.CodeSymbolDictionary
+				delete(CodeSignDictionary, 0)
+
+				f.newobj()
+				f.out(fmt.Sprintf("<</Type /Font\n/Subtype /Type0\n/BaseFont /%s\n/Encoding /Identity-H\n/DescendantFonts [%d 0 R]\n/ToUnicode %d 0 R>>\n"+"endobj", fontName, f.n+1, f.n+2))
+
+				f.newobj()
+				f.out("<</Type /Font\n/Subtype /CIDFontType2\n/BaseFont /" + fontName + "\n" +
+					"/CIDSystemInfo " + strconv.Itoa(f.n+2) + " 0 R\n/FontDescriptor " + strconv.Itoa(f.n+3) + " 0 R")
+				if font.Desc.MissingWidth != 0 {
+					f.out("/DW " + strconv.Itoa(font.Desc.MissingWidth) + "")
+				}
+				f.generateCIDFontMap(&font, font.utf8File.LastRune)
+				f.out("/CIDToGIDMap " + strconv.Itoa(f.n+4) + " 0 R>>")
+				f.out("endobj")
+
+				f.newobj()
+				f.out("<</Length " + strconv.Itoa(len(toUnicode)) + ">>")
+				f.putstream([]byte(toUnicode))
+				f.out("endobj")
+
+				// CIDInfo
+				f.newobj()
+				f.out("<</Registry (Adobe)\n/Ordering (UCS)\n/Supplement 0>>")
+				f.out("endobj")
+
+				// Font descriptor
+				f.newobj()
+				var s fmtBuffer
+				s.printf("<</Type /FontDescriptor /FontName /%s\n /Ascent %d", fontName, font.Desc.Ascent)
+				s.printf(" /Descent %d", font.Desc.Descent)
+				s.printf(" /CapHeight %d", font.Desc.CapHeight)
+				v := font.Desc.Flags
+				v = v | 4
+				v = v &^ 32
+				s.printf(" /Flags %d", v)
+				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)
+				s.printf("/FontFile2 %d 0 R", f.n+2)
+				s.printf(">>")
+				f.out(s.String())
+				f.out("endobj")
+
+				// Embed CIDToGIDMap
+				cidToGidMap := make([]byte, 256*256*2)
+
+				for cc, glyph := range CodeSignDictionary {
+					cidToGidMap[cc*2] = byte(glyph >> 8)
+					cidToGidMap[cc*2+1] = byte(glyph & 0xFF)
+				}
+
+				cidToGidMap = sliceCompress(cidToGidMap)
+				f.newobj()
+				f.out("<</Length " + strconv.Itoa(len(cidToGidMap)) + "/Filter /FlateDecode>>")
+				f.putstream(cidToGidMap)
+				f.out("endobj")
+
+				//Font file
+				f.newobj()
+				f.out("<</Length " + strconv.Itoa(len(compressedFontStream)))
+				f.out("/Filter /FlateDecode")
+				f.out("/Length1 " + strconv.Itoa(utf8FontSize))
+				f.out(">>")
+				f.putstream(compressedFontStream)
+				f.out("endobj")
+			default:
+				f.err = fmt.Errorf("unsupported font type: %s", tp)
+				return
+			}
+		}
+	}
+	return
+}
+
+func (f *Fpdf) generateCIDFontMap(font *fontDefType, LastRune int) {
+	rangeID := 0
+	cidArray := make(map[int]*untypedKeyMap)
+	cidArrayKeys := make([]int, 0)
+	prevCid := -2
+	prevWidth := -1
+	interval := false
+	startCid := 1
+	cwLen := LastRune + 1
+
+	// for each character
+	for cid := startCid; cid < cwLen; cid++ {
+		if font.Cw[cid] == 0x00 {
+			continue
+		}
+		width := font.Cw[cid]
+		if width == 65535 {
+			width = 0
+		}
+		if numb, OK := font.usedRunes[cid]; cid > 255 && (!OK || numb == 0) {
+			continue
+		}
+
+		if cid == prevCid+1 {
+			if width == prevWidth {
+
+				if width == cidArray[rangeID].get(0) {
+					cidArray[rangeID].put(nil, width)
+				} else {
+					cidArray[rangeID].pop()
+					rangeID = prevCid
+					r := untypedKeyMap{
+						valueSet: make([]int, 0),
+						keySet:   make([]interface{}, 0),
+					}
+					cidArray[rangeID] = &r
+					cidArrayKeys = append(cidArrayKeys, rangeID)
+					cidArray[rangeID].put(nil, prevWidth)
+					cidArray[rangeID].put(nil, width)
+				}
+				interval = true
+				cidArray[rangeID].put("interval", 1)
+			} else {
+				if interval {
+					// new range
+					rangeID = cid
+					r := untypedKeyMap{
+						valueSet: make([]int, 0),
+						keySet:   make([]interface{}, 0),
+					}
+					cidArray[rangeID] = &r
+					cidArrayKeys = append(cidArrayKeys, rangeID)
+					cidArray[rangeID].put(nil, width)
+				} else {
+					cidArray[rangeID].put(nil, width)
+				}
+				interval = false
+			}
+		} else {
+			rangeID = cid
+			r := untypedKeyMap{
+				valueSet: make([]int, 0),
+				keySet:   make([]interface{}, 0),
+			}
+			cidArray[rangeID] = &r
+			cidArrayKeys = append(cidArrayKeys, rangeID)
+			cidArray[rangeID].put(nil, width)
+			interval = false
+		}
+		prevCid = cid
+		prevWidth = width
+
+	}
+	previousKey := -1
+	nextKey := -1
+	isInterval := false
+	for g := 0; g < len(cidArrayKeys); {
+		key := cidArrayKeys[g]
+		ws := *cidArray[key]
+		cws := len(ws.keySet)
+		if (key == nextKey) && (!isInterval) && (ws.getIndex("interval") < 0 || cws < 4) {
+			if cidArray[key].getIndex("interval") >= 0 {
+				cidArray[key].delete("interval")
+			}
+			cidArray[previousKey] = arrayMerge(cidArray[previousKey], cidArray[key])
+			cidArrayKeys = remove(cidArrayKeys, key)
+		} else {
+			g++
+			previousKey = key
+		}
+		nextKey = key + cws
+		// ui := ws.getIndex("interval")
+		// ui = ui + 1
+		if ws.getIndex("interval") >= 0 {
+			if cws > 3 {
+				isInterval = true
+			} else {
+				isInterval = false
+			}
+			cidArray[key].delete("interval")
+			nextKey--
+		} else {
+			isInterval = false
+		}
+	}
+	var w fmtBuffer
+	for _, k := range cidArrayKeys {
+		ws := cidArray[k]
+		if len(arrayCountValues(ws.valueSet)) == 1 {
+			w.printf(" %d %d %d", k, k+len(ws.valueSet)-1, ws.get(0))
+		} else {
+			w.printf(" %d [ %s ]\n", k, implode(" ", ws.valueSet))
+		}
+	}
+	f.out("/W [" + w.String() + " ]")
+}
+
+func implode(sep string, arr []int) string {
+	var s fmtBuffer
+	for i := 0; i < len(arr)-1; i++ {
+		s.printf("%v", arr[i])
+		s.printf(sep)
+	}
+	if len(arr) > 0 {
+		s.printf("%v", arr[len(arr)-1])
+	}
+	return s.String()
+}
+
+// arrayCountValues counts the occurrences of each item in the $mp array.
+func arrayCountValues(mp []int) map[int]int {
+	answer := make(map[int]int)
+	for _, v := range mp {
+		answer[v] = answer[v] + 1
+	}
+	return answer
+}
+
+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)
+	}
+
+	// Sort the keyList []string by the corresponding image's width.
+	if f.catalogSort {
+		sort.SliceStable(keyList, func(i, j int) bool { return f.images[keyList[i]].w < f.images[keyList[j]].w })
+	}
+
+	// Maintain a list of inserted image SHA-1 hashes, with their
+	// corresponding object ID number.
+	insertedImages := map[string]int{}
+
+	for _, key = range keyList {
+		image := f.images[key]
+
+		// Check if this image has already been inserted using it's SHA-1 hash.
+		insertedImageObjN, isFound := insertedImages[image.i]
+
+		// If found, skip inserting the image as a new object, and
+		// use the object ID from the insertedImages map.
+		// If not, insert the image into the PDF and store the object ID.
+		if isFound {
+			image.n = insertedImageObjN
+		} else {
+			f.putimage(image)
+			insertedImages[image.i] = image.n
+		}
+	}
+}
+
+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.SliceStable(keyList, func(i, j int) bool { return f.images[keyList[i]].i < f.images[keyList[j]].i })
+		}
+		for _, key = range keyList {
+			image = f.images[key]
+			f.outf("/I%s %d 0 R", image.i, image.n)
+		}
+	}
+	{
+		var keyList []string
+		var key string
+		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%s %d 0 R", id, objID)
+			}
+		}
+	}
+	{
+		for tplName, objID := range f.importedTplObjs {
+			// here replace obj id hash with n
+			f.outf("%s %d 0 R", tplName, f.importedTplIDs[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.SliceStable(keyList, func(i, j int) bool { return f.fonts[keyList[i]].i < f.fonts[keyList[j]].i })
+		}
+		for _, key = range keyList {
+			font = f.fonts[key]
+			f.outf("/F%s %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()
+	f.spotColorPutResourceDict()
+}
+
+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) putjavascript() {
+	if f.javascript == nil {
+		return
+	}
+
+	f.newobj()
+	f.nJs = f.n
+	f.out("<<")
+	f.outf("/Names [(EmbeddedJS) %d 0 R]", f.n+1)
+	f.out(">>")
+	f.out("endobj")
+	f.newobj()
+	f.out("<<")
+	f.out("/S /JavaScript")
+	f.outf("/JS %s", f.textstring(*f.javascript))
+	f.out(">>")
+	f.out("endobj")
+}
+
+func (f *Fpdf) putresources() {
+	if f.err != nil {
+		return
+	}
+	f.layerPutLayers()
+	f.putBlendModes()
+	f.putGradients()
+	f.putSpotColors()
+	f.putfonts()
+	if f.err != nil {
+		return
+	}
+	f.putimages()
+	f.putTemplates()
+	f.putImportedTemplates() // gofpdi
+	// 	Resource dictionary
+	f.offsets[2] = f.buffer.Len()
+	f.out("2 0 obj")
+	f.out("<<")
+	f.putresourcedict()
+	f.out(">>")
+	f.out("endobj")
+	f.putjavascript()
+	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
+}
+
+// returns Now() if tm is zero
+func timeOrNow(tm time.Time) time.Time {
+	if tm.IsZero() {
+		return time.Now()
+	}
+	return tm
+}
+
+func (f *Fpdf) putinfo() {
+	if len(f.producer) > 0 {
+		f.outf("/Producer %s", f.textstring(f.producer))
+	}
+	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))
+	}
+	creation := timeOrNow(f.creationDate)
+	f.outf("/CreationDate %s", f.textstring("D:"+creation.Format("20060102150405")))
+	mod := timeOrNow(f.modDate)
+	f.outf("/ModDate %s", f.textstring("D:"+mod.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()
+	// Name dictionary :
+	//	-> Javascript
+	//	-> Embedded files
+	f.out("/Names <<")
+	// JavaScript
+	if f.javascript != nil {
+		f.outf("/JavaScript %d 0 R", f.nJs)
+	}
+	// Embedded files
+	f.outf("/EmbeddedFiles %s", f.getEmbeddedFiles())
+	f.out(">>")
+}
+
+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) putxmp() {
+	if len(f.xmp) == 0 {
+		return
+	}
+	f.newobj()
+	f.outf("<< /Type /Metadata /Subtype /XML /Length %d >>", len(f.xmp))
+	f.putstream(f.xmp)
+	f.out("endobj")
+}
+
+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()
+	// Embedded files
+	f.putAttachments()
+	f.putAnnotationsAttachments()
+	f.putpages()
+	f.putresources()
+	if f.err != nil {
+		return
+	}
+	// Bookmarks
+	f.putbookmarks()
+	// Metadata
+	f.putxmp()
+	// 	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")
+	}
+}

+ 2924 - 0
fpdf_test.go

@@ -0,0 +1,2924 @@
+/*
+ * Copyright (c) 2013-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_test
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"math"
+	"math/rand"
+	"net/http"
+	"os"
+	"path/filepath"
+	"strconv"
+	"strings"
+	"testing"
+	"time"
+
+	"github.com/jung-kurt/gofpdf"
+	"github.com/jung-kurt/gofpdf/internal/example"
+	"github.com/jung-kurt/gofpdf/internal/files"
+)
+
+func init() {
+	cleanup()
+}
+
+func cleanup() {
+	filepath.Walk(example.PdfDir(),
+		func(path string, info os.FileInfo, err error) (reterr error) {
+			if info.Mode().IsRegular() {
+				dir, _ := filepath.Split(path)
+				if "reference" != filepath.Base(dir) {
+					if len(path) > 3 {
+						if path[len(path)-4:] == ".pdf" {
+							os.Remove(path)
+						}
+					}
+				}
+			}
+			return
+		})
+}
+
+func TestFpdfImplementPdf(t *testing.T) {
+	// this will not compile if Fpdf and Tpl
+	// do not implement Pdf
+	var _ gofpdf.Pdf = (*gofpdf.Fpdf)(nil)
+	var _ gofpdf.Pdf = (*gofpdf.Tpl)(nil)
+}
+
+// TestPagedTemplate ensures new paged templates work
+func TestPagedTemplate(t *testing.T) {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	tpl := pdf.CreateTemplate(func(t *gofpdf.Tpl) {
+		// this will be the second page, as a page is already
+		// created by default
+		t.AddPage()
+		t.AddPage()
+		t.AddPage()
+	})
+
+	if tpl.NumPages() != 4 {
+		t.Fatalf("The template does not have the correct number of pages %d", tpl.NumPages())
+	}
+
+	tplPages := tpl.FromPages()
+	for x := 0; x < len(tplPages); x++ {
+		pdf.AddPage()
+		pdf.UseTemplate(tplPages[x])
+	}
+
+	// get the last template
+	tpl2, err := tpl.FromPage(tpl.NumPages())
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// the objects should be the exact same, as the
+	// template will represent the last page by default
+	// therefore no new id should be set, and the object
+	// should be the same object
+	if fmt.Sprintf("%p", tpl2) != fmt.Sprintf("%p", tpl) {
+		t.Fatal("Template no longer respecting initial template object")
+	}
+}
+
+// TestIssue0116 addresses issue 116 in which library silently fails after
+// calling CellFormat when no font has been set.
+func TestIssue0116(t *testing.T) {
+	var pdf *gofpdf.Fpdf
+
+	pdf = gofpdf.New("P", "mm", "A4", "")
+	pdf.AddPage()
+	pdf.SetFont("Arial", "B", 16)
+	pdf.Cell(40, 10, "OK")
+	if pdf.Error() != nil {
+		t.Fatalf("not expecting error when rendering text")
+	}
+
+	pdf = gofpdf.New("P", "mm", "A4", "")
+	pdf.AddPage()
+	pdf.Cell(40, 10, "Not OK") // Font not set
+	if pdf.Error() == nil {
+		t.Fatalf("expecting error when rendering text without having set font")
+	}
+}
+
+// TestIssue0193 addresses issue 193 in which the error io.EOF is incorrectly
+// assigned to the FPDF instance error.
+func TestIssue0193(t *testing.T) {
+	var png []byte
+	var pdf *gofpdf.Fpdf
+	var err error
+	var rdr *bytes.Reader
+
+	png, err = ioutil.ReadFile(example.ImageFile("sweden.png"))
+	if err == nil {
+		rdr = bytes.NewReader(png)
+		pdf = gofpdf.New("P", "mm", "A4", "")
+		pdf.AddPage()
+		_ = pdf.RegisterImageOptionsReader("sweden", gofpdf.ImageOptions{ImageType: "png", ReadDpi: true}, rdr)
+		err = pdf.Error()
+	}
+	if err != nil {
+		t.Fatalf("issue 193 error: %s", err)
+	}
+
+}
+
+// TestIssue0209SplitLinesEqualMultiCell addresses issue 209
+// make SplitLines and MultiCell split at the same place
+func TestIssue0209SplitLinesEqualMultiCell(t *testing.T) {
+	var pdf *gofpdf.Fpdf
+
+	pdf = gofpdf.New("P", "mm", "A4", "")
+	pdf.AddPage()
+	pdf.SetFont("Arial", "", 8)
+	// this sentence should not be splited
+	str := "Guochin Amandine"
+	lines := pdf.SplitLines([]byte(str), 26)
+	_, FontSize := pdf.GetFontSize()
+	y_start := pdf.GetY()
+	pdf.MultiCell(26, FontSize, str, "", "L", false)
+	y_end := pdf.GetY()
+
+	if len(lines) != 1 {
+		t.Fatalf("expect SplitLines split in one line")
+	}
+	if int(y_end-y_start) != int(FontSize) {
+		t.Fatalf("expect MultiCell split in one line %.2f != %.2f", y_end-y_start, FontSize)
+	}
+
+	// this sentence should be splited in two lines
+	str = "Guiochini Amandine"
+	lines = pdf.SplitLines([]byte(str), 26)
+	y_start = pdf.GetY()
+	pdf.MultiCell(26, FontSize, str, "", "L", false)
+	y_end = pdf.GetY()
+
+	if len(lines) != 2 {
+		t.Fatalf("expect SplitLines split in two lines")
+	}
+	if int(y_end-y_start) != int(FontSize*2) {
+		t.Fatalf("expect MultiCell split in two lines %.2f != %.2f", y_end-y_start, FontSize*2)
+	}
+}
+
+// TestFooterFuncLpi tests to make sure the footer is not call twice and SetFooterFuncLpi can work
+// without SetFooterFunc.
+func TestFooterFuncLpi(t *testing.T) {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	var (
+		oldFooterFnc  = "oldFooterFnc"
+		bothPages     = "bothPages"
+		firstPageOnly = "firstPageOnly"
+		lastPageOnly  = "lastPageOnly"
+	)
+
+	// This set just for testing, only set SetFooterFuncLpi.
+	pdf.SetFooterFunc(func() {
+		pdf.SetY(-15)
+		pdf.SetFont("Arial", "I", 8)
+		pdf.CellFormat(0, 10, oldFooterFnc,
+			"", 0, "C", false, 0, "")
+	})
+	pdf.SetFooterFuncLpi(func(lastPage bool) {
+		pdf.SetY(-15)
+		pdf.SetFont("Arial", "I", 8)
+		pdf.CellFormat(0, 10, bothPages, "", 0, "L", false, 0, "")
+		if !lastPage {
+			pdf.CellFormat(0, 10, firstPageOnly, "", 0, "C", false, 0, "")
+		} else {
+			pdf.CellFormat(0, 10, lastPageOnly, "", 0, "C", false, 0, "")
+		}
+	})
+	pdf.AddPage()
+	pdf.SetFont("Arial", "B", 16)
+	for j := 1; j <= 40; j++ {
+		pdf.CellFormat(0, 10, fmt.Sprintf("Printing line number %d", j),
+			"", 1, "", false, 0, "")
+	}
+	if pdf.Error() != nil {
+		t.Fatalf("not expecting error when rendering text")
+	}
+	w := &bytes.Buffer{}
+	if err := pdf.Output(w); err != nil {
+		t.Errorf("unexpected err: %s", err)
+	}
+	b := w.Bytes()
+	if bytes.Contains(b, []byte(oldFooterFnc)) {
+		t.Errorf("not expecting %s render on pdf when FooterFncLpi is set", oldFooterFnc)
+	}
+	got := bytes.Count(b, []byte("bothPages"))
+	if got != 2 {
+		t.Errorf("footer %s should render on two page got:%d", bothPages, got)
+	}
+	got = bytes.Count(b, []byte(firstPageOnly))
+	if got != 1 {
+		t.Errorf("footer %s should render only on first page got: %d", firstPageOnly, got)
+	}
+	got = bytes.Count(b, []byte(lastPageOnly))
+	if got != 1 {
+		t.Errorf("footer %s should render only on first page got: %d", lastPageOnly, got)
+	}
+	f := bytes.Index(b, []byte(firstPageOnly))
+	l := bytes.Index(b, []byte(lastPageOnly))
+	if f > l {
+		t.Errorf("index %d (%s) should less than index %d (%s)", f, firstPageOnly, l, lastPageOnly)
+	}
+}
+
+type fontResourceType struct {
+}
+
+func (f fontResourceType) Open(name string) (rdr io.Reader, err error) {
+	var buf []byte
+	buf, err = ioutil.ReadFile(example.FontFile(name))
+	if err == nil {
+		rdr = bytes.NewReader(buf)
+		fmt.Printf("Generalized font loader reading %s\n", name)
+	}
+	return
+}
+
+// strDelimit converts 'ABCDEFG' to, for example, 'A,BCD,EFG'
+func strDelimit(str string, sepstr string, sepcount int) string {
+	pos := len(str) - sepcount
+	for pos > 0 {
+		str = str[:pos] + sepstr + str[pos:]
+		pos = pos - sepcount
+	}
+	return str
+}
+
+func loremList() []string {
+	return []string{
+		"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod " +
+			"tempor incididunt ut labore et dolore magna aliqua.",
+		"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " +
+			"aliquip ex ea commodo consequat.",
+		"Duis aute irure dolor in reprehenderit in voluptate velit esse cillum " +
+			"dolore eu fugiat nulla pariatur.",
+		"Excepteur sint occaecat cupidatat non proident, sunt in culpa qui " +
+			"officia deserunt mollit anim id est laborum.",
+	}
+}
+
+func lorem() string {
+	return strings.Join(loremList(), " ")
+}
+
+// Example demonstrates the generation of a simple PDF document. Note that
+// since only core fonts are used (in this case Arial, a synonym for
+// Helvetica), an empty string can be specified for the font directory in the
+// call to New(). Note also that the example.Filename() and example.Summary()
+// functions belong to a separate, internal package and are not part of the
+// gofpdf library. If an error occurs at some point during the construction of
+// the document, subsequent method calls exit immediately and the error is
+// finally retrieved with the output call where it can be handled by the
+// application.
+func Example() {
+	pdf := gofpdf.New(gofpdf.OrientationPortrait, "mm", "A4", "")
+	pdf.AddPage()
+	pdf.SetFont("Arial", "B", 16)
+	pdf.Cell(40, 10, "Hello World!")
+	fileStr := example.Filename("basic")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/basic.pdf
+}
+
+// ExampleFpdf_AddPage demonsrates the generation of headers, footers and page breaks.
+func ExampleFpdf_AddPage() {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.SetTopMargin(30)
+	pdf.SetHeaderFuncMode(func() {
+		pdf.Image(example.ImageFile("logo.png"), 10, 6, 30, 0, false, "", 0, "")
+		pdf.SetY(5)
+		pdf.SetFont("Arial", "B", 15)
+		pdf.Cell(80, 0, "")
+		pdf.CellFormat(30, 10, "Title", "1", 0, "C", false, 0, "")
+		pdf.Ln(20)
+	}, true)
+	pdf.SetFooterFunc(func() {
+		pdf.SetY(-15)
+		pdf.SetFont("Arial", "I", 8)
+		pdf.CellFormat(0, 10, fmt.Sprintf("Page %d/{nb}", pdf.PageNo()),
+			"", 0, "C", false, 0, "")
+	})
+	pdf.AliasNbPages("")
+	pdf.AddPage()
+	pdf.SetFont("Times", "", 12)
+	for j := 1; j <= 40; j++ {
+		pdf.CellFormat(0, 10, fmt.Sprintf("Printing line number %d", j),
+			"", 1, "", false, 0, "")
+	}
+	fileStr := example.Filename("Fpdf_AddPage")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_AddPage.pdf
+}
+
+// ExampleFpdf_MultiCell demonstrates word-wrapping, line justification and
+// page-breaking.
+func ExampleFpdf_MultiCell() {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	titleStr := "20000 Leagues Under the Seas"
+	pdf.SetTitle(titleStr, false)
+	pdf.SetAuthor("Jules Verne", false)
+	pdf.SetHeaderFunc(func() {
+		// Arial bold 15
+		pdf.SetFont("Arial", "B", 15)
+		// Calculate width of title and position
+		wd := pdf.GetStringWidth(titleStr) + 6
+		pdf.SetX((210 - wd) / 2)
+		// Colors of frame, background and text
+		pdf.SetDrawColor(0, 80, 180)
+		pdf.SetFillColor(230, 230, 0)
+		pdf.SetTextColor(220, 50, 50)
+		// Thickness of frame (1 mm)
+		pdf.SetLineWidth(1)
+		// Title
+		pdf.CellFormat(wd, 9, titleStr, "1", 1, "C", true, 0, "")
+		// Line break
+		pdf.Ln(10)
+	})
+	pdf.SetFooterFunc(func() {
+		// Position at 1.5 cm from bottom
+		pdf.SetY(-15)
+		// Arial italic 8
+		pdf.SetFont("Arial", "I", 8)
+		// Text color in gray
+		pdf.SetTextColor(128, 128, 128)
+		// Page number
+		pdf.CellFormat(0, 10, fmt.Sprintf("Page %d", pdf.PageNo()),
+			"", 0, "C", false, 0, "")
+	})
+	chapterTitle := func(chapNum int, titleStr string) {
+		// 	// Arial 12
+		pdf.SetFont("Arial", "", 12)
+		// Background color
+		pdf.SetFillColor(200, 220, 255)
+		// Title
+		pdf.CellFormat(0, 6, fmt.Sprintf("Chapter %d : %s", chapNum, titleStr),
+			"", 1, "L", true, 0, "")
+		// Line break
+		pdf.Ln(4)
+	}
+	chapterBody := func(fileStr string) {
+		// Read text file
+		txtStr, err := ioutil.ReadFile(fileStr)
+		if err != nil {
+			pdf.SetError(err)
+		}
+		// Times 12
+		pdf.SetFont("Times", "", 12)
+		// Output justified text
+		pdf.MultiCell(0, 5, string(txtStr), "", "", false)
+		// Line break
+		pdf.Ln(-1)
+		// Mention in italics
+		pdf.SetFont("", "I", 0)
+		pdf.Cell(0, 5, "(end of excerpt)")
+	}
+	printChapter := func(chapNum int, titleStr, fileStr string) {
+		pdf.AddPage()
+		chapterTitle(chapNum, titleStr)
+		chapterBody(fileStr)
+	}
+	printChapter(1, "A RUNAWAY REEF", example.TextFile("20k_c1.txt"))
+	printChapter(2, "THE PROS AND CONS", example.TextFile("20k_c2.txt"))
+	fileStr := example.Filename("Fpdf_MultiCell")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_MultiCell.pdf
+}
+
+// ExampleFpdf_SetLeftMargin demonstrates the generation of a PDF document that has multiple
+// columns. This is accomplished with the SetLeftMargin() and Cell() methods.
+func ExampleFpdf_SetLeftMargin() {
+	var y0 float64
+	var crrntCol int
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.SetDisplayMode("fullpage", "TwoColumnLeft")
+	titleStr := "20000 Leagues Under the Seas"
+	pdf.SetTitle(titleStr, false)
+	pdf.SetAuthor("Jules Verne", false)
+	setCol := func(col int) {
+		// Set position at a given column
+		crrntCol = col
+		x := 10.0 + float64(col)*65.0
+		pdf.SetLeftMargin(x)
+		pdf.SetX(x)
+	}
+	chapterTitle := func(chapNum int, titleStr string) {
+		// Arial 12
+		pdf.SetFont("Arial", "", 12)
+		// Background color
+		pdf.SetFillColor(200, 220, 255)
+		// Title
+		pdf.CellFormat(0, 6, fmt.Sprintf("Chapter %d : %s", chapNum, titleStr),
+			"", 1, "L", true, 0, "")
+		// Line break
+		pdf.Ln(4)
+		y0 = pdf.GetY()
+	}
+	chapterBody := func(fileStr string) {
+		// Read text file
+		txtStr, err := ioutil.ReadFile(fileStr)
+		if err != nil {
+			pdf.SetError(err)
+		}
+		// Font
+		pdf.SetFont("Times", "", 12)
+		// Output text in a 6 cm width column
+		pdf.MultiCell(60, 5, string(txtStr), "", "", false)
+		pdf.Ln(-1)
+		// Mention
+		pdf.SetFont("", "I", 0)
+		pdf.Cell(0, 5, "(end of excerpt)")
+		// Go back to first column
+		setCol(0)
+	}
+	printChapter := func(num int, titleStr, fileStr string) {
+		// Add chapter
+		pdf.AddPage()
+		chapterTitle(num, titleStr)
+		chapterBody(fileStr)
+	}
+	pdf.SetAcceptPageBreakFunc(func() bool {
+		// Method accepting or not automatic page break
+		if crrntCol < 2 {
+			// Go to next column
+			setCol(crrntCol + 1)
+			// Set ordinate to top
+			pdf.SetY(y0)
+			// Keep on page
+			return false
+		}
+		// Go back to first column
+		setCol(0)
+		// Page break
+		return true
+	})
+	pdf.SetHeaderFunc(func() {
+		// Arial bold 15
+		pdf.SetFont("Arial", "B", 15)
+		// Calculate width of title and position
+		wd := pdf.GetStringWidth(titleStr) + 6
+		pdf.SetX((210 - wd) / 2)
+		// Colors of frame, background and text
+		pdf.SetDrawColor(0, 80, 180)
+		pdf.SetFillColor(230, 230, 0)
+		pdf.SetTextColor(220, 50, 50)
+		// Thickness of frame (1 mm)
+		pdf.SetLineWidth(1)
+		// Title
+		pdf.CellFormat(wd, 9, titleStr, "1", 1, "C", true, 0, "")
+		// Line break
+		pdf.Ln(10)
+		// Save ordinate
+		y0 = pdf.GetY()
+	})
+	pdf.SetFooterFunc(func() {
+		// Position at 1.5 cm from bottom
+		pdf.SetY(-15)
+		// Arial italic 8
+		pdf.SetFont("Arial", "I", 8)
+		// Text color in gray
+		pdf.SetTextColor(128, 128, 128)
+		// Page number
+		pdf.CellFormat(0, 10, fmt.Sprintf("Page %d", pdf.PageNo()),
+			"", 0, "C", false, 0, "")
+	})
+	printChapter(1, "A RUNAWAY REEF", example.TextFile("20k_c1.txt"))
+	printChapter(2, "THE PROS AND CONS", example.TextFile("20k_c2.txt"))
+	fileStr := example.Filename("Fpdf_SetLeftMargin_multicolumn")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_SetLeftMargin_multicolumn.pdf
+}
+
+// ExampleFpdf_SplitLines_tables demonstrates word-wrapped table cells
+func ExampleFpdf_SplitLines_tables() {
+	const (
+		colCount = 3
+		colWd    = 60.0
+		marginH  = 15.0
+		lineHt   = 5.5
+		cellGap  = 2.0
+	)
+	// var colStrList [colCount]string
+	type cellType struct {
+		str  string
+		list [][]byte
+		ht   float64
+	}
+	var (
+		cellList [colCount]cellType
+		cell     cellType
+	)
+
+	pdf := gofpdf.New("P", "mm", "A4", "") // 210 x 297
+	header := [colCount]string{"Column A", "Column B", "Column C"}
+	alignList := [colCount]string{"L", "C", "R"}
+	strList := loremList()
+	pdf.SetMargins(marginH, 15, marginH)
+	pdf.SetFont("Arial", "", 14)
+	pdf.AddPage()
+
+	// Headers
+	pdf.SetTextColor(224, 224, 224)
+	pdf.SetFillColor(64, 64, 64)
+	for colJ := 0; colJ < colCount; colJ++ {
+		pdf.CellFormat(colWd, 10, header[colJ], "1", 0, "CM", true, 0, "")
+	}
+	pdf.Ln(-1)
+	pdf.SetTextColor(24, 24, 24)
+	pdf.SetFillColor(255, 255, 255)
+
+	// Rows
+	y := pdf.GetY()
+	count := 0
+	for rowJ := 0; rowJ < 2; rowJ++ {
+		maxHt := lineHt
+		// Cell height calculation loop
+		for colJ := 0; colJ < colCount; colJ++ {
+			count++
+			if count > len(strList) {
+				count = 1
+			}
+			cell.str = strings.Join(strList[0:count], " ")
+			cell.list = pdf.SplitLines([]byte(cell.str), colWd-cellGap-cellGap)
+			cell.ht = float64(len(cell.list)) * lineHt
+			if cell.ht > maxHt {
+				maxHt = cell.ht
+			}
+			cellList[colJ] = cell
+		}
+		// Cell render loop
+		x := marginH
+		for colJ := 0; colJ < colCount; colJ++ {
+			pdf.Rect(x, y, colWd, maxHt+cellGap+cellGap, "D")
+			cell = cellList[colJ]
+			cellY := y + cellGap + (maxHt-cell.ht)/2
+			for splitJ := 0; splitJ < len(cell.list); splitJ++ {
+				pdf.SetXY(x+cellGap, cellY)
+				pdf.CellFormat(colWd-cellGap-cellGap, lineHt, string(cell.list[splitJ]), "", 0,
+					alignList[colJ], false, 0, "")
+				cellY += lineHt
+			}
+			x += colWd
+		}
+		y += maxHt + cellGap + cellGap
+	}
+
+	fileStr := example.Filename("Fpdf_SplitLines_tables")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_SplitLines_tables.pdf
+}
+
+// ExampleFpdf_CellFormat_tables demonstrates various table styles.
+func ExampleFpdf_CellFormat_tables() {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	type countryType struct {
+		nameStr, capitalStr, areaStr, popStr string
+	}
+	countryList := make([]countryType, 0, 8)
+	header := []string{"Country", "Capital", "Area (sq km)", "Pop. (thousands)"}
+	loadData := func(fileStr string) {
+		fl, err := os.Open(fileStr)
+		if err == nil {
+			scanner := bufio.NewScanner(fl)
+			var c countryType
+			for scanner.Scan() {
+				// Austria;Vienna;83859;8075
+				lineStr := scanner.Text()
+				list := strings.Split(lineStr, ";")
+				if len(list) == 4 {
+					c.nameStr = list[0]
+					c.capitalStr = list[1]
+					c.areaStr = list[2]
+					c.popStr = list[3]
+					countryList = append(countryList, c)
+				} else {
+					err = fmt.Errorf("error tokenizing %s", lineStr)
+				}
+			}
+			fl.Close()
+			if len(countryList) == 0 {
+				err = fmt.Errorf("error loading data from %s", fileStr)
+			}
+		}
+		if err != nil {
+			pdf.SetError(err)
+		}
+	}
+	// Simple table
+	basicTable := func() {
+		left := (210.0 - 4*40) / 2
+		pdf.SetX(left)
+		for _, str := range header {
+			pdf.CellFormat(40, 7, str, "1", 0, "", false, 0, "")
+		}
+		pdf.Ln(-1)
+		for _, c := range countryList {
+			pdf.SetX(left)
+			pdf.CellFormat(40, 6, c.nameStr, "1", 0, "", false, 0, "")
+			pdf.CellFormat(40, 6, c.capitalStr, "1", 0, "", false, 0, "")
+			pdf.CellFormat(40, 6, c.areaStr, "1", 0, "", false, 0, "")
+			pdf.CellFormat(40, 6, c.popStr, "1", 0, "", false, 0, "")
+			pdf.Ln(-1)
+		}
+	}
+	// Better table
+	improvedTable := func() {
+		// Column widths
+		w := []float64{40.0, 35.0, 40.0, 45.0}
+		wSum := 0.0
+		for _, v := range w {
+			wSum += v
+		}
+		left := (210 - wSum) / 2
+		// 	Header
+		pdf.SetX(left)
+		for j, str := range header {
+			pdf.CellFormat(w[j], 7, str, "1", 0, "C", false, 0, "")
+		}
+		pdf.Ln(-1)
+		// Data
+		for _, c := range countryList {
+			pdf.SetX(left)
+			pdf.CellFormat(w[0], 6, c.nameStr, "LR", 0, "", false, 0, "")
+			pdf.CellFormat(w[1], 6, c.capitalStr, "LR", 0, "", false, 0, "")
+			pdf.CellFormat(w[2], 6, strDelimit(c.areaStr, ",", 3),
+				"LR", 0, "R", false, 0, "")
+			pdf.CellFormat(w[3], 6, strDelimit(c.popStr, ",", 3),
+				"LR", 0, "R", false, 0, "")
+			pdf.Ln(-1)
+		}
+		pdf.SetX(left)
+		pdf.CellFormat(wSum, 0, "", "T", 0, "", false, 0, "")
+	}
+	// Colored table
+	fancyTable := func() {
+		// Colors, line width and bold font
+		pdf.SetFillColor(255, 0, 0)
+		pdf.SetTextColor(255, 255, 255)
+		pdf.SetDrawColor(128, 0, 0)
+		pdf.SetLineWidth(.3)
+		pdf.SetFont("", "B", 0)
+		// 	Header
+		w := []float64{40, 35, 40, 45}
+		wSum := 0.0
+		for _, v := range w {
+			wSum += v
+		}
+		left := (210 - wSum) / 2
+		pdf.SetX(left)
+		for j, str := range header {
+			pdf.CellFormat(w[j], 7, str, "1", 0, "C", true, 0, "")
+		}
+		pdf.Ln(-1)
+		// Color and font restoration
+		pdf.SetFillColor(224, 235, 255)
+		pdf.SetTextColor(0, 0, 0)
+		pdf.SetFont("", "", 0)
+		// 	Data
+		fill := false
+		for _, c := range countryList {
+			pdf.SetX(left)
+			pdf.CellFormat(w[0], 6, c.nameStr, "LR", 0, "", fill, 0, "")
+			pdf.CellFormat(w[1], 6, c.capitalStr, "LR", 0, "", fill, 0, "")
+			pdf.CellFormat(w[2], 6, strDelimit(c.areaStr, ",", 3),
+				"LR", 0, "R", fill, 0, "")
+			pdf.CellFormat(w[3], 6, strDelimit(c.popStr, ",", 3),
+				"LR", 0, "R", fill, 0, "")
+			pdf.Ln(-1)
+			fill = !fill
+		}
+		pdf.SetX(left)
+		pdf.CellFormat(wSum, 0, "", "T", 0, "", false, 0, "")
+	}
+	loadData(example.TextFile("countries.txt"))
+	pdf.SetFont("Arial", "", 14)
+	pdf.AddPage()
+	basicTable()
+	pdf.AddPage()
+	improvedTable()
+	pdf.AddPage()
+	fancyTable()
+	fileStr := example.Filename("Fpdf_CellFormat_tables")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_CellFormat_tables.pdf
+}
+
+// ExampleFpdf_HTMLBasicNew demonstrates internal and external links with and without basic
+// HTML.
+func ExampleFpdf_HTMLBasicNew() {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	// First page: manual local link
+	pdf.AddPage()
+	pdf.SetFont("Helvetica", "", 20)
+	_, lineHt := pdf.GetFontSize()
+	pdf.Write(lineHt, "To find out what's new in this tutorial, click ")
+	pdf.SetFont("", "U", 0)
+	link := pdf.AddLink()
+	pdf.WriteLinkID(lineHt, "here", link)
+	pdf.SetFont("", "", 0)
+	// Second page: image link and basic HTML with link
+	pdf.AddPage()
+	pdf.SetLink(link, 0, -1)
+	pdf.Image(example.ImageFile("logo.png"), 10, 12, 30, 0, false, "", 0, "http://www.fpdf.org")
+	pdf.SetLeftMargin(45)
+	pdf.SetFontSize(14)
+	_, lineHt = pdf.GetFontSize()
+	htmlStr := `You can now easily print text mixing different styles: <b>bold</b>, ` +
+		`<i>italic</i>, <u>underlined</u>, or <b><i><u>all at once</u></i></b>!<br><br>` +
+		`<center>You can also center text.</center>` +
+		`<right>Or align it to the right.</right>` +
+		`You can also insert links on text, such as ` +
+		`<a href="http://www.fpdf.org">www.fpdf.org</a>, or on an image: click on the logo.`
+	html := pdf.HTMLBasicNew()
+	html.Write(lineHt, htmlStr)
+	fileStr := example.Filename("Fpdf_HTMLBasicNew")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_HTMLBasicNew.pdf
+}
+
+// ExampleFpdf_AddFont demonstrates the use of a non-standard font.
+func ExampleFpdf_AddFont() {
+	pdf := gofpdf.New("P", "mm", "A4", example.FontDir())
+	pdf.AddFont("Calligrapher", "", "calligra.json")
+	pdf.AddPage()
+	pdf.SetFont("Calligrapher", "", 35)
+	pdf.Cell(0, 10, "Enjoy new fonts with FPDF!")
+	fileStr := example.Filename("Fpdf_AddFont")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_AddFont.pdf
+}
+
+// ExampleFpdf_WriteAligned demonstrates how to align text with the Write function.
+func ExampleFpdf_WriteAligned() {
+	pdf := gofpdf.New("P", "mm", "A4", example.FontDir())
+	pdf.SetLeftMargin(50.0)
+	pdf.SetRightMargin(50.0)
+	pdf.AddPage()
+	pdf.SetFont("Helvetica", "", 12)
+	pdf.WriteAligned(0, 35, "This text is the default alignment, Left", "")
+	pdf.Ln(35)
+	pdf.WriteAligned(0, 35, "This text is aligned Left", "L")
+	pdf.Ln(35)
+	pdf.WriteAligned(0, 35, "This text is aligned Center", "C")
+	pdf.Ln(35)
+	pdf.WriteAligned(0, 35, "This text is aligned Right", "R")
+	pdf.Ln(35)
+	line := "This can by used to write justified text"
+	leftMargin, _, rightMargin, _ := pdf.GetMargins()
+	pageWidth, _ := pdf.GetPageSize()
+	pageWidth -= leftMargin + rightMargin
+	pdf.SetWordSpacing((pageWidth - pdf.GetStringWidth(line)) / float64(strings.Count(line, " ")))
+	pdf.WriteAligned(pageWidth, 35, line, "L")
+	fileStr := example.Filename("Fpdf_WriteAligned")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_WriteAligned.pdf
+}
+
+// ExampleFpdf_Image demonstrates how images are included in documents.
+func ExampleFpdf_Image() {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.AddPage()
+	pdf.SetFont("Arial", "", 11)
+	pdf.Image(example.ImageFile("logo.png"), 10, 10, 30, 0, false, "", 0, "")
+	pdf.Text(50, 20, "logo.png")
+	pdf.Image(example.ImageFile("logo.gif"), 10, 40, 30, 0, false, "", 0, "")
+	pdf.Text(50, 50, "logo.gif")
+	pdf.Image(example.ImageFile("logo-gray.png"), 10, 70, 30, 0, false, "", 0, "")
+	pdf.Text(50, 80, "logo-gray.png")
+	pdf.Image(example.ImageFile("logo-rgb.png"), 10, 100, 30, 0, false, "", 0, "")
+	pdf.Text(50, 110, "logo-rgb.png")
+	pdf.Image(example.ImageFile("logo.jpg"), 10, 130, 30, 0, false, "", 0, "")
+	pdf.Text(50, 140, "logo.jpg")
+	fileStr := example.Filename("Fpdf_Image")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_Image.pdf
+}
+
+// ExampleFpdf_ImageOptions demonstrates how the AllowNegativePosition field of the
+// ImageOption struct can be used to affect horizontal image placement.
+func ExampleFpdf_ImageOptions() {
+	var opt gofpdf.ImageOptions
+
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.AddPage()
+	pdf.SetFont("Arial", "", 11)
+	pdf.SetX(60)
+	opt.ImageType = "png"
+	pdf.ImageOptions(example.ImageFile("logo.png"), -10, 10, 30, 0, false, opt, 0, "")
+	opt.AllowNegativePosition = true
+	pdf.ImageOptions(example.ImageFile("logo.png"), -10, 50, 30, 0, false, opt, 0, "")
+	fileStr := example.Filename("Fpdf_ImageOptions")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_ImageOptions.pdf
+}
+
+// ExampleFpdf_RegisterImageOptionsReader demonstrates how to load an image
+// from a io.Reader (in this case, a file) and register it with options.
+func ExampleFpdf_RegisterImageOptionsReader() {
+	var (
+		opt    gofpdf.ImageOptions
+		pdfStr string
+		fl     *os.File
+		err    error
+	)
+
+	pdfStr = example.Filename("Fpdf_RegisterImageOptionsReader")
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.AddPage()
+	pdf.SetFont("Arial", "", 11)
+	fl, err = os.Open(example.ImageFile("logo.png"))
+	if err == nil {
+		opt.ImageType = "png"
+		opt.AllowNegativePosition = true
+		_ = pdf.RegisterImageOptionsReader("logo", opt, fl)
+		fl.Close()
+		for x := -20.0; x <= 40.0; x += 5 {
+			pdf.ImageOptions("logo", x, x+30, 0, 0, false, opt, 0, "")
+		}
+		err = pdf.OutputFileAndClose(pdfStr)
+	}
+	example.Summary(err, pdfStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_RegisterImageOptionsReader.pdf
+}
+
+// This example demonstrates Landscape mode with images.
+func ExampleFpdf_SetAcceptPageBreakFunc() {
+	var y0 float64
+	var crrntCol int
+	loremStr := lorem()
+	pdf := gofpdf.New("L", "mm", "A4", "")
+	const (
+		pageWd = 297.0 // A4 210.0 x 297.0
+		margin = 10.0
+		gutter = 4
+		colNum = 3
+		colWd  = (pageWd - 2*margin - (colNum-1)*gutter) / colNum
+	)
+	setCol := func(col int) {
+		crrntCol = col
+		x := margin + float64(col)*(colWd+gutter)
+		pdf.SetLeftMargin(x)
+		pdf.SetX(x)
+	}
+	pdf.SetHeaderFunc(func() {
+		titleStr := "gofpdf"
+		pdf.SetFont("Helvetica", "B", 48)
+		wd := pdf.GetStringWidth(titleStr) + 6
+		pdf.SetX((pageWd - wd) / 2)
+		pdf.SetTextColor(128, 128, 160)
+		pdf.Write(12, titleStr[:2])
+		pdf.SetTextColor(128, 128, 128)
+		pdf.Write(12, titleStr[2:])
+		pdf.Ln(20)
+		y0 = pdf.GetY()
+	})
+	pdf.SetAcceptPageBreakFunc(func() bool {
+		if crrntCol < colNum-1 {
+			setCol(crrntCol + 1)
+			pdf.SetY(y0)
+			// Start new column, not new page
+			return false
+		}
+		setCol(0)
+		return true
+	})
+	pdf.AddPage()
+	pdf.SetFont("Times", "", 12)
+	for j := 0; j < 20; j++ {
+		if j == 1 {
+			pdf.Image(example.ImageFile("fpdf.png"), -1, 0, colWd, 0, true, "", 0, "")
+		} else if j == 5 {
+			pdf.Image(example.ImageFile("golang-gopher.png"),
+				-1, 0, colWd, 0, true, "", 0, "")
+		}
+		pdf.MultiCell(colWd, 5, loremStr, "", "", false)
+		pdf.Ln(-1)
+	}
+	fileStr := example.Filename("Fpdf_SetAcceptPageBreakFunc_landscape")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_SetAcceptPageBreakFunc_landscape.pdf
+}
+
+// This example tests corner cases as reported by the gocov tool.
+func ExampleFpdf_SetKeywords() {
+	var err error
+	fileStr := example.Filename("Fpdf_SetKeywords")
+	err = gofpdf.MakeFont(example.FontFile("CalligrapherRegular.pfb"),
+		example.FontFile("cp1252.map"), example.FontDir(), nil, true)
+	if err == nil {
+		pdf := gofpdf.New("", "", "", "")
+		pdf.SetFontLocation(example.FontDir())
+		pdf.SetTitle("世界", true)
+		pdf.SetAuthor("世界", true)
+		pdf.SetSubject("世界", true)
+		pdf.SetCreator("世界", true)
+		pdf.SetKeywords("世界", true)
+		pdf.AddFont("Calligrapher", "", "CalligrapherRegular.json")
+		pdf.AddPage()
+		pdf.SetFont("Calligrapher", "", 16)
+		pdf.Writef(5, "\x95 %s \x95", pdf)
+		err = pdf.OutputFileAndClose(fileStr)
+	}
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_SetKeywords.pdf
+}
+
+// ExampleFpdf_Circle demonstrates the construction of various geometric figures,
+func ExampleFpdf_Circle() {
+	const (
+		thin  = 0.2
+		thick = 3.0
+	)
+	pdf := gofpdf.New("", "", "", "")
+	pdf.SetFont("Helvetica", "", 12)
+	pdf.SetFillColor(200, 200, 220)
+	pdf.AddPage()
+
+	y := 15.0
+	pdf.Text(10, y, "Circles")
+	pdf.SetFillColor(200, 200, 220)
+	pdf.SetLineWidth(thin)
+	pdf.Circle(20, y+15, 10, "D")
+	pdf.Circle(45, y+15, 10, "F")
+	pdf.Circle(70, y+15, 10, "FD")
+	pdf.SetLineWidth(thick)
+	pdf.Circle(95, y+15, 10, "FD")
+	pdf.SetLineWidth(thin)
+
+	y += 40.0
+	pdf.Text(10, y, "Ellipses")
+	pdf.SetFillColor(220, 200, 200)
+	pdf.Ellipse(30, y+15, 20, 10, 0, "D")
+	pdf.Ellipse(75, y+15, 20, 10, 0, "F")
+	pdf.Ellipse(120, y+15, 20, 10, 0, "FD")
+	pdf.SetLineWidth(thick)
+	pdf.Ellipse(165, y+15, 20, 10, 0, "FD")
+	pdf.SetLineWidth(thin)
+
+	y += 40.0
+	pdf.Text(10, y, "Curves (quadratic)")
+	pdf.SetFillColor(220, 220, 200)
+	pdf.Curve(10, y+30, 15, y-20, 40, y+30, "D")
+	pdf.Curve(45, y+30, 50, y-20, 75, y+30, "F")
+	pdf.Curve(80, y+30, 85, y-20, 110, y+30, "FD")
+	pdf.SetLineWidth(thick)
+	pdf.Curve(115, y+30, 120, y-20, 145, y+30, "FD")
+	pdf.SetLineCapStyle("round")
+	pdf.Curve(150, y+30, 155, y-20, 180, y+30, "FD")
+	pdf.SetLineWidth(thin)
+	pdf.SetLineCapStyle("butt")
+
+	y += 40.0
+	pdf.Text(10, y, "Curves (cubic)")
+	pdf.SetFillColor(220, 200, 220)
+	pdf.CurveBezierCubic(10, y+30, 15, y-20, 10, y+30, 40, y+30, "D")
+	pdf.CurveBezierCubic(45, y+30, 50, y-20, 45, y+30, 75, y+30, "F")
+	pdf.CurveBezierCubic(80, y+30, 85, y-20, 80, y+30, 110, y+30, "FD")
+	pdf.SetLineWidth(thick)
+	pdf.CurveBezierCubic(115, y+30, 120, y-20, 115, y+30, 145, y+30, "FD")
+	pdf.SetLineCapStyle("round")
+	pdf.CurveBezierCubic(150, y+30, 155, y-20, 150, y+30, 180, y+30, "FD")
+	pdf.SetLineWidth(thin)
+	pdf.SetLineCapStyle("butt")
+
+	y += 40.0
+	pdf.Text(10, y, "Arcs")
+	pdf.SetFillColor(200, 220, 220)
+	pdf.SetLineWidth(thick)
+	pdf.Arc(45, y+35, 20, 10, 0, 0, 180, "FD")
+	pdf.SetLineWidth(thin)
+	pdf.Arc(45, y+35, 25, 15, 0, 90, 270, "D")
+	pdf.SetLineWidth(thick)
+	pdf.Arc(45, y+35, 30, 20, 0, 0, 360, "D")
+	pdf.SetLineCapStyle("round")
+	pdf.Arc(135, y+35, 20, 10, 135, 0, 180, "FD")
+	pdf.SetLineWidth(thin)
+	pdf.Arc(135, y+35, 25, 15, 135, 90, 270, "D")
+	pdf.SetLineWidth(thick)
+	pdf.Arc(135, y+35, 30, 20, 135, 0, 360, "D")
+	pdf.SetLineWidth(thin)
+	pdf.SetLineCapStyle("butt")
+
+	fileStr := example.Filename("Fpdf_Circle_figures")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_Circle_figures.pdf
+}
+
+// ExampleFpdf_SetAlpha demonstrates alpha transparency.
+func ExampleFpdf_SetAlpha() {
+	const (
+		gapX  = 10.0
+		gapY  = 9.0
+		rectW = 40.0
+		rectH = 58.0
+		pageW = 210
+		pageH = 297
+	)
+	modeList := []string{"Normal", "Multiply", "Screen", "Overlay",
+		"Darken", "Lighten", "ColorDodge", "ColorBurn", "HardLight", "SoftLight",
+		"Difference", "Exclusion", "Hue", "Saturation", "Color", "Luminosity"}
+	pdf := gofpdf.New("", "", "", "")
+	pdf.SetLineWidth(2)
+	pdf.SetAutoPageBreak(false, 0)
+	pdf.AddPage()
+	pdf.SetFont("Helvetica", "", 18)
+	pdf.SetXY(0, gapY)
+	pdf.SetTextColor(0, 0, 0)
+	pdf.CellFormat(pageW, gapY, "Alpha Blending Modes", "", 0, "C", false, 0, "")
+	j := 0
+	y := 3 * gapY
+	for col := 0; col < 4; col++ {
+		x := gapX
+		for row := 0; row < 4; row++ {
+			pdf.Rect(x, y, rectW, rectH, "D")
+			pdf.SetFont("Helvetica", "B", 12)
+			pdf.SetFillColor(0, 0, 0)
+			pdf.SetTextColor(250, 250, 230)
+			pdf.SetXY(x, y+rectH-4)
+			pdf.CellFormat(rectW, 5, modeList[j], "", 0, "C", true, 0, "")
+			pdf.SetFont("Helvetica", "I", 150)
+			pdf.SetTextColor(80, 80, 120)
+			pdf.SetXY(x, y+2)
+			pdf.CellFormat(rectW, rectH, "A", "", 0, "C", false, 0, "")
+			pdf.SetAlpha(0.5, modeList[j])
+			pdf.Image(example.ImageFile("golang-gopher.png"),
+				x-gapX, y, rectW+2*gapX, 0, false, "", 0, "")
+			pdf.SetAlpha(1.0, "Normal")
+			x += rectW + gapX
+			j++
+		}
+		y += rectH + gapY
+	}
+	fileStr := example.Filename("Fpdf_SetAlpha_transparency")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_SetAlpha_transparency.pdf
+}
+
+// ExampleFpdf_LinearGradient deomstrates various gradients.
+func ExampleFpdf_LinearGradient() {
+	pdf := gofpdf.New("", "", "", "")
+	pdf.SetFont("Helvetica", "", 12)
+	pdf.AddPage()
+	pdf.LinearGradient(0, 0, 210, 100, 250, 250, 255, 220, 220, 225, 0, 0, 0, .5)
+	pdf.LinearGradient(20, 25, 75, 75, 220, 220, 250, 80, 80, 220, 0, .2, 0, .8)
+	pdf.Rect(20, 25, 75, 75, "D")
+	pdf.LinearGradient(115, 25, 75, 75, 220, 220, 250, 80, 80, 220, 0, 0, 1, 1)
+	pdf.Rect(115, 25, 75, 75, "D")
+	pdf.RadialGradient(20, 120, 75, 75, 220, 220, 250, 80, 80, 220,
+		0.25, 0.75, 0.25, 0.75, 1)
+	pdf.Rect(20, 120, 75, 75, "D")
+	pdf.RadialGradient(115, 120, 75, 75, 220, 220, 250, 80, 80, 220,
+		0.25, 0.75, 0.75, 0.75, 0.75)
+	pdf.Rect(115, 120, 75, 75, "D")
+	fileStr := example.Filename("Fpdf_LinearGradient_gradient")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_LinearGradient_gradient.pdf
+}
+
+// ExampleFpdf_ClipText demonstrates clipping.
+func ExampleFpdf_ClipText() {
+	pdf := gofpdf.New("", "", "", "")
+	y := 10.0
+	pdf.AddPage()
+
+	pdf.SetFont("Helvetica", "", 24)
+	pdf.SetXY(0, y)
+	pdf.ClipText(10, y+12, "Clipping examples", false)
+	pdf.RadialGradient(10, y, 100, 20, 128, 128, 160, 32, 32, 48,
+		0.25, 0.5, 0.25, 0.5, 0.2)
+	pdf.ClipEnd()
+
+	y += 12
+	pdf.SetFont("Helvetica", "B", 120)
+	pdf.SetDrawColor(64, 80, 80)
+	pdf.SetLineWidth(.5)
+	pdf.ClipText(10, y+40, pdf.String(), true)
+	pdf.RadialGradient(10, y, 200, 50, 220, 220, 250, 80, 80, 220,
+		0.25, 0.5, 0.25, 0.5, 1)
+	pdf.ClipEnd()
+
+	y += 55
+	pdf.ClipRect(10, y, 105, 20, true)
+	pdf.SetFillColor(255, 255, 255)
+	pdf.Rect(10, y, 105, 20, "F")
+	pdf.ClipCircle(40, y+10, 15, false)
+	pdf.RadialGradient(25, y, 30, 30, 220, 250, 220, 40, 60, 40, 0.3,
+		0.85, 0.3, 0.85, 0.5)
+	pdf.ClipEnd()
+	pdf.ClipEllipse(80, y+10, 20, 15, false)
+	pdf.RadialGradient(60, y, 40, 30, 250, 220, 220, 60, 40, 40, 0.3,
+		0.85, 0.3, 0.85, 0.5)
+	pdf.ClipEnd()
+	pdf.ClipEnd()
+
+	y += 28
+	pdf.ClipEllipse(26, y+10, 16, 10, true)
+	pdf.Image(example.ImageFile("logo.jpg"), 10, y, 32, 0, false, "JPG", 0, "")
+	pdf.ClipEnd()
+
+	pdf.ClipCircle(60, y+10, 10, true)
+	pdf.RadialGradient(50, y, 20, 20, 220, 220, 250, 40, 40, 60, 0.3,
+		0.7, 0.3, 0.7, 0.5)
+	pdf.ClipEnd()
+
+	pdf.ClipPolygon([]gofpdf.PointType{{X: 80, Y: y + 20}, {X: 90, Y: y},
+		{X: 100, Y: y + 20}}, true)
+	pdf.LinearGradient(80, y, 20, 20, 250, 220, 250, 60, 40, 60, 0.5,
+		1, 0.5, 0.5)
+	pdf.ClipEnd()
+
+	y += 30
+	pdf.SetLineWidth(.1)
+	pdf.SetDrawColor(180, 180, 180)
+	pdf.ClipRoundedRect(10, y, 120, 20, 5, true)
+	pdf.RadialGradient(10, y, 120, 20, 255, 255, 255, 240, 240, 220,
+		0.25, 0.75, 0.25, 0.75, 0.5)
+	pdf.SetXY(5, y-5)
+	pdf.SetFont("Times", "", 12)
+	pdf.MultiCell(130, 5, lorem(), "", "", false)
+	pdf.ClipEnd()
+
+	y += 30
+	pdf.SetDrawColor(180, 100, 180)
+	pdf.ClipRoundedRectExt(10, y, 120, 20, 5, 10, 5, 10, true)
+	pdf.RadialGradient(10, y, 120, 20, 255, 255, 255, 240, 240, 220,
+		0.25, 0.75, 0.25, 0.75, 0.5)
+	pdf.SetXY(5, y-5)
+	pdf.SetFont("Times", "", 12)
+	pdf.MultiCell(130, 5, lorem(), "", "", false)
+	pdf.ClipEnd()
+
+	fileStr := example.Filename("Fpdf_ClipText")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_ClipText.pdf
+}
+
+// ExampleFpdf_PageSize generates a PDF document with various page sizes.
+func ExampleFpdf_PageSize() {
+	pdf := gofpdf.NewCustom(&gofpdf.InitType{
+		UnitStr:    "in",
+		Size:       gofpdf.SizeType{Wd: 6, Ht: 6},
+		FontDirStr: example.FontDir(),
+	})
+	pdf.SetMargins(0.5, 1, 0.5)
+	pdf.SetFont("Times", "", 14)
+	pdf.AddPageFormat("L", gofpdf.SizeType{Wd: 3, Ht: 12})
+	pdf.SetXY(0.5, 1.5)
+	pdf.CellFormat(11, 0.2, "12 in x 3 in", "", 0, "C", false, 0, "")
+	pdf.AddPage() // Default size established in NewCustom()
+	pdf.SetXY(0.5, 3)
+	pdf.CellFormat(5, 0.2, "6 in x 6 in", "", 0, "C", false, 0, "")
+	pdf.AddPageFormat("P", gofpdf.SizeType{Wd: 3, Ht: 12})
+	pdf.SetXY(0.5, 6)
+	pdf.CellFormat(2, 0.2, "3 in x 12 in", "", 0, "C", false, 0, "")
+	for j := 0; j <= 3; j++ {
+		wd, ht, u := pdf.PageSize(j)
+		fmt.Printf("%d: %6.2f %s, %6.2f %s\n", j, wd, u, ht, u)
+	}
+	fileStr := example.Filename("Fpdf_PageSize")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// 0:   6.00 in,   6.00 in
+	// 1:  12.00 in,   3.00 in
+	// 2:   6.00 in,   6.00 in
+	// 3:   3.00 in,  12.00 in
+	// Successfully generated pdf/Fpdf_PageSize.pdf
+}
+
+// ExampleFpdf_Bookmark demonstrates the Bookmark method.
+func ExampleFpdf_Bookmark() {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.AddPage()
+	pdf.SetFont("Arial", "", 15)
+	pdf.Bookmark("Page 1", 0, 0)
+	pdf.Bookmark("Paragraph 1", 1, -1)
+	pdf.Cell(0, 6, "Paragraph 1")
+	pdf.Ln(50)
+	pdf.Bookmark("Paragraph 2", 1, -1)
+	pdf.Cell(0, 6, "Paragraph 2")
+	pdf.AddPage()
+	pdf.Bookmark("Page 2", 0, 0)
+	pdf.Bookmark("Paragraph 3", 1, -1)
+	pdf.Cell(0, 6, "Paragraph 3")
+	fileStr := example.Filename("Fpdf_Bookmark")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_Bookmark.pdf
+}
+
+// ExampleFpdf_TransformBegin demonstrates various transformations. It is adapted from an
+// example script by Moritz Wagner and Andreas Würmser.
+func ExampleFpdf_TransformBegin() {
+	const (
+		light = 200
+		dark  = 0
+	)
+	var refX, refY float64
+	var refStr string
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.AddPage()
+	color := func(val int) {
+		pdf.SetDrawColor(val, val, val)
+		pdf.SetTextColor(val, val, val)
+	}
+	reference := func(str string, x, y float64, val int) {
+		color(val)
+		pdf.Rect(x, y, 40, 10, "D")
+		pdf.Text(x, y-1, str)
+	}
+	refDraw := func(str string, x, y float64) {
+		refStr = str
+		refX = x
+		refY = y
+		reference(str, x, y, light)
+	}
+	refDupe := func() {
+		reference(refStr, refX, refY, dark)
+	}
+
+	titleStr := "Transformations"
+	titlePt := 36.0
+	titleHt := pdf.PointConvert(titlePt)
+	pdf.SetFont("Helvetica", "", titlePt)
+	titleWd := pdf.GetStringWidth(titleStr)
+	titleX := (210 - titleWd) / 2
+	pdf.Text(titleX, 10+titleHt, titleStr)
+	pdf.TransformBegin()
+	pdf.TransformMirrorVertical(10 + titleHt + 0.5)
+	pdf.ClipText(titleX, 10+titleHt, titleStr, false)
+	// Remember that the transform will mirror the gradient box too
+	pdf.LinearGradient(titleX, 10, titleWd, titleHt+4, 120, 120, 120,
+		255, 255, 255, 0, 0, 0, 0.6)
+	pdf.ClipEnd()
+	pdf.TransformEnd()
+
+	pdf.SetFont("Helvetica", "", 12)
+
+	// Scale by 150% centered by lower left corner of the rectangle
+	refDraw("Scale", 50, 60)
+	pdf.TransformBegin()
+	pdf.TransformScaleXY(150, 50, 70)
+	refDupe()
+	pdf.TransformEnd()
+
+	// Translate 7 to the right, 5 to the bottom
+	refDraw("Translate", 125, 60)
+	pdf.TransformBegin()
+	pdf.TransformTranslate(7, 5)
+	refDupe()
+	pdf.TransformEnd()
+
+	// Rotate 20 degrees counter-clockwise centered by the lower left corner of
+	// the rectangle
+	refDraw("Rotate", 50, 110)
+	pdf.TransformBegin()
+	pdf.TransformRotate(20, 50, 120)
+	refDupe()
+	pdf.TransformEnd()
+
+	// Skew 30 degrees along the x-axis centered by the lower left corner of the
+	// rectangle
+	refDraw("Skew", 125, 110)
+	pdf.TransformBegin()
+	pdf.TransformSkewX(30, 125, 110)
+	refDupe()
+	pdf.TransformEnd()
+
+	// Mirror horizontally with axis of reflection at left side of the rectangle
+	refDraw("Mirror horizontal", 50, 160)
+	pdf.TransformBegin()
+	pdf.TransformMirrorHorizontal(50)
+	refDupe()
+	pdf.TransformEnd()
+
+	// Mirror vertically with axis of reflection at bottom side of the rectangle
+	refDraw("Mirror vertical", 125, 160)
+	pdf.TransformBegin()
+	pdf.TransformMirrorVertical(170)
+	refDupe()
+	pdf.TransformEnd()
+
+	// Reflect against a point at the lower left point of rectangle
+	refDraw("Mirror point", 50, 210)
+	pdf.TransformBegin()
+	pdf.TransformMirrorPoint(50, 220)
+	refDupe()
+	pdf.TransformEnd()
+
+	// Mirror against a straight line described by a point and an angle
+	angle := -20.0
+	px := 120.0
+	py := 220.0
+	refDraw("Mirror line", 125, 210)
+	pdf.TransformBegin()
+	pdf.TransformRotate(angle, px, py)
+	pdf.Line(px-1, py-1, px+1, py+1)
+	pdf.Line(px-1, py+1, px+1, py-1)
+	pdf.Line(px-5, py, px+60, py)
+	pdf.TransformEnd()
+	pdf.TransformBegin()
+	pdf.TransformMirrorLine(angle, px, py)
+	refDupe()
+	pdf.TransformEnd()
+
+	fileStr := example.Filename("Fpdf_TransformBegin")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_TransformBegin.pdf
+}
+
+// ExampleFpdf_RegisterImage demonstrates Lawrence Kesteloot's image registration code.
+func ExampleFpdf_RegisterImage() {
+	const (
+		margin = 10
+		wd     = 210
+		ht     = 297
+	)
+	fileList := []string{
+		"logo-gray.png",
+		"logo.jpg",
+		"logo.png",
+		"logo-rgb.png",
+		"logo-progressive.jpg",
+	}
+	var infoPtr *gofpdf.ImageInfoType
+	var imageFileStr string
+	var imgWd, imgHt, lf, tp float64
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.AddPage()
+	pdf.SetMargins(10, 10, 10)
+	pdf.SetFont("Helvetica", "", 15)
+	for j, str := range fileList {
+		imageFileStr = example.ImageFile(str)
+		infoPtr = pdf.RegisterImage(imageFileStr, "")
+		imgWd, imgHt = infoPtr.Extent()
+		switch j {
+		case 0:
+			lf = margin
+			tp = margin
+		case 1:
+			lf = wd - margin - imgWd
+			tp = margin
+		case 2:
+			lf = (wd - imgWd) / 2.0
+			tp = (ht - imgHt) / 2.0
+		case 3:
+			lf = margin
+			tp = ht - imgHt - margin
+		case 4:
+			lf = wd - imgWd - margin
+			tp = ht - imgHt - margin
+		}
+		pdf.Image(imageFileStr, lf, tp, imgWd, imgHt, false, "", 0, "")
+	}
+	fileStr := example.Filename("Fpdf_RegisterImage")
+	// Test the image information retrieval method
+	infoShow := func(imageStr string) {
+		imageStr = example.ImageFile(imageStr)
+		info := pdf.GetImageInfo(imageStr)
+		if info != nil {
+			if info.Width() > 0.0 {
+				fmt.Printf("Image %s is registered\n", filepath.ToSlash(imageStr))
+			} else {
+				fmt.Printf("Incorrect information for image %s\n", filepath.ToSlash(imageStr))
+			}
+		} else {
+			fmt.Printf("Image %s is not registered\n", filepath.ToSlash(imageStr))
+		}
+	}
+	infoShow(fileList[0])
+	infoShow("foo.png")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Image image/logo-gray.png is registered
+	// Image image/foo.png is not registered
+	// Successfully generated pdf/Fpdf_RegisterImage.pdf
+}
+
+// ExampleFpdf_SplitLines demonstrates Bruno Michel's line splitting function.
+func ExampleFpdf_SplitLines() {
+	const (
+		fontPtSize = 18.0
+		wd         = 100.0
+	)
+	pdf := gofpdf.New("P", "mm", "A4", "") // A4 210.0 x 297.0
+	pdf.SetFont("Times", "", fontPtSize)
+	_, lineHt := pdf.GetFontSize()
+	pdf.AddPage()
+	pdf.SetMargins(10, 10, 10)
+	lines := pdf.SplitLines([]byte(lorem()), wd)
+	ht := float64(len(lines)) * lineHt
+	y := (297.0 - ht) / 2.0
+	pdf.SetDrawColor(128, 128, 128)
+	pdf.SetFillColor(255, 255, 210)
+	x := (210.0 - (wd + 40.0)) / 2.0
+	pdf.Rect(x, y-20.0, wd+40.0, ht+40.0, "FD")
+	pdf.SetY(y)
+	for _, line := range lines {
+		pdf.CellFormat(190.0, lineHt, string(line), "", 1, "C", false, 0, "")
+	}
+	fileStr := example.Filename("Fpdf_Splitlines")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_Splitlines.pdf
+}
+
+// ExampleFpdf_SVGBasicWrite demonstrates how to render a simple path-only SVG image of the
+// type generated by the jSignature web control.
+func ExampleFpdf_SVGBasicWrite() {
+	const (
+		fontPtSize = 16.0
+		wd         = 100.0
+		sigFileStr = "signature.svg"
+	)
+	var (
+		sig gofpdf.SVGBasicType
+		err error
+	)
+	pdf := gofpdf.New("P", "mm", "A4", "") // A4 210.0 x 297.0
+	pdf.SetFont("Times", "", fontPtSize)
+	lineHt := pdf.PointConvert(fontPtSize)
+	pdf.AddPage()
+	pdf.SetMargins(10, 10, 10)
+	htmlStr := `This example renders a simple ` +
+		`<a href="http://www.w3.org/TR/SVG/">SVG</a> (scalable vector graphics) ` +
+		`image that contains only basic path commands without any styling, ` +
+		`color fill, reflection or endpoint closures. In particular, the ` +
+		`type of vector graphic returned from a ` +
+		`<a href="http://willowsystems.github.io/jSignature/#/demo/">jSignature</a> ` +
+		`web control is supported and is used in this example.`
+	html := pdf.HTMLBasicNew()
+	html.Write(lineHt, htmlStr)
+	sig, err = gofpdf.SVGBasicFileParse(example.ImageFile(sigFileStr))
+	if err == nil {
+		scale := 100 / sig.Wd
+		scaleY := 30 / sig.Ht
+		if scale > scaleY {
+			scale = scaleY
+		}
+		pdf.SetLineCapStyle("round")
+		pdf.SetLineWidth(0.25)
+		pdf.SetDrawColor(0, 0, 128)
+		pdf.SetXY((210.0-scale*sig.Wd)/2.0, pdf.GetY()+10)
+		pdf.SVGBasicWrite(&sig, scale)
+	} else {
+		pdf.SetError(err)
+	}
+	fileStr := example.Filename("Fpdf_SVGBasicWrite")
+	err = pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_SVGBasicWrite.pdf
+}
+
+// ExampleFpdf_CellFormat_align demonstrates Stefan Schroeder's code to control vertical
+// alignment.
+func ExampleFpdf_CellFormat_align() {
+	type recType struct {
+		align, txt string
+	}
+	recList := []recType{
+		{"TL", "top left"},
+		{"TC", "top center"},
+		{"TR", "top right"},
+		{"LM", "middle left"},
+		{"CM", "middle center"},
+		{"RM", "middle right"},
+		{"BL", "bottom left"},
+		{"BC", "bottom center"},
+		{"BR", "bottom right"},
+	}
+	recListBaseline := []recType{
+		{"AL", "baseline left"},
+		{"AC", "baseline center"},
+		{"AR", "baseline right"},
+	}
+	var formatRect = func(pdf *gofpdf.Fpdf, recList []recType) {
+		linkStr := ""
+		for pageJ := 0; pageJ < 2; pageJ++ {
+			pdf.AddPage()
+			pdf.SetMargins(10, 10, 10)
+			pdf.SetAutoPageBreak(false, 0)
+			borderStr := "1"
+			for _, rec := range recList {
+				pdf.SetXY(20, 20)
+				pdf.CellFormat(170, 257, rec.txt, borderStr, 0, rec.align, false, 0, linkStr)
+				borderStr = ""
+			}
+			linkStr = "https://github.com/jung-kurt/gofpdf"
+		}
+	}
+	pdf := gofpdf.New("P", "mm", "A4", "") // A4 210.0 x 297.0
+	pdf.SetFont("Helvetica", "", 16)
+	formatRect(pdf, recList)
+	formatRect(pdf, recListBaseline)
+	var fr fontResourceType
+	pdf.SetFontLoader(fr)
+	pdf.AddFont("Calligrapher", "", "calligra.json")
+	pdf.SetFont("Calligrapher", "", 16)
+	formatRect(pdf, recListBaseline)
+	fileStr := example.Filename("Fpdf_CellFormat_align")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Generalized font loader reading calligra.json
+	// Generalized font loader reading calligra.z
+	// Successfully generated pdf/Fpdf_CellFormat_align.pdf
+}
+
+// ExampleFpdf_CellFormat_codepageescape demonstrates the use of characters in the high range of the
+// Windows-1252 code page (gofdpf default). See the example for CellFormat (4)
+// for a way to do this automatically.
+func ExampleFpdf_CellFormat_codepageescape() {
+	pdf := gofpdf.New("P", "mm", "A4", "") // A4 210.0 x 297.0
+	fontSize := 16.0
+	pdf.SetFont("Helvetica", "", fontSize)
+	ht := pdf.PointConvert(fontSize)
+	write := func(str string) {
+		pdf.CellFormat(190, ht, str, "", 1, "C", false, 0, "")
+		pdf.Ln(ht)
+	}
+	pdf.AddPage()
+	htmlStr := `Until gofpdf supports UTF-8 encoded source text, source text needs ` +
+		`to be specified with all special characters escaped to match the code page ` +
+		`layout of the currently selected font. By default, gofdpf uses code page 1252.` +
+		` See <a href="http://en.wikipedia.org/wiki/Windows-1252">Wikipedia</a> for ` +
+		`a table of this layout.`
+	html := pdf.HTMLBasicNew()
+	html.Write(ht, htmlStr)
+	pdf.Ln(2 * ht)
+	write("Voix ambigu\xeb d'un c\x9cur qui au z\xe9phyr pr\xe9f\xe8re les jattes de kiwi.")
+	write("Falsches \xdcben von Xylophonmusik qu\xe4lt jeden gr\xf6\xdferen Zwerg.")
+	write("Heiz\xf6lr\xfccksto\xdfabd\xe4mpfung")
+	write("For\xe5rsj\xe6vnd\xf8gn / Efter\xe5rsj\xe6vnd\xf8gn")
+	fileStr := example.Filename("Fpdf_CellFormat_codepageescape")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_CellFormat_codepageescape.pdf
+}
+
+// ExampleFpdf_CellFormat_codepage demonstrates the automatic conversion of UTF-8 strings to an
+// 8-bit font encoding.
+func ExampleFpdf_CellFormat_codepage() {
+	pdf := gofpdf.New("P", "mm", "A4", example.FontDir()) // A4 210.0 x 297.0
+	// See documentation for details on how to generate fonts
+	pdf.AddFont("Helvetica-1251", "", "helvetica_1251.json")
+	pdf.AddFont("Helvetica-1253", "", "helvetica_1253.json")
+	fontSize := 16.0
+	pdf.SetFont("Helvetica", "", fontSize)
+	ht := pdf.PointConvert(fontSize)
+	tr := pdf.UnicodeTranslatorFromDescriptor("") // "" defaults to "cp1252"
+	write := func(str string) {
+		// pdf.CellFormat(190, ht, tr(str), "", 1, "C", false, 0, "")
+		pdf.MultiCell(190, ht, tr(str), "", "C", false)
+		pdf.Ln(ht)
+	}
+	pdf.AddPage()
+	str := `Gofpdf provides a translator that will convert any UTF-8 code point ` +
+		`that is present in the specified code page.`
+	pdf.MultiCell(190, ht, str, "", "L", false)
+	pdf.Ln(2 * ht)
+	write("Voix ambiguë d'un cœur qui au zéphyr préfère les jattes de kiwi.")
+	write("Falsches Üben von Xylophonmusik quält jeden größeren Zwerg.")
+	write("Heizölrückstoßabdämpfung")
+	write("Forårsjævndøgn / Efterårsjævndøgn")
+	write("À noite, vovô Kowalsky vê o ímã cair no pé do pingüim queixoso e vovó" +
+		"põe açúcar no chá de tâmaras do jabuti feliz.")
+	pdf.SetFont("Helvetica-1251", "", fontSize) // Name matches one specified in AddFont()
+	tr = pdf.UnicodeTranslatorFromDescriptor("cp1251")
+	write("Съешь же ещё этих мягких французских булок, да выпей чаю.")
+
+	pdf.SetFont("Helvetica-1253", "", fontSize)
+	tr = pdf.UnicodeTranslatorFromDescriptor("cp1253")
+	write("Θέλει αρετή και τόλμη η ελευθερία. (Ανδρέας Κάλβος)")
+
+	fileStr := example.Filename("Fpdf_CellFormat_codepage")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_CellFormat_codepage.pdf
+}
+
+// ExampleFpdf_SetProtection demonstrates password protection for documents.
+func ExampleFpdf_SetProtection() {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.SetProtection(gofpdf.CnProtectPrint, "123", "abc")
+	pdf.AddPage()
+	pdf.SetFont("Arial", "", 12)
+	pdf.Write(10, "Password-protected.")
+	fileStr := example.Filename("Fpdf_SetProtection")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_SetProtection.pdf
+}
+
+// ExampleFpdf_Polygon displays equilateral polygons in a demonstration of the Polygon
+// function.
+func ExampleFpdf_Polygon() {
+	const rowCount = 5
+	const colCount = 4
+	const ptSize = 36
+	var x, y, radius, gap, advance float64
+	var rgVal int
+	var pts []gofpdf.PointType
+	vertices := func(count int) (res []gofpdf.PointType) {
+		var pt gofpdf.PointType
+		res = make([]gofpdf.PointType, 0, count)
+		mlt := 2.0 * math.Pi / float64(count)
+		for j := 0; j < count; j++ {
+			pt.Y, pt.X = math.Sincos(float64(j) * mlt)
+			res = append(res, gofpdf.PointType{
+				X: x + radius*pt.X,
+				Y: y + radius*pt.Y})
+		}
+		return
+	}
+	pdf := gofpdf.New("P", "mm", "A4", "") // A4 210.0 x 297.0
+	pdf.AddPage()
+	pdf.SetFont("Helvetica", "", ptSize)
+	pdf.SetDrawColor(0, 80, 180)
+	gap = 12.0
+	pdf.SetY(gap)
+	pdf.CellFormat(190.0, gap, "Equilateral polygons", "", 1, "C", false, 0, "")
+	radius = (210.0 - float64(colCount+1)*gap) / (2.0 * float64(colCount))
+	advance = gap + 2.0*radius
+	y = 2*gap + pdf.PointConvert(ptSize) + radius
+	rgVal = 230
+	for row := 0; row < rowCount; row++ {
+		pdf.SetFillColor(rgVal, rgVal, 0)
+		rgVal -= 12
+		x = gap + radius
+		for col := 0; col < colCount; col++ {
+			pts = vertices(row*colCount + col + 3)
+			pdf.Polygon(pts, "FD")
+			x += advance
+		}
+		y += advance
+	}
+	fileStr := example.Filename("Fpdf_Polygon")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_Polygon.pdf
+}
+
+// ExampleFpdf_AddLayer demonstrates document layers. The initial visibility of a layer
+// is specified with the second parameter to AddLayer(). The layer list
+// displayed by the document reader allows layer visibility to be controlled
+// interactively.
+func ExampleFpdf_AddLayer() {
+
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.AddPage()
+	pdf.SetFont("Arial", "", 15)
+	pdf.Write(8, "This line doesn't belong to any layer.\n")
+
+	// Define layers
+	l1 := pdf.AddLayer("Layer 1", true)
+	l2 := pdf.AddLayer("Layer 2", true)
+
+	// Open layer pane in PDF viewer
+	pdf.OpenLayerPane()
+
+	// First layer
+	pdf.BeginLayer(l1)
+	pdf.Write(8, "This line belongs to layer 1.\n")
+	pdf.EndLayer()
+
+	// Second layer
+	pdf.BeginLayer(l2)
+	pdf.Write(8, "This line belongs to layer 2.\n")
+	pdf.EndLayer()
+
+	// First layer again
+	pdf.BeginLayer(l1)
+	pdf.Write(8, "This line belongs to layer 1 again.\n")
+	pdf.EndLayer()
+
+	fileStr := example.Filename("Fpdf_AddLayer")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_AddLayer.pdf
+}
+
+// ExampleFpdf_RegisterImageReader demonstrates the use of an image that is retrieved from a web
+// server.
+func ExampleFpdf_RegisterImageReader() {
+
+	const (
+		margin   = 10
+		wd       = 210
+		ht       = 297
+		fontSize = 15
+		urlStr   = "https://github.com/jung-kurt/gofpdf/blob/master/image/gofpdf.png?raw=true"
+		msgStr   = `Images from the web can be easily embedded when a PDF document is generated.`
+	)
+
+	var (
+		rsp *http.Response
+		err error
+		tp  string
+	)
+
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.AddPage()
+	pdf.SetFont("Helvetica", "", fontSize)
+	ln := pdf.PointConvert(fontSize)
+	pdf.MultiCell(wd-margin-margin, ln, msgStr, "", "L", false)
+	rsp, err = http.Get(urlStr)
+	if err == nil {
+		tp = pdf.ImageTypeFromMime(rsp.Header["Content-Type"][0])
+		infoPtr := pdf.RegisterImageReader(urlStr, tp, rsp.Body)
+		if pdf.Ok() {
+			imgWd, imgHt := infoPtr.Extent()
+			pdf.Image(urlStr, (wd-imgWd)/2.0, pdf.GetY()+ln,
+				imgWd, imgHt, false, tp, 0, "")
+		}
+	} else {
+		pdf.SetError(err)
+	}
+	fileStr := example.Filename("Fpdf_RegisterImageReader_url")
+	err = pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_RegisterImageReader_url.pdf
+
+}
+
+// ExampleFpdf_Beziergon demonstrates the Beziergon function.
+func ExampleFpdf_Beziergon() {
+
+	const (
+		margin      = 10
+		wd          = 210
+		unit        = (wd - 2*margin) / 6
+		ht          = 297
+		fontSize    = 15
+		msgStr      = `Demonstration of Beziergon function`
+		coefficient = 0.6
+		delta       = coefficient * unit
+		ln          = fontSize * 25.4 / 72
+		offsetX     = (wd - 4*unit) / 2.0
+		offsetY     = offsetX + 2*ln
+	)
+
+	srcList := []gofpdf.PointType{
+		{X: 0, Y: 0},
+		{X: 1, Y: 0},
+		{X: 1, Y: 1},
+		{X: 2, Y: 1},
+		{X: 2, Y: 2},
+		{X: 3, Y: 2},
+		{X: 3, Y: 3},
+		{X: 4, Y: 3},
+		{X: 4, Y: 4},
+		{X: 1, Y: 4},
+		{X: 1, Y: 3},
+		{X: 0, Y: 3},
+	}
+
+	ctrlList := []gofpdf.PointType{
+		{X: 1, Y: -1},
+		{X: 1, Y: 1},
+		{X: 1, Y: 1},
+		{X: 1, Y: 1},
+		{X: 1, Y: 1},
+		{X: 1, Y: 1},
+		{X: 1, Y: 1},
+		{X: 1, Y: 1},
+		{X: -1, Y: 1},
+		{X: -1, Y: -1},
+		{X: -1, Y: -1},
+		{X: -1, Y: -1},
+	}
+
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.AddPage()
+	pdf.SetFont("Helvetica", "", fontSize)
+	for j, src := range srcList {
+		srcList[j].X = offsetX + src.X*unit
+		srcList[j].Y = offsetY + src.Y*unit
+	}
+	for j, ctrl := range ctrlList {
+		ctrlList[j].X = ctrl.X * delta
+		ctrlList[j].Y = ctrl.Y * delta
+	}
+	jPrev := len(srcList) - 1
+	srcPrev := srcList[jPrev]
+	curveList := []gofpdf.PointType{srcPrev} // point [, control 0, control 1, point]*
+	control := func(x, y float64) {
+		curveList = append(curveList, gofpdf.PointType{X: x, Y: y})
+	}
+	for j, src := range srcList {
+		ctrl := ctrlList[jPrev]
+		control(srcPrev.X+ctrl.X, srcPrev.Y+ctrl.Y) // Control 0
+		ctrl = ctrlList[j]
+		control(src.X-ctrl.X, src.Y-ctrl.Y) // Control 1
+		curveList = append(curveList, src)  // Destination
+		jPrev = j
+		srcPrev = src
+	}
+	pdf.MultiCell(wd-margin-margin, ln, msgStr, "", "C", false)
+	pdf.SetDashPattern([]float64{0.8, 0.8}, 0)
+	pdf.SetDrawColor(160, 160, 160)
+	pdf.Polygon(srcList, "D")
+	pdf.SetDashPattern([]float64{}, 0)
+	pdf.SetDrawColor(64, 64, 128)
+	pdf.SetLineWidth(pdf.GetLineWidth() * 3)
+	pdf.Beziergon(curveList, "D")
+	fileStr := example.Filename("Fpdf_Beziergon")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_Beziergon.pdf
+
+}
+
+// ExampleFpdf_SetFontLoader demonstrates loading a non-standard font using a generalized
+// font loader. fontResourceType implements the FontLoader interface and is
+// defined locally in the test source code.
+func ExampleFpdf_SetFontLoader() {
+	var fr fontResourceType
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.SetFontLoader(fr)
+	pdf.AddFont("Calligrapher", "", "calligra.json")
+	pdf.AddPage()
+	pdf.SetFont("Calligrapher", "", 35)
+	pdf.Cell(0, 10, "Load fonts from any source")
+	fileStr := example.Filename("Fpdf_SetFontLoader")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Generalized font loader reading calligra.json
+	// Generalized font loader reading calligra.z
+	// Successfully generated pdf/Fpdf_SetFontLoader.pdf
+}
+
+// ExampleFpdf_MoveTo demonstrates the Path Drawing functions, such as: MoveTo,
+// LineTo, CurveTo, ..., ClosePath and DrawPath.
+func ExampleFpdf_MoveTo() {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.AddPage()
+	pdf.MoveTo(20, 20)
+	pdf.LineTo(170, 20)
+	pdf.ArcTo(170, 40, 20, 20, 0, 90, 0)
+	pdf.CurveTo(190, 100, 105, 100)
+	pdf.CurveBezierCubicTo(20, 100, 105, 200, 20, 200)
+	pdf.ClosePath()
+	pdf.SetFillColor(200, 200, 200)
+	pdf.SetLineWidth(3)
+	pdf.DrawPath("DF")
+	fileStr := example.Filename("Fpdf_MoveTo_path")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_MoveTo_path.pdf
+}
+
+// ExampleFpdf_SetLineJoinStyle demonstrates various line cap and line join styles.
+func ExampleFpdf_SetLineJoinStyle() {
+	const offset = 75.0
+	pdf := gofpdf.New("L", "mm", "A4", "")
+	pdf.AddPage()
+	var draw = func(cap, join string, x0, y0, x1, y1 float64) {
+		// transform begin & end needed to isolate caps and joins
+		pdf.SetLineCapStyle(cap)
+		pdf.SetLineJoinStyle(join)
+
+		// Draw thick line
+		pdf.SetDrawColor(0x33, 0x33, 0x33)
+		pdf.SetLineWidth(30.0)
+		pdf.MoveTo(x0, y0)
+		pdf.LineTo((x0+x1)/2+offset, (y0+y1)/2)
+		pdf.LineTo(x1, y1)
+		pdf.DrawPath("D")
+
+		// Draw thin helping line
+		pdf.SetDrawColor(0xFF, 0x33, 0x33)
+		pdf.SetLineWidth(2.56)
+		pdf.MoveTo(x0, y0)
+		pdf.LineTo((x0+x1)/2+offset, (y0+y1)/2)
+		pdf.LineTo(x1, y1)
+		pdf.DrawPath("D")
+
+	}
+	x := 35.0
+	caps := []string{"butt", "square", "round"}
+	joins := []string{"bevel", "miter", "round"}
+	for i := range caps {
+		draw(caps[i], joins[i], x, 50, x, 160)
+		x += offset
+	}
+	fileStr := example.Filename("Fpdf_SetLineJoinStyle_caps")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_SetLineJoinStyle_caps.pdf
+}
+
+// ExampleFpdf_DrawPath demonstrates various fill modes.
+func ExampleFpdf_DrawPath() {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.SetDrawColor(0xff, 0x00, 0x00)
+	pdf.SetFillColor(0x99, 0x99, 0x99)
+	pdf.SetFont("Helvetica", "", 15)
+	pdf.AddPage()
+	pdf.SetAlpha(1, "Multiply")
+	var (
+		polygon = func(cx, cy, r, n, dir float64) {
+			da := 2 * math.Pi / n
+			pdf.MoveTo(cx+r, cy)
+			pdf.Text(cx+r, cy, "0")
+			i := 1
+			for a := da; a < 2*math.Pi; a += da {
+				x, y := cx+r*math.Cos(dir*a), cy+r*math.Sin(dir*a)
+				pdf.LineTo(x, y)
+				pdf.Text(x, y, strconv.Itoa(i))
+				i++
+			}
+			pdf.ClosePath()
+		}
+		polygons = func(cx, cy, r, n, dir float64) {
+			d := 1.0
+			for rf := r; rf > 0; rf -= 10 {
+				polygon(cx, cy, rf, n, d)
+				d *= dir
+			}
+		}
+		star = func(cx, cy, r, n float64) {
+			da := 4 * math.Pi / n
+			pdf.MoveTo(cx+r, cy)
+			for a := da; a < 4*math.Pi+da; a += da {
+				x, y := cx+r*math.Cos(a), cy+r*math.Sin(a)
+				pdf.LineTo(x, y)
+			}
+			pdf.ClosePath()
+		}
+	)
+	// triangle
+	polygons(55, 45, 40, 3, 1)
+	pdf.DrawPath("B")
+	pdf.Text(15, 95, "B (same direction, non zero winding)")
+
+	// square
+	polygons(155, 45, 40, 4, 1)
+	pdf.DrawPath("B*")
+	pdf.Text(115, 95, "B* (same direction, even odd)")
+
+	// pentagon
+	polygons(55, 145, 40, 5, -1)
+	pdf.DrawPath("B")
+	pdf.Text(15, 195, "B (different direction, non zero winding)")
+
+	// hexagon
+	polygons(155, 145, 40, 6, -1)
+	pdf.DrawPath("B*")
+	pdf.Text(115, 195, "B* (different direction, even odd)")
+
+	// star
+	star(55, 245, 40, 5)
+	pdf.DrawPath("B")
+	pdf.Text(15, 290, "B (non zero winding)")
+
+	// star
+	star(155, 245, 40, 5)
+	pdf.DrawPath("B*")
+	pdf.Text(115, 290, "B* (even odd)")
+
+	fileStr := example.Filename("Fpdf_DrawPath_fill")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_DrawPath_fill.pdf
+}
+
+// ExampleFpdf_CreateTemplate demonstrates creating and using templates
+func ExampleFpdf_CreateTemplate() {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.SetCompression(false)
+	// pdf.SetFont("Times", "", 12)
+	template := pdf.CreateTemplate(func(tpl *gofpdf.Tpl) {
+		tpl.Image(example.ImageFile("logo.png"), 6, 6, 30, 0, false, "", 0, "")
+		tpl.SetFont("Arial", "B", 16)
+		tpl.Text(40, 20, "Template says hello")
+		tpl.SetDrawColor(0, 100, 200)
+		tpl.SetLineWidth(2.5)
+		tpl.Line(95, 12, 105, 22)
+	})
+	_, tplSize := template.Size()
+	// fmt.Println("Size:", tplSize)
+	// fmt.Println("Scaled:", tplSize.ScaleBy(1.5))
+
+	template2 := pdf.CreateTemplate(func(tpl *gofpdf.Tpl) {
+		tpl.UseTemplate(template)
+		subtemplate := tpl.CreateTemplate(func(tpl2 *gofpdf.Tpl) {
+			tpl2.Image(example.ImageFile("logo.png"), 6, 86, 30, 0, false, "", 0, "")
+			tpl2.SetFont("Arial", "B", 16)
+			tpl2.Text(40, 100, "Subtemplate says hello")
+			tpl2.SetDrawColor(0, 200, 100)
+			tpl2.SetLineWidth(2.5)
+			tpl2.Line(102, 92, 112, 102)
+		})
+		tpl.UseTemplate(subtemplate)
+	})
+
+	pdf.SetDrawColor(200, 100, 0)
+	pdf.SetLineWidth(2.5)
+	pdf.SetFont("Arial", "B", 16)
+
+	// serialize and deserialize template
+	b, _ := template2.Serialize()
+	template3, _ := gofpdf.DeserializeTemplate(b)
+
+	pdf.AddPage()
+	pdf.UseTemplate(template3)
+	pdf.UseTemplateScaled(template3, gofpdf.PointType{X: 0, Y: 30}, tplSize)
+	pdf.Line(40, 210, 60, 210)
+	pdf.Text(40, 200, "Template example page 1")
+
+	pdf.AddPage()
+	pdf.UseTemplate(template2)
+	pdf.UseTemplateScaled(template3, gofpdf.PointType{X: 0, Y: 30}, tplSize.ScaleBy(1.4))
+	pdf.Line(60, 210, 80, 210)
+	pdf.Text(40, 200, "Template example page 2")
+
+	fileStr := example.Filename("Fpdf_CreateTemplate")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_CreateTemplate.pdf
+}
+
+// ExampleFpdf_AddFontFromBytes demonstrate how to use embedded fonts from byte array
+func ExampleFpdf_AddFontFromBytes() {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.AddPage()
+	pdf.AddFontFromBytes("calligra", "", files.CalligraJson, files.CalligraZ)
+	pdf.SetFont("calligra", "", 16)
+	pdf.Cell(40, 10, "Hello World With Embedded Font!")
+	fileStr := example.Filename("Fpdf_EmbeddedFont")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_EmbeddedFont.pdf
+}
+
+// This example demonstrate Clipped table cells
+func ExampleFpdf_ClipRect() {
+	marginCell := 2. // margin of top/bottom of cell
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.SetFont("Arial", "", 12)
+	pdf.AddPage()
+	pagew, pageh := pdf.GetPageSize()
+	mleft, mright, _, mbottom := pdf.GetMargins()
+
+	cols := []float64{60, 100, pagew - mleft - mright - 100 - 60}
+	rows := [][]string{}
+	for i := 1; i <= 50; i++ {
+		word := fmt.Sprintf("%d:%s", i, strings.Repeat("A", i%100))
+		rows = append(rows, []string{word, word, word})
+	}
+
+	for _, row := range rows {
+		_, lineHt := pdf.GetFontSize()
+		height := lineHt + marginCell
+
+		x, y := pdf.GetXY()
+		// add a new page if the height of the row doesn't fit on the page
+		if y+height >= pageh-mbottom {
+			pdf.AddPage()
+			x, y = pdf.GetXY()
+		}
+		for i, txt := range row {
+			width := cols[i]
+			pdf.Rect(x, y, width, height, "")
+			pdf.ClipRect(x, y, width, height, false)
+			pdf.Cell(width, height, txt)
+			pdf.ClipEnd()
+			x += width
+		}
+		pdf.Ln(-1)
+	}
+	fileStr := example.Filename("Fpdf_ClippedTableCells")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_ClippedTableCells.pdf
+}
+
+// This example demonstrate wrapped table cells
+func ExampleFpdf_Rect() {
+	marginCell := 2. // margin of top/bottom of cell
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.SetFont("Arial", "", 12)
+	pdf.AddPage()
+	pagew, pageh := pdf.GetPageSize()
+	mleft, mright, _, mbottom := pdf.GetMargins()
+
+	cols := []float64{60, 100, pagew - mleft - mright - 100 - 60}
+	rows := [][]string{}
+	for i := 1; i <= 30; i++ {
+		word := fmt.Sprintf("%d:%s", i, strings.Repeat("A", i%100))
+		rows = append(rows, []string{word, word, word})
+	}
+
+	for _, row := range rows {
+		curx, y := pdf.GetXY()
+		x := curx
+
+		height := 0.
+		_, lineHt := pdf.GetFontSize()
+
+		for i, txt := range row {
+			lines := pdf.SplitLines([]byte(txt), cols[i])
+			h := float64(len(lines))*lineHt + marginCell*float64(len(lines))
+			if h > height {
+				height = h
+			}
+		}
+		// add a new page if the height of the row doesn't fit on the page
+		if pdf.GetY()+height > pageh-mbottom {
+			pdf.AddPage()
+			y = pdf.GetY()
+		}
+		for i, txt := range row {
+			width := cols[i]
+			pdf.Rect(x, y, width, height, "")
+			pdf.MultiCell(width, lineHt+marginCell, txt, "", "", false)
+			x += width
+			pdf.SetXY(x, y)
+		}
+		pdf.SetXY(curx, y+height)
+	}
+	fileStr := example.Filename("Fpdf_WrappedTableCells")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_WrappedTableCells.pdf
+}
+
+// ExampleFpdf_SetJavascript demonstrates including JavaScript in the document.
+func ExampleFpdf_SetJavascript() {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.SetJavascript("print(true);")
+	pdf.AddPage()
+	pdf.SetFont("Arial", "", 12)
+	pdf.Write(10, "Auto-print.")
+	fileStr := example.Filename("Fpdf_SetJavascript")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_SetJavascript.pdf
+}
+
+// ExampleFpdf_AddSpotColor demonstrates spot color use
+func ExampleFpdf_AddSpotColor() {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.AddSpotColor("PANTONE 145 CVC", 0, 42, 100, 25)
+	pdf.AddPage()
+	pdf.SetFillSpotColor("PANTONE 145 CVC", 90)
+	pdf.Rect(80, 40, 50, 50, "F")
+	fileStr := example.Filename("Fpdf_AddSpotColor")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_AddSpotColor.pdf
+}
+
+// ExampleFpdf_RegisterAlias demonstrates how to use `RegisterAlias` to create a table of
+// contents.
+func ExampleFpdf_RegisterAlias() {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.SetFont("Arial", "", 12)
+	pdf.AliasNbPages("")
+	pdf.AddPage()
+
+	// Write the table of contents. We use aliases instead of the page number
+	// because we don't know which page the section will begin on.
+	numSections := 3
+	for i := 1; i <= numSections; i++ {
+		pdf.Cell(0, 10, fmt.Sprintf("Section %d begins on page {mark %d}", i, i))
+		pdf.Ln(10)
+	}
+
+	// Write the sections. Before we start writing, we use `RegisterAlias` to
+	// ensure that the alias written in the table of contents will be replaced
+	// by the current page number.
+	for i := 1; i <= numSections; i++ {
+		pdf.AddPage()
+		pdf.RegisterAlias(fmt.Sprintf("{mark %d}", i), fmt.Sprintf("%d", pdf.PageNo()))
+		pdf.Write(10, fmt.Sprintf("Section %d, page %d of {nb}", i, pdf.PageNo()))
+	}
+
+	fileStr := example.Filename("Fpdf_RegisterAlias")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_RegisterAlias.pdf
+}
+
+// ExampleFpdf_RegisterAlias_utf8 demonstrates how to use `RegisterAlias` to
+// create a table of contents. This particular example demonstrates the use of
+// UTF-8 aliases.
+func ExampleFpdf_RegisterAlias_utf8() {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.AddUTF8Font("dejavu", "", example.FontFile("DejaVuSansCondensed.ttf"))
+	pdf.SetFont("dejavu", "", 12)
+	pdf.AliasNbPages("{entute}")
+	pdf.AddPage()
+
+	// Write the table of contents. We use aliases instead of the page number
+	// because we don't know which page the section will begin on.
+	numSections := 3
+	for i := 1; i <= numSections; i++ {
+		pdf.Cell(0, 10, fmt.Sprintf("Sekcio %d komenciĝas ĉe paĝo {ĉi tiu marko %d}", i, i))
+		pdf.Ln(10)
+	}
+
+	// Write the sections. Before we start writing, we use `RegisterAlias` to
+	// ensure that the alias written in the table of contents will be replaced
+	// by the current page number.
+	for i := 1; i <= numSections; i++ {
+		pdf.AddPage()
+		pdf.RegisterAlias(fmt.Sprintf("{ĉi tiu marko %d}", i), fmt.Sprintf("%d", pdf.PageNo()))
+		pdf.Write(10, fmt.Sprintf("Sekcio %d, paĝo %d de {entute}", i, pdf.PageNo()))
+	}
+
+	fileStr := example.Filename("Fpdf_RegisterAliasUTF8")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_RegisterAliasUTF8.pdf
+}
+
+// ExampleNewGrid demonstrates the generation of graph grids.
+func ExampleNewGrid() {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.SetFont("Arial", "", 12)
+	pdf.AddPage()
+
+	gr := gofpdf.NewGrid(13, 10, 187, 130)
+	gr.TickmarksExtentX(0, 10, 4)
+	gr.TickmarksExtentY(0, 10, 3)
+	gr.Grid(pdf)
+
+	gr = gofpdf.NewGrid(13, 154, 187, 128)
+	gr.XLabelRotate = true
+	gr.TickmarksExtentX(0, 1, 12)
+	gr.XDiv = 5
+	gr.TickmarksContainY(0, 1.1)
+	gr.YDiv = 20
+	// Replace X label formatter with month abbreviation
+	gr.XTickStr = func(val float64, precision int) string {
+		return time.Month(math.Mod(val, 12) + 1).String()[0:3]
+	}
+	gr.Grid(pdf)
+	dot := func(x, y float64) {
+		pdf.Circle(gr.X(x), gr.Y(y), 0.5, "F")
+	}
+	pts := []float64{0.39, 0.457, 0.612, 0.84, 0.998, 1.037, 1.015, 0.918, 0.772, 0.659, 0.593, 0.164}
+	for month, val := range pts {
+		dot(float64(month)+0.5, val)
+	}
+	pdf.SetDrawColor(255, 64, 64)
+	pdf.SetAlpha(0.5, "Normal")
+	pdf.SetLineWidth(1.2)
+	gr.Plot(pdf, 0.5, 11.5, 50, func(x float64) float64 {
+		// http://www.xuru.org/rt/PR.asp
+		return 0.227 * math.Exp(-0.0373*x*x+0.471*x)
+	})
+	pdf.SetAlpha(1.0, "Normal")
+	pdf.SetXY(gr.X(0.5), gr.Y(1.35))
+	pdf.SetFontSize(14)
+	pdf.Write(0, "Solar energy (MWh) per month, 2016")
+	pdf.AddPage()
+
+	gr = gofpdf.NewGrid(13, 10, 187, 274)
+	gr.TickmarksContainX(2.3, 3.4)
+	gr.TickmarksContainY(10.4, 56.8)
+	gr.Grid(pdf)
+
+	fileStr := example.Filename("Fpdf_Grid")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_Grid.pdf
+}
+
+// ExampleFpdf_SetPageBox demonstrates the use of a page box
+func ExampleFpdf_SetPageBox() {
+	// pdfinfo (from http://www.xpdfreader.com) reports the following for this example:
+	// ~ pdfinfo -box pdf/Fpdf_PageBox.pdf
+	// Producer:       FPDF 1.7
+	// CreationDate:   Sat Jan  1 00:00:00 2000
+	// ModDate:   	   Sat Jan  1 00:00:00 2000
+	// Tagged:         no
+	// Form:           none
+	// Pages:          1
+	// Encrypted:      no
+	// Page size:      493.23 x 739.85 pts (rotated 0 degrees)
+	// MediaBox:           0.00     0.00   595.28   841.89
+	// CropBox:           51.02    51.02   544.25   790.87
+	// BleedBox:          51.02    51.02   544.25   790.87
+	// TrimBox:           51.02    51.02   544.25   790.87
+	// ArtBox:            51.02    51.02   544.25   790.87
+	// File size:      1053 bytes
+	// Optimized:      no
+	// PDF version:    1.3
+	const (
+		wd        = 210
+		ht        = 297
+		fontsize  = 6
+		boxmargin = 3 * fontsize
+	)
+	pdf := gofpdf.New("P", "mm", "A4", "") // 210mm x 297mm
+	pdf.SetPageBox("crop", boxmargin, boxmargin, wd-2*boxmargin, ht-2*boxmargin)
+	pdf.SetFont("Arial", "", pdf.UnitToPointConvert(fontsize))
+	pdf.AddPage()
+	pdf.MoveTo(fontsize, fontsize)
+	pdf.Write(fontsize, "This will be cropped from printed output")
+	pdf.MoveTo(boxmargin+fontsize, boxmargin+fontsize)
+	pdf.Write(fontsize, "This will be displayed in cropped output")
+	fileStr := example.Filename("Fpdf_PageBox")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_PageBox.pdf
+}
+
+// ExampleFpdf_SubWrite demonstrates subscripted and superscripted text
+// Adapted from http://www.fpdf.org/en/script/script61.php
+func ExampleFpdf_SubWrite() {
+
+	const (
+		fontSize = 12
+		halfX    = 105
+	)
+
+	pdf := gofpdf.New("P", "mm", "A4", "") // 210mm x 297mm
+	pdf.AddPage()
+	pdf.SetFont("Arial", "", fontSize)
+	_, lineHt := pdf.GetFontSize()
+
+	pdf.Write(lineHt, "Hello World!")
+	pdf.SetX(halfX)
+	pdf.Write(lineHt, "This is standard text.\n")
+	pdf.Ln(lineHt * 2)
+
+	pdf.SubWrite(10, "H", 33, 0, 0, "")
+	pdf.Write(10, "ello World!")
+	pdf.SetX(halfX)
+	pdf.Write(10, "This is text with a capital first letter.\n")
+	pdf.Ln(lineHt * 2)
+
+	pdf.SubWrite(lineHt, "Y", 6, 0, 0, "")
+	pdf.Write(lineHt, "ou can also begin the sentence with a small letter. And word wrap also works if the line is too long, like this one is.")
+	pdf.SetX(halfX)
+	pdf.Write(lineHt, "This is text with a small first letter.\n")
+	pdf.Ln(lineHt * 2)
+
+	pdf.Write(lineHt, "The world has a lot of km")
+	pdf.SubWrite(lineHt, "2", 6, 4, 0, "")
+	pdf.SetX(halfX)
+	pdf.Write(lineHt, "This is text with a superscripted letter.\n")
+	pdf.Ln(lineHt * 2)
+
+	pdf.Write(lineHt, "The world has a lot of H")
+	pdf.SubWrite(lineHt, "2", 6, -3, 0, "")
+	pdf.Write(lineHt, "O")
+	pdf.SetX(halfX)
+	pdf.Write(lineHt, "This is text with a subscripted letter.\n")
+
+	fileStr := example.Filename("Fpdf_SubWrite")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_SubWrite.pdf
+}
+
+// ExampleFpdf_SetPage demomstrates the SetPage() method, allowing content
+// generation to be deferred until all pages have been added.
+func ExampleFpdf_SetPage() {
+	rnd := rand.New(rand.NewSource(0)) // Make reproducible documents
+	pdf := gofpdf.New("L", "cm", "A4", "")
+	pdf.SetFont("Times", "", 12)
+
+	var time []float64
+	temperaturesFromSensors := make([][]float64, 5)
+	maxs := []float64{25, 41, 89, 62, 11}
+	for i := range temperaturesFromSensors {
+		temperaturesFromSensors[i] = make([]float64, 0)
+	}
+
+	for i := 0.0; i < 100; i += 0.5 {
+		time = append(time, i)
+		for j, sensor := range temperaturesFromSensors {
+			dataValue := rnd.Float64() * maxs[j]
+			sensor = append(sensor, dataValue)
+			temperaturesFromSensors[j] = sensor
+		}
+	}
+	var graphs []gofpdf.GridType
+	var pageNums []int
+	xMax := time[len(time)-1]
+	for i := range temperaturesFromSensors {
+		//Create a new page and graph for each sensor we want to graph.
+		pdf.AddPage()
+		pdf.Ln(1)
+		//Custom label per sensor
+		pdf.WriteAligned(0, 0, "Temperature Sensor "+strconv.Itoa(i+1)+" (C) vs Time (min)", "C")
+		pdf.Ln(0.5)
+		graph := gofpdf.NewGrid(pdf.GetX(), pdf.GetY(), 20, 10)
+		graph.TickmarksContainX(0, xMax)
+		//Custom Y axis
+		graph.TickmarksContainY(0, maxs[i])
+		graph.Grid(pdf)
+		//Save references and locations.
+		graphs = append(graphs, graph)
+		pageNums = append(pageNums, pdf.PageNo())
+	}
+	// For each X, graph the Y in each sensor.
+	for i, currTime := range time {
+		for j, sensor := range temperaturesFromSensors {
+			pdf.SetPage(pageNums[j])
+			graph := graphs[j]
+			temperature := sensor[i]
+			pdf.Circle(graph.X(currTime), graph.Y(temperature), 0.04, "D")
+		}
+	}
+
+	fileStr := example.Filename("Fpdf_SetPage")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_SetPage.pdf
+}
+
+// ExampleFpdf_SetFillColor demonstrates how graphic attributes are properly
+// assigned within multiple transformations. See issue #234.
+func ExampleFpdf_SetFillColor() {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+
+	pdf.AddPage()
+	pdf.SetFont("Arial", "", 8)
+
+	draw := func(trX, trY float64) {
+		pdf.TransformBegin()
+		pdf.TransformTranslateX(trX)
+		pdf.TransformTranslateY(trY)
+		pdf.SetLineJoinStyle("round")
+		pdf.SetLineWidth(0.5)
+		pdf.SetDrawColor(128, 64, 0)
+		pdf.SetFillColor(255, 127, 0)
+		pdf.SetAlpha(0.5, "Normal")
+		pdf.SetDashPattern([]float64{5, 10}, 0)
+		pdf.Rect(0, 0, 40, 40, "FD")
+		pdf.SetFontSize(12)
+		pdf.SetXY(5, 5)
+		pdf.Write(0, "Test")
+		pdf.TransformEnd()
+	}
+
+	draw(5, 5)
+	draw(50, 50)
+
+	fileStr := example.Filename("Fpdf_SetFillColor")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_SetFillColor.pdf
+}
+
+// ExampleFpdf_TransformRotate demonstrates how to rotate text within a header
+// to make a watermark that appears on each page.
+func ExampleFpdf_TransformRotate() {
+
+	loremStr := lorem() + "\n\n"
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	margin := 25.0
+	pdf.SetMargins(margin, margin, margin)
+
+	fontHt := 13.0
+	lineHt := pdf.PointToUnitConvert(fontHt)
+	markFontHt := 50.0
+	markLineHt := pdf.PointToUnitConvert(markFontHt)
+	markY := (297.0 - markLineHt) / 2.0
+	ctrX := 210.0 / 2.0
+	ctrY := 297.0 / 2.0
+
+	pdf.SetHeaderFunc(func() {
+		pdf.SetFont("Arial", "B", markFontHt)
+		pdf.SetTextColor(206, 216, 232)
+		pdf.SetXY(margin, markY)
+		pdf.TransformBegin()
+		pdf.TransformRotate(45, ctrX, ctrY)
+		pdf.CellFormat(0, markLineHt, "W A T E R M A R K   D E M O", "", 0, "C", false, 0, "")
+		pdf.TransformEnd()
+		pdf.SetXY(margin, margin)
+	})
+
+	pdf.AddPage()
+	pdf.SetFont("Arial", "", 8)
+	for j := 0; j < 25; j++ {
+		pdf.MultiCell(0, lineHt, loremStr, "", "L", false)
+	}
+
+	fileStr := example.Filename("Fpdf_RotateText")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_RotateText.pdf
+}
+
+// ExampleFpdf_AddUTF8Font demonstrates how use the font
+// with utf-8 mode
+func ExampleFpdf_AddUTF8Font() {
+	var fileStr string
+	var txtStr []byte
+	var err error
+
+	pdf := gofpdf.New("P", "mm", "A4", "")
+
+	pdf.AddPage()
+
+	pdf.AddUTF8Font("dejavu", "", example.FontFile("DejaVuSansCondensed.ttf"))
+	pdf.AddUTF8Font("dejavu", "B", example.FontFile("DejaVuSansCondensed-Bold.ttf"))
+	pdf.AddUTF8Font("dejavu", "I", example.FontFile("DejaVuSansCondensed-Oblique.ttf"))
+	pdf.AddUTF8Font("dejavu", "BI", example.FontFile("DejaVuSansCondensed-BoldOblique.ttf"))
+
+	fileStr = example.Filename("Fpdf_AddUTF8Font")
+	txtStr, err = ioutil.ReadFile(example.TextFile("utf-8test.txt"))
+	if err == nil {
+
+		pdf.SetFont("dejavu", "B", 17)
+		pdf.MultiCell(100, 8, "Text in different languages :", "", "C", false)
+		pdf.SetFont("dejavu", "", 14)
+		pdf.MultiCell(100, 5, string(txtStr), "", "C", false)
+		pdf.Ln(15)
+
+		txtStr, err = ioutil.ReadFile(example.TextFile("utf-8test2.txt"))
+		if err == nil {
+
+			pdf.SetFont("dejavu", "BI", 17)
+			pdf.MultiCell(100, 8, "Greek text with alignStr = \"J\":", "", "C", false)
+			pdf.SetFont("dejavu", "I", 14)
+			pdf.MultiCell(100, 5, string(txtStr), "", "J", false)
+			err = pdf.OutputFileAndClose(fileStr)
+
+		}
+	}
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_AddUTF8Font.pdf
+}
+
+// ExampleUTF8CutFont demonstrates how generate a TrueType font subset.
+func ExampleUTF8CutFont() {
+	var pdfFileStr, fullFontFileStr, subFontFileStr string
+	var subFont, fullFont []byte
+	var err error
+
+	pdfFileStr = example.Filename("Fpdf_UTF8CutFont")
+	fullFontFileStr = example.FontFile("calligra.ttf")
+	fullFont, err = ioutil.ReadFile(fullFontFileStr)
+	if err == nil {
+		subFontFileStr = "calligra_abcde.ttf"
+		subFont = gofpdf.UTF8CutFont(fullFont, "abcde")
+		err = ioutil.WriteFile(subFontFileStr, subFont, 0600)
+		if err == nil {
+			y := 24.0
+			pdf := gofpdf.New("P", "mm", "A4", "")
+			fontHt := 17.0
+			lineHt := pdf.PointConvert(fontHt)
+			write := func(format string, args ...interface{}) {
+				pdf.SetXY(24.0, y)
+				pdf.Cell(200.0, lineHt, fmt.Sprintf(format, args...))
+				y += lineHt
+			}
+			writeSize := func(fileStr string) {
+				var info os.FileInfo
+				var err error
+				info, err = os.Stat(fileStr)
+				if err == nil {
+					write("%6d: size of %s", info.Size(), fileStr)
+				}
+			}
+			pdf.AddPage()
+			pdf.AddUTF8Font("calligra", "", subFontFileStr)
+			pdf.SetFont("calligra", "", fontHt)
+			write("cabbed")
+			write("vwxyz")
+			pdf.SetFont("courier", "", fontHt)
+			writeSize(fullFontFileStr)
+			writeSize(subFontFileStr)
+			err = pdf.OutputFileAndClose(pdfFileStr)
+			os.Remove(subFontFileStr)
+		}
+	}
+	example.Summary(err, pdfFileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_UTF8CutFont.pdf
+}
+
+func ExampleFpdf_RoundedRect() {
+	const (
+		wd     = 40.0
+		hgap   = 10.0
+		radius = 10.0
+		ht     = 60.0
+		vgap   = 10.0
+	)
+	corner := func(b1, b2, b3, b4 bool) (cstr string) {
+		if b1 {
+			cstr = "1"
+		}
+		if b2 {
+			cstr += "2"
+		}
+		if b3 {
+			cstr += "3"
+		}
+		if b4 {
+			cstr += "4"
+		}
+		return
+	}
+	pdf := gofpdf.New("P", "mm", "A4", "") // 210 x 297
+	pdf.AddPage()
+	pdf.SetLineWidth(0.5)
+	y := vgap
+	r := 40
+	g := 30
+	b := 20
+	for row := 0; row < 4; row++ {
+		x := hgap
+		for col := 0; col < 4; col++ {
+			pdf.SetFillColor(r, g, b)
+			pdf.RoundedRect(x, y, wd, ht, radius, corner(row&1 == 1, row&2 == 2, col&1 == 1, col&2 == 2), "FD")
+			r += 8
+			g += 10
+			b += 12
+			x += wd + hgap
+		}
+		y += ht + vgap
+	}
+	pdf.AddPage()
+	pdf.RoundedRectExt(10, 20, 40, 80, 4., 0., 20, 0., "FD")
+
+	fileStr := example.Filename("Fpdf_RoundedRect")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_RoundedRect.pdf
+}
+
+// ExampleFpdf_SetUnderlineThickness demonstrates how to adjust the text
+// underline thickness.
+func ExampleFpdf_SetUnderlineThickness() {
+	pdf := gofpdf.New("P", "mm", "A4", "") // 210mm x 297mm
+	pdf.AddPage()
+	pdf.SetFont("Arial", "U", 12)
+
+	pdf.SetUnderlineThickness(0.5)
+	pdf.CellFormat(0, 10, "Thin underline", "", 1, "", false, 0, "")
+
+	pdf.SetUnderlineThickness(1)
+	pdf.CellFormat(0, 10, "Normal underline", "", 1, "", false, 0, "")
+
+	pdf.SetUnderlineThickness(2)
+	pdf.CellFormat(0, 10, "Thicker underline", "", 1, "", false, 0, "")
+
+	fileStr := example.Filename("Fpdf_UnderlineThickness")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_UnderlineThickness.pdf
+}
+
+// ExampleFpdf_Cell_strikeout demonstrates striked-out text
+func ExampleFpdf_Cell_strikeout() {
+
+	pdf := gofpdf.New("P", "mm", "A4", "") // 210mm x 297mm
+	pdf.AddPage()
+
+	for fontSize := 4; fontSize < 40; fontSize += 10 {
+		pdf.SetFont("Arial", "S", float64(fontSize))
+		pdf.SetXY(0, float64(fontSize))
+		pdf.Cell(40, 10, "Hello World")
+	}
+
+	fileStr := example.Filename("Fpdf_Cell_strikeout")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_Cell_strikeout.pdf
+}
+
+// ExampleFpdf_SetTextRenderingMode demonstrates rendering modes in PDFs.
+func ExampleFpdf_SetTextRenderingMode() {
+
+	pdf := gofpdf.New("P", "mm", "A4", "") // 210mm x 297mm
+	pdf.AddPage()
+	fontSz := float64(16)
+	lineSz := pdf.PointToUnitConvert(fontSz)
+	pdf.SetFont("Times", "", fontSz)
+	pdf.Write(lineSz, "This document demonstrates various modes of text rendering. Search for \"Mode 3\" "+
+		"to locate text that has been rendered invisibly. This selection can be copied "+
+		"into the clipboard as usual and is useful for overlaying onto non-textual elements such "+
+		"as images to make them searchable.\n\n")
+	fontSz = float64(125)
+	lineSz = pdf.PointToUnitConvert(fontSz)
+	pdf.SetFontSize(fontSz)
+	pdf.SetTextColor(170, 170, 190)
+	pdf.SetDrawColor(50, 60, 90)
+
+	write := func(mode int) {
+		pdf.SetTextRenderingMode(mode)
+		pdf.CellFormat(210, lineSz, fmt.Sprintf("Mode %d", mode), "", 1, "", false, 0, "")
+	}
+
+	for mode := 0; mode < 4; mode++ {
+		write(mode)
+	}
+	write(0)
+
+	fileStr := example.Filename("Fpdf_TextRenderingMode")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_TextRenderingMode.pdf
+}
+
+// TestIssue0316 addresses issue 316 in which AddUTF8FromBytes modifies its argument
+// utf8bytes resulting in a panic if you generate two PDFs with the "same" font bytes.
+func TestIssue0316(t *testing.T) {
+	pdf := gofpdf.New(gofpdf.OrientationPortrait, "mm", "A4", "")
+	pdf.AddPage()
+	fontBytes, _ := ioutil.ReadFile(example.FontFile("DejaVuSansCondensed.ttf"))
+	ofontBytes := append([]byte{}, fontBytes...)
+	pdf.AddUTF8FontFromBytes("dejavu", "", fontBytes)
+	pdf.SetFont("dejavu", "", 16)
+	pdf.Cell(40, 10, "Hello World!")
+	fileStr := example.Filename("TestIssue0316")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	pdf.AddPage()
+	if !bytes.Equal(fontBytes, ofontBytes) {
+		t.Fatal("Font data changed during pdf generation")
+	}
+}
+
+func TestMultiCellUnsupportedChar(t *testing.T) {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.AddPage()
+	fontBytes, _ := ioutil.ReadFile(example.FontFile("DejaVuSansCondensed.ttf"))
+	pdf.AddUTF8FontFromBytes("dejavu", "", fontBytes)
+	pdf.SetFont("dejavu", "", 16)
+
+	defer func() {
+		if r := recover(); r != nil {
+			t.Errorf("unexpected panic: %v", r)
+		}
+	}()
+
+	pdf.MultiCell(0, 5, "😀", "", "", false)
+
+	fileStr := example.Filename("TestMultiCellUnsupportedChar")
+	pdf.OutputFileAndClose(fileStr)
+}
+
+// ExampleFpdf_SetTextRenderingMode demonstrates embedding files in PDFs,
+// at the top-level.
+func ExampleFpdf_SetAttachments() {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+
+	// Global attachments
+	file, err := ioutil.ReadFile("grid.go")
+	if err != nil {
+		pdf.SetError(err)
+	}
+	a1 := gofpdf.Attachment{Content: file, Filename: "grid.go"}
+	file, err = ioutil.ReadFile("LICENSE")
+	if err != nil {
+		pdf.SetError(err)
+	}
+	a2 := gofpdf.Attachment{Content: file, Filename: "License"}
+	pdf.SetAttachments([]gofpdf.Attachment{a1, a2})
+
+	fileStr := example.Filename("Fpdf_EmbeddedFiles")
+	err = pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_EmbeddedFiles.pdf
+}
+
+func ExampleFpdf_AddAttachmentAnnotation() {
+	pdf := gofpdf.New("P", "mm", "A4", "")
+	pdf.SetFont("Arial", "", 12)
+	pdf.AddPage()
+
+	// Per page attachment
+	file, err := ioutil.ReadFile("grid.go")
+	if err != nil {
+		pdf.SetError(err)
+	}
+	a := gofpdf.Attachment{Content: file, Filename: "grid.go", Description: "Some amazing code !"}
+
+	pdf.SetXY(5, 10)
+	pdf.Rect(2, 10, 50, 15, "D")
+	pdf.AddAttachmentAnnotation(&a, 2, 10, 50, 15)
+	pdf.Cell(50, 15, "A first link")
+
+	pdf.SetXY(5, 80)
+	pdf.Rect(2, 80, 50, 15, "D")
+	pdf.AddAttachmentAnnotation(&a, 2, 80, 50, 15)
+	pdf.Cell(50, 15, "A second link (no copy)")
+
+	fileStr := example.Filename("Fpdf_FileAnnotations")
+	err = pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_FileAnnotations.pdf
+}
+
+func ExampleFpdf_SetModificationDate() {
+	// pdfinfo (from http://www.xpdfreader.com) reports the following for this example :
+	// ~ pdfinfo -box pdf/Fpdf_PageBox.pdf
+	// Producer:       FPDF 1.7
+	// CreationDate:   Sat Jan  1 00:00:00 2000
+	// ModDate:        Sun Jan  2 10:22:30 2000
+	pdf := gofpdf.New("", "", "", "")
+	pdf.AddPage()
+	pdf.SetModificationDate(time.Date(2000, 1, 2, 10, 22, 30, 0, time.UTC))
+	fileStr := example.Filename("Fpdf_SetModificationDate")
+	err := pdf.OutputFileAndClose(fileStr)
+	example.Summary(err, fileStr)
+	// Output:
+	// Successfully generated pdf/Fpdf_SetModificationDate.pdf
+}

+ 213 - 0
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")
+	}
+}

+ 12 - 0
go.mod

@@ -0,0 +1,12 @@
+module git.listensoft.net/loubowen/lxPdf
+
+go 1.12
+
+require (
+	github.com/boombuler/barcode v1.0.0
+	github.com/phpdave11/gofpdi v1.0.7
+	github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58
+	golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a
+)
+
+replace gofpdf => ./

+ 20 - 0
go.sum

@@ -0,0 +1,20 @@
+github.com/boombuler/barcode v1.0.0 h1:s1TvRnXwL2xJRaccrdcBQMZxq6X7DvsMogtmJeHDdrc=
+github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
+github.com/phpdave11/gofpdi v1.0.7 h1:k2oy4yhkQopCK+qW8KjCla0iU2RpDow+QUDmH9DDt44=
+github.com/phpdave11/gofpdi v1.0.7/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
+github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58 h1:nlG4Wa5+minh3S9LVFtNoY+GVRiudA2e3EVfcCi3RCA=
+github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=
+github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+golang.org/x/image v0.0.0-20190902063713-cb417be4ba39 h1:4dQcAORh9oYBwVSBVIkP489LUPC+f1HBkTYXgmqfR+o=
+golang.org/x/image v0.0.0-20190902063713-cb417be4ba39/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a h1:gHevYm0pO4QUbwy8Dmdr01R5r1BuKtfYqRqF0h/Cbh0=
+golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

+ 446 - 0
grid.go

@@ -0,0 +1,446 @@
+package gofpdf
+
+import (
+	"math"
+	"strconv"
+)
+
+func unused(args ...interface{}) {
+}
+
+// RGBType holds fields for red, green and blue color components (0..255)
+type RGBType struct {
+	R, G, B int
+}
+
+// RGBAType holds fields for red, green and blue color components (0..255) and
+// an alpha transparency value (0..1)
+type RGBAType struct {
+	R, G, B int
+	Alpha   float64
+}
+
+// StateType holds various commonly used drawing values for convenient
+// retrieval (StateGet()) and restore (Put) methods.
+type StateType struct {
+	clrDraw, clrText, clrFill RGBType
+	lineWd                    float64
+	fontSize                  float64
+	alpha                     float64
+	blendStr                  string
+	cellMargin                float64
+}
+
+// StateGet returns a variable that contains common state values.
+func StateGet(pdf *Fpdf) (st StateType) {
+	st.clrDraw.R, st.clrDraw.G, st.clrDraw.B = pdf.GetDrawColor()
+	st.clrFill.R, st.clrFill.G, st.clrFill.B = pdf.GetFillColor()
+	st.clrText.R, st.clrText.G, st.clrText.B = pdf.GetTextColor()
+	st.lineWd = pdf.GetLineWidth()
+	_, st.fontSize = pdf.GetFontSize()
+	st.alpha, st.blendStr = pdf.GetAlpha()
+	st.cellMargin = pdf.GetCellMargin()
+	return
+}
+
+// Put sets the common state values contained in the state structure
+// specified by st.
+func (st StateType) Put(pdf *Fpdf) {
+	pdf.SetDrawColor(st.clrDraw.R, st.clrDraw.G, st.clrDraw.B)
+	pdf.SetFillColor(st.clrFill.R, st.clrFill.G, st.clrFill.B)
+	pdf.SetTextColor(st.clrText.R, st.clrText.G, st.clrText.B)
+	pdf.SetLineWidth(st.lineWd)
+	pdf.SetFontUnitSize(st.fontSize)
+	pdf.SetAlpha(st.alpha, st.blendStr)
+	pdf.SetCellMargin(st.cellMargin)
+}
+
+// TickFormatFncType defines a callback for label drawing.
+type TickFormatFncType func(val float64, precision int) string
+
+// defaultFormatter returns the string form of val with precision decimal places.
+func defaultFormatter(val float64, precision int) string {
+	return strconv.FormatFloat(val, 'f', precision, 64)
+}
+
+// GridType assists with the generation of graphs. It allows the application to
+// work with logical data coordinates rather than page coordinates and assists
+// with the drawing of a background grid.
+type GridType struct {
+	// Chart coordinates in page units
+	x, y, w, h float64
+	// X, Y, Wd, Ht float64
+	// Slopes and intercepts scale data points to graph coordinates linearly
+	xm, xb, ym, yb float64
+	// Tickmarks
+	xTicks, yTicks []float64
+	// Labels are inside of graph boundary
+	XLabelIn, YLabelIn bool
+	// Labels on X-axis should be rotated
+	XLabelRotate bool
+	// Formatters; use nil to eliminate labels
+	XTickStr, YTickStr TickFormatFncType
+	// Subdivisions between tickmarks
+	XDiv, YDiv int
+	// Formatting precision
+	xPrecision, yPrecision int
+	// Line and label colors
+	ClrText, ClrMain, ClrSub RGBAType
+	// Line thickness
+	WdMain, WdSub float64
+	// Label height in points
+	TextSize float64
+}
+
+// linear returns the slope and y-intercept of the straight line joining the
+// two specified points. For scaling purposes, associate the arguments as
+// follows: x1: observed low value, y1: desired low value, x2: observed high
+// value, y2: desired high value.
+func linear(x1, y1, x2, y2 float64) (slope, intercept float64) {
+	if x2 != x1 {
+		slope = (y2 - y1) / (x2 - x1)
+		intercept = y2 - x2*slope
+	}
+	return
+}
+
+// linearTickmark returns the slope and intercept that will linearly map data
+// values (the range of which is specified by the tickmark slice tm) to page
+// values (the range of which is specified by lo and hi).
+func linearTickmark(tm []float64, lo, hi float64) (slope, intercept float64) {
+	ln := len(tm)
+	if ln > 0 {
+		slope, intercept = linear(tm[0], lo, tm[ln-1], hi)
+	}
+	return
+}
+
+// NewGrid returns a variable of type GridType that is initialized to draw on a
+// rectangle of width w and height h with the upper left corner positioned at
+// point (x, y). The coordinates are in page units, that is, the same as those
+// specified in New().
+//
+// The returned variable is initialized with a very simple default tickmark
+// layout that ranges from 0 to 1 in both axes. Prior to calling Grid(), the
+// application may establish a more suitable tickmark layout by calling the
+// methods TickmarksContainX() and TickmarksContainY(). These methods bound the
+// data range with appropriate boundaries and divisions. Alternatively, if the
+// exact extent and divisions of the tickmark layout are known, the methods
+// TickmarksExtentX() and TickmarksExtentY may be called instead.
+func NewGrid(x, y, w, h float64) (grid GridType) {
+	grid.x = x
+	grid.y = y
+	grid.w = w
+	grid.h = h
+	grid.TextSize = 7 // Points
+	grid.TickmarksExtentX(0, 1, 1)
+	grid.TickmarksExtentY(0, 1, 1)
+	grid.XLabelIn = false
+	grid.YLabelIn = false
+	grid.XLabelRotate = false
+	grid.XDiv = 10
+	grid.YDiv = 10
+	grid.ClrText = RGBAType{R: 0, G: 0, B: 0, Alpha: 1}
+	grid.ClrMain = RGBAType{R: 128, G: 160, B: 128, Alpha: 1}
+	grid.ClrSub = RGBAType{R: 192, G: 224, B: 192, Alpha: 1}
+	grid.WdMain = 0.1
+	grid.WdSub = 0.1
+	grid.YTickStr = defaultFormatter
+	grid.XTickStr = defaultFormatter
+	return
+}
+
+// WdAbs returns the absolute value of dataWd, specified in logical data units,
+// that has been converted to the unit of measure specified in New().
+func (g GridType) WdAbs(dataWd float64) float64 {
+	return math.Abs(g.xm * dataWd)
+}
+
+// Wd converts dataWd, specified in logical data units, to the unit of measure
+// specified in New().
+func (g GridType) Wd(dataWd float64) float64 {
+	return g.xm * dataWd
+}
+
+// XY converts dataX and dataY, specified in logical data units, to the X and Y
+// position on the current page.
+func (g GridType) XY(dataX, dataY float64) (x, y float64) {
+	return g.xm*dataX + g.xb, g.ym*dataY + g.yb
+}
+
+// Pos returns the point, in page units, indicated by the relative positions
+// xRel and yRel. These are values between 0 and 1. xRel specifies the relative
+// position between the grid's left and right edges. yRel specifies the
+// relative position between the grid's bottom and top edges.
+func (g GridType) Pos(xRel, yRel float64) (x, y float64) {
+	x = g.w*xRel + g.x
+	y = g.h*(1-yRel) + g.y
+	return
+}
+
+// X converts dataX, specified in logical data units, to the X position on the
+// current page.
+func (g GridType) X(dataX float64) float64 {
+	return g.xm*dataX + g.xb
+}
+
+// HtAbs returns the absolute value of dataHt, specified in logical data units,
+// that has been converted to the unit of measure specified in New().
+func (g GridType) HtAbs(dataHt float64) float64 {
+	return math.Abs(g.ym * dataHt)
+}
+
+// Ht converts dataHt, specified in logical data units, to the unit of measure
+// specified in New().
+func (g GridType) Ht(dataHt float64) float64 {
+	return g.ym * dataHt
+}
+
+// Y converts dataY, specified in logical data units, to the Y position on the
+// current page.
+func (g GridType) Y(dataY float64) float64 {
+	return g.ym*dataY + g.yb
+}
+
+// XRange returns the minimum and maximum values for the current tickmark
+// sequence. These correspond to the data values of the graph's left and right
+// edges.
+func (g GridType) XRange() (min, max float64) {
+	min = g.xTicks[0]
+	max = g.xTicks[len(g.xTicks)-1]
+	return
+}
+
+// YRange returns the minimum and maximum values for the current tickmark
+// sequence. These correspond to the data values of the graph's bottom and top
+// edges.
+func (g GridType) YRange() (min, max float64) {
+	min = g.yTicks[0]
+	max = g.yTicks[len(g.yTicks)-1]
+	return
+}
+
+// TickmarksContainX sets the tickmarks to be shown by Grid() in the horizontal
+// dimension. The argument min and max specify the minimum and maximum values
+// to be contained within the grid. The tickmark values that are generated are
+// suitable for general purpose graphs.
+//
+// See TickmarkExtentX() for an alternative to this method to be used when the
+// exact values of the tickmarks are to be set by the application.
+func (g *GridType) TickmarksContainX(min, max float64) {
+	g.xTicks, g.xPrecision = Tickmarks(min, max)
+	g.xm, g.xb = linearTickmark(g.xTicks, g.x, g.x+g.w)
+}
+
+// TickmarksContainY sets the tickmarks to be shown by Grid() in the vertical
+// dimension. The argument min and max specify the minimum and maximum values
+// to be contained within the grid. The tickmark values that are generated are
+// suitable for general purpose graphs.
+//
+// See TickmarkExtentY() for an alternative to this method to be used when the
+// exact values of the tickmarks are to be set by the application.
+func (g *GridType) TickmarksContainY(min, max float64) {
+	g.yTicks, g.yPrecision = Tickmarks(min, max)
+	g.ym, g.yb = linearTickmark(g.yTicks, g.y+g.h, g.y)
+}
+
+func extent(min, div float64, count int) (tm []float64, precision int) {
+	tm = make([]float64, count+1)
+	for j := 0; j <= count; j++ {
+		tm[j] = min
+		min += div
+	}
+	precision = TickmarkPrecision(div)
+	return
+}
+
+// TickmarksExtentX sets the tickmarks to be shown by Grid() in the horizontal
+// dimension. count specifies number of major tickmark subdivisions to be
+// graphed. min specifies the leftmost data value. div specifies, in data
+// units, the extent of each major tickmark subdivision.
+//
+// See TickmarkContainX() for an alternative to this method to be used when
+// viewer-friendly tickmarks are to be determined automatically.
+func (g *GridType) TickmarksExtentX(min, div float64, count int) {
+	g.xTicks, g.xPrecision = extent(min, div, count)
+	g.xm, g.xb = linearTickmark(g.xTicks, g.x, g.x+g.w)
+}
+
+// TickmarksExtentY sets the tickmarks to be shown by Grid() in the vertical
+// dimension. count specifies number of major tickmark subdivisions to be
+// graphed. min specifies the bottommost data value. div specifies, in data
+// units, the extent of each major tickmark subdivision.
+//
+// See TickmarkContainY() for an alternative to this method to be used when
+// viewer-friendly tickmarks are to be determined automatically.
+func (g *GridType) TickmarksExtentY(min, div float64, count int) {
+	g.yTicks, g.yPrecision = extent(min, div, count)
+	g.ym, g.yb = linearTickmark(g.yTicks, g.y+g.h, g.y)
+}
+
+// func (g *GridType) SetXExtent(dataLf, paperLf, dataRt, paperRt float64) {
+// 	g.xm, g.xb = linear(dataLf, paperLf, dataRt, paperRt)
+// }
+
+// func (g *GridType) SetYExtent(dataTp, paperTp, dataBt, paperBt float64) {
+// 	g.ym, g.yb = linear(dataTp, paperTp, dataBt, paperBt)
+// }
+
+func lineAttr(pdf *Fpdf, clr RGBAType, lineWd float64) {
+	pdf.SetLineWidth(lineWd)
+	pdf.SetAlpha(clr.Alpha, "Normal")
+	pdf.SetDrawColor(clr.R, clr.G, clr.B)
+}
+
+// Grid generates a graph-paperlike set of grid lines on the current page.
+func (g GridType) Grid(pdf *Fpdf) {
+	var st StateType
+	var yLen, xLen int
+	var textSz, halfTextSz, yMin, yMax, xMin, xMax, yDiv, xDiv float64
+	var str string
+	var strOfs, strWd, tp, bt, lf, rt, drawX, drawY float64
+
+	xLen = len(g.xTicks)
+	yLen = len(g.yTicks)
+	if xLen > 1 && yLen > 1 {
+
+		st = StateGet(pdf)
+
+		line := func(x1, y1, x2, y2 float64, heavy bool) {
+			if heavy {
+				lineAttr(pdf, g.ClrMain, g.WdMain)
+			} else {
+				lineAttr(pdf, g.ClrSub, g.WdSub)
+			}
+			pdf.Line(x1, y1, x2, y2)
+		}
+
+		textSz = pdf.PointToUnitConvert(g.TextSize)
+		halfTextSz = textSz / 2
+
+		pdf.SetAutoPageBreak(false, 0)
+		pdf.SetFontUnitSize(textSz)
+		strOfs = pdf.GetStringWidth("0")
+		pdf.SetFillColor(255, 255, 255)
+		pdf.SetCellMargin(0)
+
+		xMin = g.xTicks[0]
+		xMax = g.xTicks[xLen-1]
+
+		yMin = g.yTicks[0]
+		yMax = g.yTicks[yLen-1]
+
+		lf = g.X(xMin)
+		rt = g.X(xMax)
+		bt = g.Y(yMin)
+		tp = g.Y(yMax)
+
+		// Verticals along X axis
+		xDiv = g.xTicks[1] - g.xTicks[0]
+		if g.XDiv > 0 {
+			xDiv = xDiv / float64(g.XDiv)
+		}
+		xDiv = g.Wd(xDiv)
+		for j, x := range g.xTicks {
+			drawX = g.X(x)
+			line(drawX, tp, drawX, bt, true)
+			if j < xLen-1 {
+				for k := 1; k < g.XDiv; k++ {
+					drawX += xDiv
+					line(drawX, tp, drawX, bt, false)
+				}
+			}
+		}
+
+		// Horizontals along Y axis
+		yDiv = g.yTicks[1] - g.yTicks[0]
+		if g.YDiv > 0 {
+			yDiv = yDiv / float64(g.YDiv)
+		}
+		yDiv = g.Ht(yDiv)
+		for j, y := range g.yTicks {
+			drawY = g.Y(y)
+			line(lf, drawY, rt, drawY, true)
+			if j < yLen-1 {
+				for k := 1; k < g.YDiv; k++ {
+					drawY += yDiv
+					line(lf, drawY, rt, drawY, false)
+				}
+			}
+		}
+
+		// X labels
+		if g.XTickStr != nil {
+			drawY = bt
+			for _, x := range g.xTicks {
+				str = g.XTickStr(x, g.xPrecision)
+				strWd = pdf.GetStringWidth(str)
+				drawX = g.X(x)
+				if g.XLabelRotate {
+					pdf.TransformBegin()
+					pdf.TransformRotate(90, drawX, drawY)
+					if g.XLabelIn {
+						pdf.SetXY(drawX+strOfs, drawY-halfTextSz)
+					} else {
+						pdf.SetXY(drawX-strOfs-strWd, drawY-halfTextSz)
+					}
+					pdf.CellFormat(strWd, textSz, str, "", 0, "L", true, 0, "")
+					pdf.TransformEnd()
+				} else {
+					drawX -= strWd / 2.0
+					if g.XLabelIn {
+						pdf.SetXY(drawX, drawY-textSz-strOfs)
+					} else {
+						pdf.SetXY(drawX, drawY+strOfs)
+					}
+					pdf.CellFormat(strWd, textSz, str, "", 0, "L", true, 0, "")
+				}
+			}
+		}
+
+		// Y labels
+		if g.YTickStr != nil {
+			drawX = lf
+			for _, y := range g.yTicks {
+				// str = strconv.FormatFloat(y, 'f', g.yPrecision, 64)
+				str = g.YTickStr(y, g.yPrecision)
+				strWd = pdf.GetStringWidth(str)
+				if g.YLabelIn {
+					pdf.SetXY(drawX+strOfs, g.Y(y)-halfTextSz)
+				} else {
+					pdf.SetXY(lf-strOfs-strWd, g.Y(y)-halfTextSz)
+				}
+				pdf.CellFormat(strWd, textSz, str, "", 0, "L", true, 0, "")
+			}
+		}
+
+		// Restore drawing attributes
+		st.Put(pdf)
+
+	}
+
+}
+
+// Plot plots a series of count line segments from xMin to xMax. It repeatedly
+// calls fnc(x) to retrieve the y value associate with x. The currently
+// selected line drawing attributes are used.
+func (g GridType) Plot(pdf *Fpdf, xMin, xMax float64, count int, fnc func(x float64) (y float64)) {
+	if count > 0 {
+		var x, delta, drawX0, drawY0, drawX1, drawY1 float64
+		delta = (xMax - xMin) / float64(count)
+		x = xMin
+		for j := 0; j <= count; j++ {
+			if j == 0 {
+				drawX1 = g.X(x)
+				drawY1 = g.Y(fnc(x))
+			} else {
+				pdf.Line(drawX0, drawY0, drawX1, drawY1)
+			}
+			x += delta
+			drawX0 = drawX1
+			drawY0 = drawY1
+			drawX1 = g.X(x)
+			drawY1 = g.Y(fnc(x))
+		}
+	}
+}

+ 220 - 0
htmlbasic.go

@@ -0,0 +1,220 @@
+/*
+ * 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" || alignStr == "R" {
+					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 "right":
+				html.pdf.Ln(lineHt)
+				alignStr = "R"
+			case "left":
+				html.pdf.Ln(lineHt)
+				alignStr = "L"
+			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"
+			case "right":
+				html.pdf.Ln(lineHt)
+				alignStr = "L"
+			}
+		}
+	}
+}

BIN
image/doc.png


+ 20 - 0
image/doc.svg

@@ -0,0 +1,20 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="109" height="20">
+  <linearGradient id="a" x2="0" y2="100%">
+    <stop offset="0" stop-color="#bbb" stop-opacity=".1" />
+    <stop offset="1" stop-opacity=".1" />
+  </linearGradient>
+  <rect rx="3" width="109" height="20" fill="#555" />
+  <rect rx="3" x="44" width="65" height="20" fill="#5272B4" />
+  <path fill="#5272B4" d="M44 0h4v20h-4z" />
+  <rect rx="3" width="109" height="20" fill="url(#a)" />
+  <g fill="#fff" text-anchor="middle"
+  font-family="DejaVu Sans,Verdana,Geneva,sans-serif"
+  font-size="11">
+    <text x="23" y="15" fill="#010101" fill-opacity=".3">
+    godoc</text>
+    <text x="23" y="14">godoc</text>
+    <text x="75.5" y="15" fill="#010101" fill-opacity=".3">
+    reference</text>
+    <text x="75.5" y="14">reference</text>
+  </g>
+</svg>

BIN
image/fpdf.png


BIN
image/gofpdf.png


BIN
image/golang-gopher.png


BIN
image/golang-gopher.tiff


BIN
image/logo-gray.png


BIN
image/logo-progressive.jpg


BIN
image/logo-rgb.png


BIN
image/logo.gif


BIN
image/logo.jpg


BIN
image/logo.png


BIN
image/logo_gofpdf.jpg


BIN
image/mit.png


+ 20 - 0
image/mit.svg

@@ -0,0 +1,20 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="109" height="20">
+  <linearGradient id="a" x2="0" y2="100%">
+    <stop offset="0" stop-color="#bbb" stop-opacity=".1" />
+    <stop offset="1" stop-opacity=".1" />
+  </linearGradient>
+  <rect rx="3" width="109" height="20" fill="#555" />
+  <rect rx="3" x="64" width="45" height="20" fill="#7b5" />
+  <path fill="#7b5" d="M64 0h4v20h-4z" />
+  <rect rx="3" width="109" height="20" fill="url(#a)" />
+  <g fill="#fff" text-anchor="middle"
+  font-family="DejaVu Sans,Verdana,Geneva,sans-serif"
+  font-size="11">
+    <text x="30" y="15" fill="#010101" fill-opacity=".3">
+    license</text>
+    <text x="30" y="14">license</text>
+    <text x="85" y="15" fill="#010101" fill-opacity=".3">
+    MIT</text>
+    <text x="85" y="14">MIT</text>
+  </g>
+</svg>

+ 73 - 0
image/signature.svg

@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg" height="1106" width="3990">
+  <path
+     d="m 234.43804,111.69821 c 50.21866,26.50627 126.75595,-3.87395 151.46369,-35.941621 24.70774,-32.067668 10.41159,-51.980992 -16.41089,-58.072772 -26.82248,-6.09178 -42.17661,10.494756 -57.68933,33.13636 -15.51272,22.641602 -22.3395,49.640453 -26.04984,89.319923 -3.71034,39.67947 -2.57151,103.67609 -16.65175,144.69433 -14.08024,41.01824 -40.79012,59.98014 -80.0876,71.50199 -39.29748,11.52185 -96.607494,6.67866 -126.372407,-24.20296 -29.764916,-30.88162 -24.693439,-84.55794 0.62001,-107.05538 25.313453,-22.49744 49.916587,-21.8463 53.386947,18.74456 3.47036,40.59086 -77.347635,106.99944 -102.157295,102.59574 -24.80966,-4.4037 -9.1930819,0 -13.78962288,0" />
+  <path
+     d="m 535.44946,262.31206 c 16.02735,-13.54645 29.98118,-31.39768 32.51139,-52.84016 1.4974,-10.24434 -1.94415,-22.06454 -11.64632,-27.13714 -22.66026,-14.31032 -51.37591,-9.68663 -75.27088,-1.12303 -29.57925,11.19994 -56.66841,28.48168 -80.87983,48.69857 -15.56749,13.48245 -30.31327,28.65126 -40.17476,46.87113 -10.56334,25.04076 5.93271,58.80187 33.76392,62.35287 20.97698,3.69753 41.31134,-5.15667 59.15595,-15.26739 23.68053,-12.07041 45.37059,-27.68722 65.11773,-45.42392 5.85816,-4.99109 11.66007,-10.04795 17.4228,-15.14884" />
+  <path
+     d="m 605.17805,221.06416 c -39.71057,22.89155 -90.21146,57.33437 -110.62013,81.46882 -20.40867,24.13445 1.74636,32.16167 21.51346,33.96557 19.7671,1.8039 40.22731,-5.81242 63.90833,-18.83825 23.68102,-13.02583 54.88215,-39.05314 73.09016,-60.24005 18.20801,-21.18691 37.84165,-41.69088 43.78312,-57.46575 5.94147,-15.77487 6.81292,-20.38898 -2.3045,-26.03079" />
+  <path
+     d="m 576.69736,336.95111 c 59.46452,-49.53559 110.50457,-110.94455 181.15663,-145.53797 21.55772,-14.53068 69.21456,-30.38164 74.52476,8.12435 2.15457,32.87115 -24.99905,56.36851 -41.3729,81.85669 -11.33394,14.91071 -34.85688,47.22341 -38.29416,51.12061 38.40925,-59.07476 94.0006,-105.23813 152.94098,-142.74425 21.53324,-14.17578 76.3474,-17.732 63.14039,22.44093 -6.44013,30.30909 -29.58192,52.20309 -51.31162,72.13403 -22.35245,20.18703 -11.93986,55.81184 21.21245,48.89199 28.04358,-1.72994 49.86098,-21.80465 73.62851,-34.51546 51.0484,-39.90132 89.3284,-97.12351 150.3008,-123.60116 30.7216,-12.02494 70.5868,-23.14241 98.2954,1.38478 22.9075,21.32517 9.8573,56.2678 -7.0675,76.93906 -18.1931,26.99594 -44.6741,46.96256 -74.8471,58.94304 -34.0583,20.33195 -79.3725,18.48794 -110.8061,-6.03301 -1.0838,-0.69666 -2.2533,-1.23366 -3.4004,-1.81269" />
+  <path
+     d="m 1145.2696,144.64925 c -19.2615,48.72397 -39.2763,98.0821 -71.8076,139.71403 -28.4578,44.00142 -46.4445,94.33551 -79.72453,135.30113 -23.78316,32.93768 -48.80204,65.54924 -80.01549,91.86673 -19.47895,6.1922 -20.04137,-20.7923 -14.66105,-32.91267 12.83153,-36.25521 37.22095,-66.57625 54.90924,-100.3885 22.07476,-38.69659 54.05253,-69.56182 85.74383,-100.24739" />
+  <path
+     d="m 1067.4918,308.53814 c 41.6055,37.74324 106.1656,40.87499 155.2476,16.47425 79.7307,-33.80513 147.627,-88.69981 215.7912,-140.91414 38.5692,-31.19936 75.8068,-66.58379 98.2999,-111.442691 5.2858,-16.340836 11.2358,-38.191353 -2.3042,-51.988823 -24.8579,-9.392422 -44.7459,19.21292 -62.7133,32.466761 -42.206,41.159272 -75.9104,90.348773 -105.7076,140.969903 -18.1332,33.9424 -36.3441,60.40033 -45.1009,105.84746 -4.8684,25.26636 17.3519,40.01019 38.489,36.24378 27.2382,-1.27906 52.1821,-14.06224 77.2642,-23.5167 20.2617,-9.77194 38.052,-23.75443 55.7341,-37.47313" />
+  <path
+     d="m 1509.1585,216.87147 c 45.3671,35.48031 84.7434,37.23796 135.7328,25.17331 14.925,-4.86754 25.7515,-17.97315 30.1445,-32.73996 6.2047,-12.9545 -0.2899,-27.91555 -12.929,-33.8982 -19.5006,-12.36806 -44.6888,-10.55607 -64.9092,-0.92535 -33.4028,14.45512 -59.4353,40.93033 -84.563,66.45243 -13.9248,16.55902 -22.671,38.06079 -22.9956,59.74639 0.7543,12.73146 10.7427,22.65661 22.5942,25.94215 28.6381,11.95988 61.6748,18.05546 91.8527,8.36881 20.1474,-7.27059 39.868,-15.91987 58.8894,-25.73255 22.7573,-13.36221 41.3454,-32.41648 60.072,-50.72036" />
+  <path
+     d="m 1779.9918,343.26036 c 28.6993,3.03127 63.3496,2.62457 82.7159,-22.45172 21.6447,-19.99229 43.1941,-48.10952 35.6329,-79.45221 -4.1368,-22.17497 -33.5802,-38.22486 -52.1616,-22.03003 -31.7488,22.47063 -31.372,70.25063 -12.8813,101.12391 23.6727,38.55114 74.0602,50.51158 116.164,41.35476 54.0203,-10.31179 104.4208,-53.87389 110.9357,-110.27278 0.7888,-32.83995 0.7757,-65.72269 4.9445,-98.36663 3.9298,-42.7466 9.9471,-89.084405 39.2166,-122.675002 17.104,-18.491716 51.2258,-26.9233518 69.4545,-5.555968 14.6931,19.194858 3.0296,45.294939 -10.7419,61.486039 -16.3416,25.138501 -48.7197,29.136431 -75.3811,36.237431 -26.4792,5.77658 -58.6276,2.75073 -76.1034,-20.51069 -9.6512,-10.713121 -20.4603,-22.768271 -20.6837,-38.053993" />
+  <path
+     d="m 2245.2696,122.42703 c -3.9166,0.81691 -6.5582,5.39919 -5.219,9.18763 1.2777,3.63173 4.3682,6.64885 8.1357,7.58096 2.108,0.12035 4.1149,-1.67454 4.2375,-3.78089 0.7885,-3.73488 0.2701,-7.91813 -2.1144,-10.99661 -1.2461,-1.37634 -3.1464,-2.37225 -5.0398,-1.99109" />
+  <path
+     d="m 2219.5751,170.3437 c -29.9457,39.95653 -58.8628,80.7409 -86.118,122.56461 -5.4378,11.43956 -6.9218,27.24913 2.6137,36.94004 11.5344,8.50012 26.6093,3.95387 39.1614,0.62975 31.967,-8.46295 63.2786,-21.86206 88.264,-43.97857 15.2095,-12.48824 29.1196,-26.55137 41.4956,-41.85028" />
+  <path
+     d="m 2487.38,203.45563 c -3.3292,-19.2489 -24.4513,-30.55681 -42.8081,-28.63327 -39.0192,-1.47124 -74.6768,18.22839 -106.1126,39.27122 -27.4601,19.28281 -52.9628,45.12902 -62.0025,78.30592 -2.9108,24.00347 18.676,49.02117 43.417,46.57579 41.4005,-0.49369 78.4941,-23.55071 108.3115,-50.5202 26.5153,-22.3804 52.8121,-49.50782 59.1947,-84.99946" />
+  <path
+     d="m 2515.4085,226.5937 c -48.3542,24.84206 -95.4271,57.89871 -121.9801,106.67545 -38.548,57.86235 -85.0736,109.83278 -130.7587,162.02483 -14.3416,13.79585 -31.8449,28.78802 -52.8206,28.38924 -22.4201,-5.81296 -20.145,-35.44311 -3.7589,-46.92382 18.3472,-20.65863 39.7594,-38.46949 61.3752,-55.55681 37.3089,-27.01631 74.2659,-55.34905 116.5753,-74.2272 45.8819,-21.27356 92.5741,-41.44894 133.4511,-71.77058" />
+  <path
+     d="m 2561.9362,176.5937 c -11.728,39.55572 -31.7885,76.05727 -54.1537,110.51619 -11.367,17.27415 -23.5479,34.0347 -36.8185,49.90047" />
+  <path
+     d="m 2471.6585,334.92703 c 39.4203,-54.93792 84.2673,-108.82208 144.2119,-142.13528 20.4555,-10.53089 43.6781,-13.18946 66.1233,-16.24748 15.4075,-2.13385 35.1588,8.90133 33.4692,26.24623 -2.9508,16.37726 -14.16,29.73489 -22.9962,43.3486 -13.3021,19.00229 -30.5436,36.66009 -36.611,59.58253 -4.3581,18.38699 14.1449,34.91044 31.9547,29.10574 16.8023,-4.83584 31.073,-15.60156 46.3125,-23.86514 23.356,-14.17855 45.5509,-30.69352 63.9244,-51.0352" />
+  <path
+     d="m 2945.2696,276.5937 c 22.3825,-18.04222 43.6601,-40.96167 49.1836,-70.14766 1.6596,-16.7076 -14.1662,-31.70685 -30.5059,-31.31677 -38.4972,-6.9588 -76.9683,9.1156 -108.0208,30.84253 -27.6063,19.08076 -55.1974,41.48489 -69.2262,72.82154 -7.1903,18.94072 -2.0574,44.40278 17.325,53.92146 22.3966,12.66022 50.5757,7.55107 71.8376,-5.02642 25.3952,-13.7463 46.7256,-33.50699 69.4067,-51.09468" />
+  <path
+     d="m 3032.0751,221.03814 c -34.9663,24.39777 -159.9904,94.46573 -91.1404,111.19476 49.5078,12.02932 120.689,-54.55505 178.2367,-101.75128 57.5477,-47.19623 164.1423,-136.348841 176.2724,-205.706175 12.1301,-69.357335 -35.8274,25.038279 -57.6617,62.402284 -21.8343,37.364011 -53.1817,114.582201 -93.4244,175.681151 -55.9422,84.93494 14.2268,97.70016 78.695,54.07139 43.4593,-29.41104 56.0463,-39.23804 79.8558,-64.64213" />
+  <path
+     d="m 3119.5751,163.39925 c 51.3284,2.8018 102.806,4.27265 154.1667,1.38889" />
+  <path
+     d="m 3359.1585,166.17703 c -26.0554,38.94967 -53.443,76.90675 -75.3826,118.80876 -8.2374,15.73252 -12.8945,40.55439 6.2938,47.64921 25.3545,6.43589 34.5616,-2.95338 49.294,-7.34667 48.0292,-19.31164 87.8533,-54.50776 122.854,-93.37814 15.42,-20.923 30.5124,-42.09003 46.9408,-62.26134" />
+  <path
+     d="m 3511.2418,168.95481 c -31.3786,34.96488 -59.3857,72.92099 -84.9995,112.24284 -6.288,13.61689 -16.1644,29.28735 -9.8599,44.58789 7.0942,13.41865 25.2642,10.69636 37.6171,7.93765 31.8778,-9.70921 58.1068,-31.49347 83.8755,-51.77583 20.5616,-16.72078 38.3203,-36.60992 53.5974,-58.18739 14.5478,-17.73424 29.2159,-35.93086 39.6787,-56.3568 4.934,-18.95097 -28.1547,-19.20088 -17.7187,-0.12487 9.5405,17.82935 32.3392,18.53167 50.1021,19.48194 16.3122,-3.37266 23.3898,15.5346 12.9603,26.5127 -6.8718,8.02389 -13.7478,15.769 -19.1588,24.9829 -16.8576,24.69747 -36.847,48.68268 -44.6449,78.10881 -3.0723,19.33042 19.5849,33.62972 36.7818,27.38476 35.6706,-8.34057 67.9833,-26.49985 99.2689,-44.93349" />
+  <path
+     d="m 3763.3251,216.87147 c 33.1817,22.33062 74.828,35.62344 114.8149,27.5851 15.6821,-3.20582 30.2525,-10.71137 43.1524,-19.942 17.3248,-14.2012 16.9209,-44.79145 -2.1675,-57.28603 -13.4925,-8.89012 -30.6833,-5.87659 -45.6599,-3.46265 -33.5763,7.00049 -61.9142,28.29846 -85.8989,51.8761 -25.4017,22.73023 -42.112,57.70516 -36.9155,92.17467 6.3894,18.1743 25.3211,28.36102 43.6991,29.78005 26.397,2.30348 52.8197,-3.96515 77.6246,-12.547 39.816,-14.49663 75.2011,-38.73414 108.0175,-65.12268" />
+  <path
+     d="m 127.96633,989.9893 q -30.652774,0 -60.833949,-8.48849 -29.709599,-8.96003 -49.515998,-23.57904 l 12.732685,-75.45295 h 2.829486 q 20.749561,15.09059 44.800188,23.57904 24.050628,8.48846 46.686518,8.48846 44.32861,0 44.32861,-32.0675 0,-12.26111 -6.60214,-20.27798 -6.13055,-8.48846 -22.1643,-15.56217 L 91.183006,824.46436 Q 57.700762,809.37377 39.309106,783.43682 21.38903,757.49987 21.38903,723.07446 q 0,-31.59592 14.619009,-54.70339 15.09059,-23.57904 41.970703,-36.31173 27.351698,-12.73268 63.663428,-12.73268 26.88012,0 53.28865,7.07371 26.40853,7.07372 42.91386,18.39166 l -12.2611,71.20872 h -2.82949 Q 208.13508,705.62597 187.8571,699.967 q -19.8064,-6.13056 -39.14121,-6.13056 -41.49913,0 -41.49913,28.29486 0,11.31794 6.60214,19.33482 7.07371,8.01687 22.1643,14.61901 l 42.44228,19.33482 q 40.55597,18.39165 58.47604,42.91386 17.92008,24.05063 17.92008,59.89078 0,33.95383 -16.03376,59.4192 -15.56217,24.99379 -43.85702,38.66963 -28.29486,13.67588 -66.96449,13.67588 z"/>
+  <path
+     d="m 355.73912,985.27346 q -33.95383,0 -53.76023,-18.86324 -19.8064,-18.86323 -19.8064,-50.45916 0,-66.96449 89.1288,-74.98136 l 58.00446,-5.18739 v -2.35791 q 0,-16.50533 -9.9032,-23.57905 -9.43162,-7.54529 -30.18118,-7.54529 -20.74956,0 -43.85703,5.18739 -23.10747,4.71581 -36.78331,12.73268 h -3.30107 l 12.2611,-66.96449 q 41.49913,-16.97691 87.71406,-16.97691 106.10571,0 106.10571,103.27622 v 73.56663 q 0,19.8064 2.82948,37.25489 3.30107,17.4485 8.48846,27.3517 v 3.77264 h -76.39611 q -7.07371,-16.03375 -8.48846,-35.36857 h -3.30106 q -8.96004,17.92008 -30.18118,28.76644 -21.22115,10.37478 -48.57284,10.37478 z m 6.13055,-76.86769 q 0,19.33482 23.10747,19.33482 19.8064,0 32.0675,-11.31795 12.26111,-11.31794 12.26111,-28.76643 v -5.65897 l -38.19806,3.30106 q -29.23802,2.82949 -29.23802,23.10747 z"/>
+  <path
+     d="M 565.59215,981.50081 V 741.9377 h 76.39611 v 41.9707 h 3.30107 q 8.48845,-22.63588 26.88011,-34.89699 18.86324,-12.73268 43.38544,-12.73268 51.40233,0 70.26556,44.32861 h 1.88633 q 10.84636,-22.16431 30.18118,-33.01067 19.33482,-11.31794 45.27177,-11.31794 41.49912,0 63.19184,27.35169 22.16431,26.88012 22.16431,75.92453 V 981.50081 H 863.6313 V 847.10025 q 0,-39.14122 -30.18118,-39.14122 -15.56217,0 -24.99379,11.78952 -8.96004,11.31795 -8.96004,30.65276 v 131.0995 H 714.61172 V 847.57183 q 0,-39.6128 -30.18118,-39.6128 -15.56217,0 -24.99379,11.78952 -8.96003,11.78953 -8.96003,32.53909 v 129.21317 z"/>
+  <path
+     d="M 1001.8042,1099.396 V 741.9377 h 80.6403 v 35.36857 h 3.7726 q 22.1643,-41.02754 70.2656,-41.02754 31.1243,0 54.2318,15.56217 23.1075,15.56217 35.8402,43.85703 12.7326,27.82327 12.7326,66.02133 0,37.72647 -12.7326,66.02133 -12.7327,28.29485 -35.8402,43.85702 -23.1075,15.56219 -54.2318,15.56219 -42.9139,0 -66.0213,-33.01068 h -3.7727 V 1099.396 Z m 125.9121,-183.91652 q 21.2211,0 33.4822,-14.14742 12.2611,-14.61901 12.2611,-39.14122 0,-25.46537 -12.2611,-39.6128 -11.7895,-14.61901 -33.4822,-14.61901 -20.7496,0 -33.0107,14.61901 -12.2611,14.14743 -12.2611,39.14122 0,24.52221 12.2611,39.14121 12.2611,14.61901 33.0107,14.61901 z"/>
+  <path
+     d="M 1302.2008,981.50081 V 613.66769 h 84.8846 v 367.83312 z"/>
+  <path
+     d="m 1557.797,987.1598 q -58.9477,0 -93.3731,-33.48226 -33.9538,-33.48225 -33.9538,-91.95828 0,-39.6128 16.0338,-67.43608 16.5053,-28.29485 44.8002,-42.91386 28.7664,-15.09059 65.0781,-15.09059 55.6466,0 84.413,33.01066 29.238,32.53909 29.238,92.90145 v 12.73268 l -153.7354,15.09059 q 5.659,16.97692 19.8064,24.05063 14.619,7.07371 35.8402,7.07371 24.0506,0 46.2149,-5.65897 22.6359,-6.13055 33.9539,-12.2611 h 3.301 l -12.2611,66.96449 q -14.1474,6.13055 -37.7265,11.31794 -23.579,5.65899 -47.6296,5.65899 z m -2.8295,-188.63239 q -15.5622,0 -26.8801,9.43162 -10.8464,9.43162 -14.619,32.0675 l 79.2256,-7.54529 q -3.3011,-17.92008 -13.2043,-25.93695 -9.9032,-8.01688 -24.5222,-8.01688 z"/>
+  <path
+     d="m 1912.4242,989.9893 q -30.6527,0 -60.8339,-8.48849 -29.7096,-8.96003 -49.516,-23.57904 l 12.7327,-75.45295 h 2.8295 q 20.7495,15.09059 44.8002,23.57904 24.0506,8.48846 46.6865,8.48846 44.3286,0 44.3286,-32.0675 0,-12.26111 -6.6022,-20.27798 -6.1305,-8.48846 -22.1643,-15.56217 l -49.0444,-22.16431 q -33.4822,-15.09059 -51.8739,-41.02754 -17.9201,-25.93695 -17.9201,-60.36236 0,-31.59592 14.6191,-54.70339 15.0905,-23.57904 41.9707,-36.31173 27.3517,-12.73268 63.6634,-12.73268 26.8801,0 53.2886,7.07371 26.4086,7.07372 42.9139,18.39166 l -12.2611,71.20872 h -2.8295 q -14.619,-10.37478 -34.897,-16.03375 -19.8064,-6.13056 -39.1412,-6.13056 -41.4991,0 -41.4991,28.29486 0,11.31794 6.6021,19.33482 7.0737,8.01687 22.1643,14.61901 l 42.4423,19.33482 q 40.556,18.39165 58.476,42.91386 17.9201,24.05063 17.9201,59.89078 0,33.95383 -16.0337,59.4192 -15.5622,24.99379 -43.8571,38.66963 -28.2948,13.67588 -66.9645,13.67588 z"/>
+  <path
+     d="m 2124.6348,714.11442 q -23.1075,0 -37.2549,-13.67584 -14.1474,-14.14743 -14.1474,-35.36857 0,-21.22114 14.1474,-34.89699 14.1474,-14.14743 37.2549,-14.14743 23.1075,0 37.2549,14.14743 14.1474,13.67585 14.1474,34.89699 0,21.22114 -14.1474,35.36857 -14.1474,13.67584 -37.2549,13.67584 z m -42.4423,267.38639 V 741.9377 h 84.8846 v 239.56311 z"/>
+  <path
+     d="m 2329.7719,1105.055 q -27.8233,0 -53.7602,-6.6021 -25.937,-6.1306 -41.9707,-16.5053 l 14.1474,-66.493 h 3.3011 q 13.2042,8.0169 30.6527,12.7327 17.9201,5.1874 34.897,5.1874 31.5959,0 48.5729,-17.4485 16.9769,-17.4485 16.9769,-49.98756 v -17.44849 h -3.7727 q -23.1074,33.01066 -66.0213,33.01066 -31.1243,0 -54.2318,-15.09059 -23.1075,-15.56217 -35.8402,-42.91386 -12.7326,-27.82328 -12.7326,-64.60659 0,-37.25489 12.7326,-64.60659 12.7327,-27.35169 35.8402,-42.44228 23.1075,-15.56217 54.2318,-15.56217 24.9938,0 44.8002,11.31794 19.8064,11.31794 29.238,30.65276 h 3.3011 q 0.9431,-10.37478 3.301,-20.27798 2.3579,-9.9032 5.1874,-16.03375 h 80.1688 v 3.77265 q -6.1306,11.31794 -8.9601,29.7096 -2.3579,18.39165 -2.3579,34.89699 v 154.67854 q 0,67.43612 -35.8401,103.74782 -35.3686,36.3117 -101.8615,36.3117 z m 11.7895,-194.29133 q 20.7496,0 33.0107,-14.14742 12.2611,-14.14743 12.2611,-37.72648 0,-23.57905 -12.2611,-37.72647 -12.2611,-14.14743 -33.0107,-14.14743 -21.6927,0 -33.9538,14.14743 -11.7895,13.67584 -11.7895,38.19805 0,23.57905 12.2611,37.72648 12.2611,13.67584 33.4822,13.67584 z"/>
+  <path
+     d="M 2523.1198,981.50081 V 741.9377 h 76.3961 v 41.9707 h 3.301 q 8.4885,-22.63588 27.8233,-34.89699 19.3348,-12.73268 46.6865,-12.73268 40.556,0 63.6635,27.35169 23.579,27.3517 23.579,75.92453 v 141.94586 h -84.8846 V 849.45815 q 0,-41.49912 -33.9538,-41.49912 -17.4485,0 -27.8233,12.2611 -9.9032,12.26111 -9.9032,33.95383 v 127.32685 z"/>
+  <path
+     d="m 2875.8613,985.27346 q -33.9538,0 -53.7602,-18.86324 -19.8064,-18.86323 -19.8064,-50.45916 0,-66.96449 89.1288,-74.98136 l 58.0044,-5.18739 v -2.35791 q 0,-16.50533 -9.9032,-23.57905 -9.4316,-7.54529 -30.1812,-7.54529 -20.7495,0 -43.857,5.18739 -23.1075,4.71581 -36.7833,12.73268 h -3.3011 l 12.2611,-66.96449 q 41.4991,-16.97691 87.7141,-16.97691 106.1057,0 106.1057,103.27622 v 73.56663 q 0,19.8064 2.8295,37.25489 3.301,17.4485 8.4884,27.3517 v 3.77264 h -76.3961 q -7.0737,-16.03375 -8.4884,-35.36857 h -3.3011 q -8.96,17.92008 -30.1812,28.76644 -21.2211,10.37478 -48.5728,10.37478 z m 6.1305,-76.86769 q 0,19.33482 23.1075,19.33482 19.8064,0 32.0675,-11.31795 12.2611,-11.31794 12.2611,-28.76643 v -5.65897 l -38.198,3.30106 q -29.2381,2.82949 -29.2381,23.10747 z"/>
+  <path
+     d="M 3060.7205,807.95903 V 741.9377 h 40.5559 v -67.90765 h 84.8846 v 67.90765 h 58.9476 l -10.8464,66.02133 H 3186.161 V 863.134 q 0,50.93074 44.8002,50.93074 h 14.1474 l -10.8464,68.85082 h -35.3685 q -45.7434,0 -71.6803,-26.88012 -25.937,-26.88011 -25.937,-74.98136 v -73.09505 z"/>
+  <path
+     d="m 3394.1277,987.1598 q -54.7034,0 -85.8278,-30.65278 -31.1243,-31.12434 -31.1243,-86.77089 V 741.9377 h 84.8846 v 129.68476 q 0,21.22114 8.4884,32.53908 8.4885,11.31794 23.5791,11.31794 15.0905,0 23.579,-11.31794 8.4885,-11.31794 8.4885,-32.53908 V 741.9377 h 84.8845 v 127.79843 q 0,55.64655 -31.1243,86.77089 -31.1244,30.65278 -85.8277,30.65278 z"/>
+  <path
+     d="M 3562.4816,981.50081 V 741.9377 h 76.3961 v 46.68651 h 3.3011 q 16.5053,-52.34548 65.0781,-52.34548 14.1475,0 23.1075,5.65897 v 83.94141 h -3.3011 q -12.7327,-5.18739 -27.8232,-5.18739 -24.9938,0 -38.6697,16.50533 -13.2042,16.50533 -13.2042,44.32861 v 99.97515 z"/>
+  <path
+     d="m 3877.0254,987.1598 q -58.9477,0 -93.3731,-33.48226 -33.9538,-33.48225 -33.9538,-91.95828 0,-39.6128 16.0338,-67.43608 16.5053,-28.29485 44.8001,-42.91386 28.7665,-15.09059 65.0782,-15.09059 55.6466,0 84.413,33.01066 29.238,32.53909 29.238,92.90145 v 12.73268 l -153.7354,15.09059 q 5.659,16.97692 19.8064,24.05063 14.619,7.07371 35.8402,7.07371 24.0506,0 46.2149,-5.65897 22.6359,-6.13055 33.9538,-12.2611 h 3.3011 l -12.2611,66.96449 q -14.1474,6.13055 -37.7265,11.31794 -23.579,5.65899 -47.6296,5.65899 z m -2.8295,-188.63239 q -15.5622,0 -26.8801,9.43162 -10.8464,9.43162 -14.6191,32.0675 l 79.2256,-7.54529 q -3.301,-17.92008 -13.2042,-25.93695 -9.9032,-8.01688 -24.5222,-8.01688 z"/>
+</svg>

BIN
image/sweden.png


+ 143 - 0
internal/example/example.go

@@ -0,0 +1,143 @@
+// 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))
+	gofpdf.SetDefaultModificationDate(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC))
+}
+
+// setRoot assigns 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, false)
+	}
+	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 {
+		fileStr = filepath.ToSlash(fileStr)
+		fmt.Printf("Successfully generated %s\n", fileStr)
+	} else {
+		fmt.Println(err)
+	}
+}
+
+// SummaryCompare generates a predictable report for use by test examples. If
+// the specified error is nil, the generated file is compared with a reference
+// copy for byte-for-byte equality. If the files match, then the filename
+// delimiters are normalized and the filename printed to standard output with a
+// success message. If the files do not match, this condition is reported on
+// standard output. If the specified error is not nil, its String() value is
+// printed to standard output.
+func SummaryCompare(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)
+	}
+}

+ 31 - 0
internal/example/example_test.go

@@ -0,0 +1,31 @@
+/*
+ * 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_test
+
+import (
+	"errors"
+
+	"github.com/jung-kurt/gofpdf/internal/example"
+)
+
+// ExampleFilename tests the Filename() and Summary() functions.
+func ExampleFilename() {
+	fileStr := example.Filename("example")
+	example.Summary(errors.New("printer on fire"), fileStr)
+	// Output:
+	// printer on fire
+}

+ 24 - 0
internal/files/bin/Makefile

@@ -0,0 +1,24 @@
+TRG= ../files.go
+JSON= ../../../font/calligra.json
+Z= ../../../font/calligra.z
+
+${TRG} : ${JSON} ${Z} ./bin
+	echo "package files" >  ${TRG}
+	echo "" >> ${TRG}
+	echo "// CalligraJson is embedded byte slice for calligra.json" >> ${TRG}
+	echo "var CalligraJson = []byte{" >> ${TRG}
+	./bin < ${JSON} >> ${TRG}
+	echo "}" >> ${TRG}
+	echo "" >> ${TRG}
+	echo "// CalligraZ is embedded byte slice for calligra.z" >> ${TRG}
+	echo "var CalligraZ = []byte{" >> ${TRG}
+	./bin < ${Z} >> ${TRG}
+	echo "}" >> ${TRG}
+	gofmt -s -w ${TRG}
+
+./bin : bin.go
+	go build -v
+
+clean :
+	rm -f ./bin ${TRG}
+

+ 28 - 0
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)
+	}
+}

+ 1691 - 0
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}

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio