diff options
Diffstat (limited to 'Build/source')
375 files changed, 8085 insertions, 5542 deletions
diff --git a/Build/source/texk/dvisvgm/ChangeLog b/Build/source/texk/dvisvgm/ChangeLog index 5af72b2d14c..e2165ebb13b 100644 --- a/Build/source/texk/dvisvgm/ChangeLog +++ b/Build/source/texk/dvisvgm/ChangeLog @@ -1,3 +1,7 @@ +2021-01-23 TANAKA Takuji <ttk@t-lab.opal.ne.jp> + + * dvisvgm-src/*, version.ac: 2.11.1; update sources and patches. + 2020-06-07 Karl Berry <karl@freefriends.org> * configure.ac, diff --git a/Build/source/texk/dvisvgm/TLpatches/ChangeLog b/Build/source/texk/dvisvgm/TLpatches/ChangeLog index 2442901a315..c64445c335d 100644 --- a/Build/source/texk/dvisvgm/TLpatches/ChangeLog +++ b/Build/source/texk/dvisvgm/TLpatches/ChangeLog @@ -1,3 +1,8 @@ +2021-01-23 TANAKA Takuji <ttk@t-lab.opal.ne.jp> + + * Import 2.11.1. + * patch-04-configure: adapt. + 2019-12-09 Martin Gieseking <martin.gieseking@uos.de> * Import 2.8.2. diff --git a/Build/source/texk/dvisvgm/TLpatches/patch-04-configure b/Build/source/texk/dvisvgm/TLpatches/patch-04-configure index fb93d7a0dd7..fa1a443637b 100644 --- a/Build/source/texk/dvisvgm/TLpatches/patch-04-configure +++ b/Build/source/texk/dvisvgm/TLpatches/patch-04-configure @@ -1,18 +1,18 @@ ---- dvisvgm-src/configure.ac 2020-03-13 04:34:12.000000000 -0700 -+++ configure.ac 2020-03-15 15:37:10.268162998 -0700 +--- dvisvgm-2.11.1/configure.ac 2021-01-21 23:07:49.000000000 +0900 ++++ configure.ac 2021-01-23 08:58:18.575395177 +0900 @@ -1,149 +1,156 @@ -# This file is part of dvisvgm --# Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> +-# Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> -# -# Process this file with autoconf to produce a configure script. - -AC_PREREQ(2.59) --AC_INIT([dvisvgm],[2.9],[martin.gieseking@uos.de]) -+# $Id: configure.ac 53077 2019-12-10 06:22:32Z preining $ +-AC_INIT([dvisvgm],[2.11.1],[martin.gieseking@uos.de]) ++dnl $Id$ +dnl Process this file with autoconf to produce a configure script +dnl for dvisvgm in TeX Live. +dnl -+dnl Copyright 2015-2020 Karl Berry <tex-live@tug.org> ++dnl Copyright 2015-2021 Karl Berry <tex-live@tug.org> +dnl Copyright 2009-2014 Peter Breitenlohner <tex-live@tug.org> +dnl +dnl This file is free software; the copyright holder @@ -25,7 +25,7 @@ +AC_PREREQ([2.65]) +m4_include([version.ac])[] dnl define dvisvgm_version +AC_INIT([dvisvgm (TeX Live)], dvisvgm_version, [tex-k@tug.org]) - DATE="March 2020" + DATE="January 2021" -AC_CONFIG_SRCDIR(src) +AC_CONFIG_SRCDIR([dvisvgm-src/src/dvisvgm.cpp]) AC_CONFIG_HEADERS([config.h]) diff --git a/Build/source/texk/dvisvgm/configure b/Build/source/texk/dvisvgm/configure index 5d9c0e8f741..9f03e23c5aa 100755 --- a/Build/source/texk/dvisvgm/configure +++ b/Build/source/texk/dvisvgm/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for dvisvgm (TeX Live) 2.9.1. +# Generated by GNU Autoconf 2.69 for dvisvgm (TeX Live) 2.11.1. # # Report bugs to <tex-k@tug.org>. # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='dvisvgm (TeX Live)' PACKAGE_TARNAME='dvisvgm--tex-live-' -PACKAGE_VERSION='2.9.1' -PACKAGE_STRING='dvisvgm (TeX Live) 2.9.1' +PACKAGE_VERSION='2.11.1' +PACKAGE_STRING='dvisvgm (TeX Live) 2.11.1' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1391,7 +1391,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures dvisvgm (TeX Live) 2.9.1 to adapt to many kinds of systems. +\`configure' configures dvisvgm (TeX Live) 2.11.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1462,7 +1462,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of dvisvgm (TeX Live) 2.9.1:";; + short | recursive ) echo "Configuration of dvisvgm (TeX Live) 2.11.1:";; esac cat <<\_ACEOF @@ -1594,7 +1594,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -dvisvgm (TeX Live) configure 2.9.1 +dvisvgm (TeX Live) configure 2.11.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2462,7 +2462,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by dvisvgm (TeX Live) $as_me 2.9.1, which was +It was created by dvisvgm (TeX Live) $as_me 2.11.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2820,7 +2820,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu -DATE="March 2020" +DATE="January 2021" ac_config_headers="$ac_config_headers config.h" @@ -8209,7 +8209,7 @@ fi # Define the identity of the package. PACKAGE='dvisvgm--tex-live-' - VERSION='2.9.1' + VERSION='2.11.1' cat >>confdefs.h <<_ACEOF @@ -13161,7 +13161,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -13207,7 +13207,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -13231,7 +13231,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -13276,7 +13276,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -13300,7 +13300,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -20207,7 +20207,7 @@ Usage: $0 [OPTIONS] Report bugs to <bug-libtool@gnu.org>." lt_cl_version="\ -dvisvgm (TeX Live) config.lt 2.9.1 +dvisvgm (TeX Live) config.lt 2.11.1 configured by $0, generated by GNU Autoconf 2.69. Copyright (C) 2011 Free Software Foundation, Inc. @@ -23512,7 +23512,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by dvisvgm (TeX Live) $as_me 2.9.1, which was +This file was extended by dvisvgm (TeX Live) $as_me 2.11.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -23578,7 +23578,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -dvisvgm (TeX Live) config.status 2.9.1 +dvisvgm (TeX Live) config.status 2.11.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/Build/source/texk/dvisvgm/configure.ac b/Build/source/texk/dvisvgm/configure.ac index c6cdc12aeb8..5e2d6bdae49 100644 --- a/Build/source/texk/dvisvgm/configure.ac +++ b/Build/source/texk/dvisvgm/configure.ac @@ -2,7 +2,7 @@ dnl $Id$ dnl Process this file with autoconf to produce a configure script dnl for dvisvgm in TeX Live. dnl -dnl Copyright 2015-2020 Karl Berry <tex-live@tug.org> +dnl Copyright 2015-2021 Karl Berry <tex-live@tug.org> dnl Copyright 2009-2014 Peter Breitenlohner <tex-live@tug.org> dnl dnl This file is free software; the copyright holder @@ -15,7 +15,7 @@ dnl AC_PREREQ([2.65]) m4_include([version.ac])[] dnl define dvisvgm_version AC_INIT([dvisvgm (TeX Live)], dvisvgm_version, [tex-k@tug.org]) -DATE="March 2020" +DATE="January 2021" AC_CONFIG_SRCDIR([dvisvgm-src/src/dvisvgm.cpp]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIRS([../../m4])dnl not just _DIR diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog b/Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog index 725017aba85..3c17148c4c8 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog +++ b/Build/source/texk/dvisvgm/dvisvgm-src/ChangeLog @@ -1,3 +1,453 @@ +2021-01-21 Martin Gieseking <martin.gieseking@uos.de> + + * .appveyor.yml, .travis.yml, configure.ac, doc/dvisvgm.1, src/Doxyfile, + src/version.hpp: + set version to 2.11.1 + + * NEWS: + updated NEWS + +2021-01-03 Martin Gieseking <martin.gieseking@uos.de> + + * Makefile.am, README, README.md, configure.ac, doc/Makefile.am, + doc/conf-dblatex-man.xsl, doc/conf-dblatex-pdf.xsl, doc/db2html.xsl, + doc/dvisvgm.1, doc/dvisvgm.txt.in, doc/tweak-db-article.xsl, + doc/tweak-db-refentry.xsl, doc/tweak-dblatex-pdf.xsl, libs/Makefile.am, + libs/ff-woff/fontforge/tmpfile2.cpp, src/AGLTable.hpp, + src/BasicDVIReader.cpp, src/BasicDVIReader.hpp, src/Bezier.cpp, + src/Bezier.hpp, src/BgColorSpecialHandler.cpp, + src/BgColorSpecialHandler.hpp, src/Bitmap.cpp, src/Bitmap.hpp, + src/BoundingBox.cpp, src/BoundingBox.hpp, src/CLCommandLine.cpp, + src/CLCommandLine.hpp, src/CLOption.hpp, src/CMap.cpp, src/CMap.hpp, + src/CMapManager.cpp, src/CMapManager.hpp, src/CMapReader.cpp, + src/CMapReader.hpp, src/Calculator.cpp, src/Calculator.hpp, + src/CharMapID.cpp, src/CharMapID.hpp, src/Character.hpp, src/Color.cpp, + src/Color.hpp, src/ColorSpecialHandler.cpp, src/ColorSpecialHandler.hpp, + src/CommandLine.hpp, src/DLLoader.cpp, src/DLLoader.hpp, + src/DVIActions.hpp, src/DVIReader.cpp, src/DVIReader.hpp, + src/DVIToSVG.cpp, src/DVIToSVG.hpp, src/DVIToSVGActions.cpp, + src/DVIToSVGActions.hpp, src/Directory.cpp, src/Directory.hpp, + src/DvisvgmSpecialHandler.cpp, src/DvisvgmSpecialHandler.hpp, + src/EPSFile.cpp, src/EPSFile.hpp, src/EPSToSVG.hpp, + src/EllipticalArc.cpp, src/EllipticalArc.hpp, src/EmSpecialHandler.cpp, + src/EmSpecialHandler.hpp, src/EncFile.cpp, src/EncFile.hpp, + src/FileFinder.cpp, src/FileFinder.hpp, src/FilePath.cpp, + src/FilePath.hpp, src/FileSystem.cpp, src/FileSystem.hpp, + src/FixWord.hpp, src/Font.cpp, src/Font.hpp, src/FontCache.cpp, + src/FontCache.hpp, src/FontEncoding.cpp, src/FontEncoding.hpp, + src/FontEngine.cpp, src/FontEngine.hpp, src/FontManager.cpp, + src/FontManager.hpp, src/FontMap.cpp, src/FontMap.hpp, + src/FontMetrics.cpp, src/FontMetrics.hpp, src/FontStyle.hpp, + src/FontWriter.cpp, src/FontWriter.hpp, src/GFGlyphTracer.cpp, + src/GFGlyphTracer.hpp, src/GFReader.cpp, src/GFReader.hpp, + src/GFTracer.cpp, src/GFTracer.hpp, src/Ghostscript.cpp, + src/Ghostscript.hpp, src/Glyph.hpp, src/GlyphTracerMessages.hpp, + src/GraphicsPath.hpp, src/HashFunction.cpp, src/HashFunction.hpp, + src/HtmlSpecialHandler.cpp, src/HtmlSpecialHandler.hpp, + src/HyperlinkManager.cpp, src/HyperlinkManager.hpp, src/ImageToSVG.cpp, + src/ImageToSVG.hpp, src/InputBuffer.cpp, src/InputBuffer.hpp, + src/InputReader.cpp, src/InputReader.hpp, src/JFM.cpp, src/JFM.hpp, + src/Length.cpp, src/Length.hpp, src/MD5HashFunction.hpp, src/Makefile.am, + src/MapLine.cpp, src/MapLine.hpp, src/Matrix.cpp, src/Matrix.hpp, + src/Message.cpp, src/Message.hpp, src/MessageException.hpp, + src/MetafontWrapper.cpp, src/MetafontWrapper.hpp, src/MiKTeXCom.cpp, + src/MiKTeXCom.hpp, src/NoPsSpecialHandler.cpp, + src/NoPsSpecialHandler.hpp, src/NumericRanges.hpp, src/PDFParser.cpp, + src/PDFParser.hpp, src/PDFToSVG.hpp, src/PSFilter.hpp, + src/PSInterpreter.cpp, src/PSInterpreter.hpp, src/PSPattern.cpp, + src/PSPattern.hpp, src/PSPreviewFilter.cpp, src/PSPreviewFilter.hpp, + src/PageRanges.cpp, src/PageRanges.hpp, src/PageSize.cpp, + src/PageSize.hpp, src/Pair.hpp, src/PapersizeSpecialHandler.cpp, + src/PapersizeSpecialHandler.hpp, src/PathClipper.cpp, + src/PathClipper.hpp, src/PdfSpecialHandler.cpp, + src/PdfSpecialHandler.hpp, src/PreScanDVIReader.cpp, + src/PreScanDVIReader.hpp, src/Process.cpp, src/Process.hpp, + src/PsSpecialHandler.cpp, src/PsSpecialHandler.hpp, src/RangeMap.cpp, + src/RangeMap.hpp, src/SVGCharHandler.cpp, src/SVGCharHandler.hpp, + src/SVGCharHandlerFactory.cpp, src/SVGCharHandlerFactory.hpp, + src/SVGCharPathHandler.cpp, src/SVGCharPathHandler.hpp, + src/SVGCharTspanTextHandler.cpp, src/SVGCharTspanTextHandler.hpp, + src/SVGOutput.cpp, src/SVGOutput.hpp, src/SVGSingleCharTextHandler.cpp, + src/SVGSingleCharTextHandler.hpp, src/SVGTree.cpp, src/SVGTree.hpp, + src/ShadingPatch.cpp, src/ShadingPatch.hpp, src/SignalHandler.cpp, + src/SignalHandler.hpp, src/SourceInput.cpp, src/SourceInput.hpp, + src/SpecialActions.hpp, src/SpecialHandler.hpp, src/SpecialManager.cpp, + src/SpecialManager.hpp, src/StreamReader.cpp, src/StreamReader.hpp, + src/StreamWriter.cpp, src/StreamWriter.hpp, src/Subfont.cpp, + src/Subfont.hpp, src/System.cpp, src/System.hpp, src/TFM.cpp, + src/TFM.hpp, src/TTFAutohint.cpp, src/TTFAutohint.hpp, + src/TensorProductPatch.cpp, src/TensorProductPatch.hpp, src/Terminal.cpp, + src/Terminal.hpp, src/ToUnicodeMap.cpp, src/ToUnicodeMap.hpp, + src/TpicSpecialHandler.cpp, src/TpicSpecialHandler.hpp, + src/TriangularPatch.cpp, src/TriangularPatch.hpp, src/TrueTypeFont.cpp, + src/TrueTypeFont.hpp, src/Unicode.cpp, src/Unicode.hpp, + src/VFActions.hpp, src/VFReader.cpp, src/VFReader.hpp, + src/VectorIterator.hpp, src/VectorStream.hpp, src/XMLDocument.cpp, + src/XMLDocument.hpp, src/XMLNode.cpp, src/XMLNode.hpp, src/XMLString.cpp, + src/XMLString.hpp, src/XXHashFunction.hpp, src/ZLibOutputStream.hpp, + src/dvisvgm.cpp, src/ffwrapper.c, src/ffwrapper.h, src/macros.hpp, + src/optimizer/AttributeExtractor.cpp, + src/optimizer/AttributeExtractor.hpp, src/optimizer/DependencyGraph.hpp, + src/optimizer/GroupCollapser.cpp, src/optimizer/GroupCollapser.hpp, + src/optimizer/OptimizerModule.hpp, + src/optimizer/RedundantElementRemover.cpp, + src/optimizer/RedundantElementRemover.hpp, + src/optimizer/SVGOptimizer.cpp, src/optimizer/SVGOptimizer.hpp, + src/optimizer/TextSimplifier.cpp, src/optimizer/TextSimplifier.hpp, + src/optimizer/TransformSimplifier.cpp, + src/optimizer/TransformSimplifier.hpp, src/optimizer/WSNodeRemover.cpp, + src/optimizer/WSNodeRemover.hpp, src/options.dtd, src/options.xml, + src/psdefs.cpp, src/utility.cpp, src/utility.hpp, src/version.hpp, + src/version.hpp.in, src/windows.hpp, tests/BezierTest.cpp, + tests/BitmapTest.cpp, tests/BoundingBoxTest.cpp, + tests/CMapManagerTest.cpp, tests/CMapReaderTest.cpp, tests/CMapTest.cpp, + tests/CalculatorTest.cpp, tests/ColorSpecialTest.cpp, + tests/ColorTest.cpp, tests/CommandLineTest.cpp, tests/DVIReaderTest.cpp, + tests/DependencyGraphTest.cpp, tests/DirectoryTest.cpp, + tests/DvisvgmSpecialTest.cpp, tests/EllipticalArcTest.cpp, + tests/EmSpecialTest.cpp, tests/FileFinderTest.cpp, + tests/FilePathTest.cpp, tests/FileSystemTest.cpp, + tests/FontCacheTest.cpp, tests/FontManagerTest.cpp, + tests/FontMapTest.cpp, tests/GFGlyphTracerTest.cpp, + tests/GFReaderTest.cpp, tests/GhostscriptTest.cpp, + tests/GraphicsPathTest.cpp, tests/HashFunctionTest.cpp, + tests/JFMReaderTest.cpp, tests/LengthTest.cpp, tests/Makefile.am, + tests/MapLineTest.cpp, tests/MatrixTest.cpp, + tests/MessageExceptionTest.cpp, tests/PDFParserTest.cpp, + tests/PSInterpreterTest.cpp, tests/PageRagesTest.cpp, + tests/PageSizeTest.cpp, tests/PairTest.cpp, + tests/PapersizeSpecialTest.cpp, tests/RangeMapTest.cpp, + tests/SVGOutputTest.cpp, tests/ShadingPatchTest.cpp, + tests/SpecialManagerTest.cpp, tests/SplittedCharInputBufferTest.cpp, + tests/StreamInputBufferTest.cpp, tests/StreamReaderTest.cpp, + tests/StreamWriterTest.cpp, tests/StringMatcherTest.cpp, + tests/SubfontTest.cpp, tests/TFMReaderTest.cpp, + tests/TensorProductPatchTest.cpp, tests/ToUnicodeMapTest.cpp, + tests/TpicSpecialTest.cpp, tests/TriangularPatchTest.cpp, + tests/UnicodeTest.cpp, tests/UtilityTest.cpp, + tests/VectorIteratorTest.cpp, tests/VectorStreamTest.cpp, + tests/XMLNodeTest.cpp, tests/XMLStringTest.cpp, tests/check-conv, + tests/create-makefile, tests/data/Makefile.am, tests/genhashcheck.py, + tests/normalize.xsl, tests/testmain.cpp: + updated year in copyright statements to 2021 + +2020-12-30 Martin Gieseking <martin.gieseking@uos.de> + + * src/Calculator.cpp, tests/CalculatorTest.cpp: + fixed a comment and added minor calculator tests + + * src/Calculator.cpp, src/Calculator.hpp, tests/CalculatorTest.cpp: + use variant type for token objects in class Calculator + +2020-12-29 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontEngine.cpp: + renamed some local variables + +2020-12-21 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontEngine.cpp: + ensure unambiguity of GID to charcode mappings +(fixes #147) + + * src/Font.cpp, src/FontEngine.cpp, src/FontEngine.hpp: + Renamed FontEngine::buildCharMap() + +2020-11-28 Martin Gieseking <martin.gieseking@uos.de> + + * .appveyor.yml, .travis.yml, configure.ac, doc/dvisvgm.1, src/Doxyfile, + src/version.hpp: + set version to 2.11 + + * NEWS: + updated NEWS + +2020-11-20 Martin Gieseking <martin.gieseking@uos.de> + + * src/BasicDVIReader.cpp, src/BasicDVIReader.hpp, src/DVIReader.cpp, + src/DVIReader.hpp: + moved low-level DVIReader functions to BasicDVIReader +and some code + cleanup + + * src/BasicDVIReader.cpp, src/BasicDVIReader.hpp, src/DVIReader.cpp, + src/DVIToSVG.cpp, src/PdfSpecialHandler.cpp, src/PdfSpecialHandler.hpp: + process mapline specials before fontdefs +to ensure all mapline + definitions are present when registering fonts + +2020-11-19 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontMap.cpp, src/Subfont.cpp, src/Subfont.hpp, + tests/SubfontTest.cpp: + SubfontDefinition: replaced reference parameter with return value + +2020-11-18 Martin Gieseking <martin.gieseking@uos.de> + + * src/CMap.cpp, src/CMap.hpp, src/Font.cpp, src/FontEncoding.cpp, + src/FontEncoding.hpp: + keep selected Unicode fontmap if assigned CMap maps to Unicode + + * src/DVIReader.cpp, src/FontManager.cpp, src/FontManager.hpp: + added fallback for missing characters in JFM-based virtual fonts +(closes + #144) + +2020-11-17 Martin Gieseking <martin.gieseking@uos.de> + + * src/Unicode.cpp, src/Unicode.hpp, tests/UnicodeTest.cpp: + added functions to convert surrogate pairs + + * src/CMap.cpp, src/CMap.hpp, src/CMapReader.cpp: + consider surrogates when reading CMap files + +2020-10-21 Martin Gieseking <martin.gieseking@uos.de> + + * .appveyor.yml: + updated FreeType to version 2.10.4 + +2020-10-10 Martin Gieseking <martin.gieseking@uos.de> + + * .appveyor.yml: + updated FreeType to version 2.10.3 + +2020-09-22 Martin Gieseking <martin.gieseking@uos.de> + + * .appveyor.yml, .travis.yml, configure.ac, doc/dvisvgm.1, src/Doxyfile, + src/version.hpp: + set version to 2.10.1 + + * NEWS: + updated NEWS + +2020-09-11 Martin Gieseking <martin.gieseking@uos.de> + + * src/PSInterpreter.cpp, src/PSInterpreter.hpp, src/PsSpecialHandler.cpp, + src/PsSpecialHandler.hpp, src/psdefs.cpp, tests/PSInterpreterTest.cpp: + added support for new GS transparency operators +.setfillconstantalpha + and .setstrokeconstantalpha + +2020-09-04 Martin Gieseking <martin.gieseking@uos.de> + + * src/XMLNode.cpp: + renamed local variable + +2020-08-27 Martin Gieseking <martin.gieseking@uos.de> + + * libs/brotli/common/version.h: + updated brotli to version 1.0.9 +the encoder is not affected by this + update so the bundled subset +only bumps the version number. + +2020-08-26 Martin Gieseking <martin.gieseking@uos.de> + + * libs/brotli/Makefile.am, libs/brotli/common/constants.c, + libs/brotli/common/constants.h, libs/brotli/common/context.c, + libs/brotli/common/context.h, libs/brotli/common/dictionary.c, + libs/brotli/common/platform.c, libs/brotli/common/platform.h, + libs/brotli/common/transform.c, libs/brotli/common/transform.h, + libs/brotli/common/version.h, libs/brotli/enc/backward_references.c, + libs/brotli/enc/backward_references.h, + libs/brotli/enc/backward_references_hq.c, + libs/brotli/enc/backward_references_hq.h, + libs/brotli/enc/backward_references_inc.h, + libs/brotli/enc/block_splitter.c, libs/brotli/enc/block_splitter_inc.h, + libs/brotli/enc/brotli_bit_stream.c, libs/brotli/enc/cluster_inc.h, + libs/brotli/enc/command.c, libs/brotli/enc/command.h, + libs/brotli/enc/compress_fragment_two_pass.c, + libs/brotli/enc/dictionary_hash.c, libs/brotli/enc/dictionary_hash.h, + libs/brotli/enc/encode.c, libs/brotli/enc/encoder_dict.c, + libs/brotli/enc/encoder_dict.h, libs/brotli/enc/entropy_encode.c, + libs/brotli/enc/entropy_encode.h, libs/brotli/enc/fast_log.c, + libs/brotli/enc/fast_log.h, libs/brotli/enc/find_match_length.h, + libs/brotli/enc/hash.h, libs/brotli/enc/hash_composite_inc.h, + libs/brotli/enc/hash_forgetful_chain_inc.h, + libs/brotli/enc/hash_longest_match64_inc.h, + libs/brotli/enc/hash_longest_match_inc.h, + libs/brotli/enc/hash_longest_match_quickly_inc.h, + libs/brotli/enc/hash_rolling_inc.h, + libs/brotli/enc/hash_to_binary_tree_inc.h, libs/brotli/enc/memory.h, + libs/brotli/enc/metablock.c, libs/brotli/enc/metablock_inc.h, + libs/brotli/enc/params.h, libs/brotli/enc/ringbuffer.h, + libs/brotli/enc/utf8_util.c, libs/brotli/enc/write_bits.h, + libs/brotli/include/brotli/encode.h, libs/brotli/include/brotli/port.h: + updated brotli to version 1.0.8 + +2020-08-23 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.1, doc/dvisvgm.txt.in: + manpage: few additions to --bbox and --font-format + +2020-08-22 Martin Gieseking <martin.gieseking@uos.de> + + * .mailmap: + removed redundant file + +2020-08-21 Martin Gieseking <martin.gieseking@uos.de> + + * src/Ghostscript.cpp: + updated GS versioning scheme introduced with GS + 9.53.0 +http://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=0e98e2a27ed19fcc138215afe17ab1a173aeed7b + +2020-08-12 Martin Gieseking <martin.gieseking@uos.de> + + * .appveyor.yml, .travis.yml, configure.ac, doc/dvisvgm.1, src/Doxyfile, + src/version.hpp: + set version to 2.10 + + * NEWS: + updated NEWS + +2020-07-27 Martin Gieseking <martin.gieseking@uos.de> + + * doc/dvisvgm.1, doc/dvisvgm.txt.in, libs/xxHash/xxh3.h, + libs/xxHash/xxhash.h: + updated xxHash to version 0.8 + +2020-07-24 Martin Gieseking <martin.gieseking@uos.de> + + * src/psdefs.cpp: + redefine internal GS operators .fillstroke and .eofillstroke +They are + used to implement PDF operators B and B*. +(closes #139) + +2020-07-16 Martin Gieseking <martin.gieseking@uos.de> + + * src/optimizer/TransformSimplifier.cpp: + don't unwind transform attributes of image elements + + * src/optimizer/GroupCollapser.cpp: + collapse groups w/o attributes first +in order to recurse into their + descendants. + + * src/optimizer/TransformSimplifier.cpp: + optimizer: unwind transform attributes of image elements +if it consists + only of scaling and translations. Merge the scaled translation +into x and + y, and simplify the remaining matrix(...) expression to scale(...) + +2020-07-15 Martin Gieseking <martin.gieseking@uos.de> + + * src/XMLNode.cpp, src/XMLNode.hpp, src/optimizer/GroupCollapser.cpp, + src/optimizer/RedundantElementRemover.cpp, + src/optimizer/WSNodeRemover.cpp: + renamed XMLNode::remove to XMLNode::detach + +2020-07-14 Martin Gieseking <martin.gieseking@uos.de> + + * src/optimizer/GroupCollapser.cpp: + don't move inner transforms to outer clipping paths + + * src/XMLNode.cpp: + fixed XMLElement::unwrap + + * src/optimizer/GroupCollapser.cpp: + improved optimizer module GroupCollapser + +2020-07-13 Martin Gieseking <martin.gieseking@uos.de> + + * src/optimizer/SVGOptimizer.cpp: + simplify transforms before optimizing groups + + * src/DvisvgmSpecialHandler.cpp: + fixed error message about invalid closing tags + + * src/DVIToSVGActions.cpp: + handle XML parser errors thrown in EOP + + * src/DvisvgmSpecialHandler.cpp, src/DvisvgmSpecialHandler.hpp: + reduced number of successive XML error messages + + * src/DvisvgmSpecialHandler.cpp, src/DvisvgmSpecialHandler.hpp: + renamed XMLParser::flush to XMLParser::finish + +2020-07-07 Martin Gieseking <martin.gieseking@uos.de> + + * src/FontCache.cpp, src/HashFunction.cpp, src/HashFunction.hpp, + src/MD5HashFunction.hpp, src/XXHashFunction.hpp, + tests/HashFunctionTest.cpp: + renamed HashFunction::digestValue() to HashFunction::digestBytes() + + * src/XXHashFunction.hpp: + added XXHashFunction::digestValue() to get the value as encoded by + xxhash + + * src/FileSystem.cpp, src/FileSystem.hpp: + create dedicated temp folders with each call of dvisvgm + +2020-06-25 Martin Gieseking <martin.gieseking@uos.de> + + * libs/xxHash/xxh3.h, libs/xxHash/xxhash.c, libs/xxHash/xxhash.h: + updated xxHash to version 0.7.4 + +2020-06-23 Martin Gieseking <martin.gieseking@uos.de> + + * src/DvisvgmSpecialHandler.cpp, tests/DvisvgmSpecialTest.cpp: + fixed computation of string boundaries after expanding {?(...)} +(closes + #136) + +2020-05-09 Martin Gieseking <martin.gieseking@uos.de> + + * .appveyor.yml: + updated FreeType to version 2.10.2 + +2020-05-03 Martin Gieseking <martin.gieseking@uos.de> + + * src/dvisvgm.cpp: + fixed indentation + +2020-04-24 John Bowman <bowman@ualberta.ca> + + * src/dvisvgm.cpp: + Fix indentation. + +2020-04-23 John Bowman <bowman@ualberta.ca> + + * src/dvisvgm.cpp: + Return error codes to shell. + +2020-04-13 Martin Gieseking <martin.gieseking@uos.de> + + * src/PathClipper.cpp, src/PathClipper.hpp, src/PsSpecialHandler.cpp: + changed signature of PathClipper::intersect() + + * src/PathClipper.cpp, src/PathClipper.hpp: + added unite operation to PathClipper + + * src/GraphicsPath.hpp, src/PsSpecialHandler.cpp: + fixed handling of clippath/eoclip combinations + +2020-04-11 Martin Gieseking <martin.gieseking@uos.de> + + * src/DVIToSVGActions.cpp: + fixed bbox debug rectangles + + * src/Font.cpp, src/Font.hpp: + added italic correction for fake slant + + * src/DVIReader.cpp, src/DVIReader.hpp, src/FontManager.cpp: + added evaluation of LuaTeX native font definitions + + * src/DVIReader.cpp: + minor code improvements + +2020-04-10 Martin Gieseking <martin.gieseking@uos.de> + + * src/psdefs.cpp: + fixed PS operator 'eoclip' + +2020-03-30 Martin Gieseking <martin.gieseking@uos.de> + + * src/optimizer/TransformSimplifier.cpp: + optimizer: fixed omission of second scale() parameter + 2020-03-21 Martin Gieseking <martin.gieseking@uos.de> * src/Matrix.cpp: diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/Makefile.am b/Build/source/texk/dvisvgm/dvisvgm-src/Makefile.am index 09750502864..f8026835a6f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/Makefile.am +++ b/Build/source/texk/dvisvgm/dvisvgm-src/Makefile.am @@ -1,5 +1,5 @@ ## This file is part of dvisvgm -## Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> +## Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ## ## Process this file with automake. diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/NEWS b/Build/source/texk/dvisvgm/dvisvgm-src/NEWS index e898c38bd3d..5c11387cd0b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/NEWS +++ b/Build/source/texk/dvisvgm/dvisvgm-src/NEWS @@ -1,3 +1,41 @@ +dvisvgm-2.11.1 (2021-01-21) +- fixed possible ambiguity of GID to charcode mappings (GH issue #147) +- refactored representation of token objects in calculator class +- few minor code and test improvements + +dvisvgm-2.11 (2020-11-28) +- added fallback mechanism for JFM-based virtual fonts proposed + by Takuji Tanaka (GH issue #144) +- improved detection of proper CMap files for current encoding +- fixed processing of Unicode surrogates present in CMap files +- fixed handling of pdf:mapline and pdf:mapfile specials + +dvisvgm-2.10.1 (2020-09-22) +- added support for new Ghostscript transparency operators + .setfillconstantalpha and .setstrokeconstantalpha +- added support for new Ghostscript versioning scheme introduced with GS 9.53.0 +- added few additional information to the manual page +- updated bundled brotli library to version 1.0.9 + +dvisvgm-2.10 (2020-08-12) +- added evaluation of LuaTeX native font definitions +- added computation of of italic correction for fake slanted glyphs +- dvisvgm now creates dedicated temporary folders for each call of + the program to prevent file collisions between different processes +- added evaluation of internal GS operators '.fillstroke' and '.eofillstroke' + introduced with GS 9.52 to implement PDF operators 'B' and 'B*' + (GH issue #139) +- fixed and improved optimization of nested group elements +- fixed optimization of 'scale' transformation +- fixed optimization of 'transform' attributes applied to images clipping paths +- fixed processing of PS operator 'eoclip' +- fixed processing of clipping path intersections with different + fill rule properties +- fixed processing of {?(...)} expressions (GH issue #136) +- fixed error message about unmatched closing tags in XML parser +- updated bundled FreeType library to version 2.10.2 +- updated bundled xxHash library to version 0.8 + dvisvgm-2.9.1 (2020-03-21) - added macro {?(expr)} to enable the evaluation of math expressions in raw SVG fragments (GH #130) diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/README b/Build/source/texk/dvisvgm/dvisvgm-src/README index f880af15f87..e5a2d98c8ad 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/README +++ b/Build/source/texk/dvisvgm/dvisvgm-src/README @@ -130,7 +130,7 @@ ADDITIONAL INFORMATION COPYRIGHT - Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> + Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/configure.ac b/Build/source/texk/dvisvgm/dvisvgm-src/configure.ac index 783d2709a8d..9437cd5002b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/configure.ac +++ b/Build/source/texk/dvisvgm/dvisvgm-src/configure.ac @@ -1,11 +1,11 @@ # This file is part of dvisvgm -# Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> +# Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> # # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) -AC_INIT([dvisvgm],[2.9.1],[martin.gieseking@uos.de]) -DATE="March 2020" +AC_INIT([dvisvgm],[2.11.1],[martin.gieseking@uos.de]) +DATE="January 2021" AC_CONFIG_SRCDIR(src) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/doc/Makefile.am b/Build/source/texk/dvisvgm/dvisvgm-src/doc/Makefile.am index 92c7d25efd7..dfdc0483b21 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/doc/Makefile.am +++ b/Build/source/texk/dvisvgm/dvisvgm-src/doc/Makefile.am @@ -1,5 +1,5 @@ ## This file is part of dvisvgm -## Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> +## Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ## ## Process this file with automake. diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/doc/Makefile.in b/Build/source/texk/dvisvgm/dvisvgm-src/doc/Makefile.in index 8568648c65a..8efa4e75542 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/doc/Makefile.in +++ b/Build/source/texk/dvisvgm/dvisvgm-src/doc/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.2 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/doc/conf-dblatex-man.xsl b/Build/source/texk/dvisvgm/dvisvgm-src/doc/conf-dblatex-man.xsl index 2e52f9e96f8..a42a9293600 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/doc/conf-dblatex-man.xsl +++ b/Build/source/texk/dvisvgm/dvisvgm-src/doc/conf-dblatex-man.xsl @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- This file is part of dvisvgm --> -<!-- Copyright (C) 2015-2020 Martin Gieseking <martin.gieseking@uos.de> --> +<!-- Copyright (C) 2015-2021 Martin Gieseking <martin.gieseking@uos.de> --> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <!-- output monospaced text in bold --> <xsl:template match="literal"> diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/doc/conf-dblatex-pdf.xsl b/Build/source/texk/dvisvgm/dvisvgm-src/doc/conf-dblatex-pdf.xsl index bb3bd93b632..dd676ef67b0 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/doc/conf-dblatex-pdf.xsl +++ b/Build/source/texk/dvisvgm/dvisvgm-src/doc/conf-dblatex-pdf.xsl @@ -1,6 +1,6 @@ <?xml version='1.0' encoding="iso-8859-1"?> <!-- This file is part of dvisvgm --> -<!-- Copyright (C) 2015-2020 Martin Gieseking <martin.gieseking@uos.de> --> +<!-- Copyright (C) 2015-2021 Martin Gieseking <martin.gieseking@uos.de> --> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:param name="xetex.font"> <xsl:text>\setmainfont{Source Serif Pro} </xsl:text> diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1 b/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1 index 67cc037d26d..ba8b102cc9c 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1 +++ b/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.1 @@ -2,12 +2,12 @@ .\" Title: dvisvgm .\" Author: Martin Gieseking <martin.gieseking@uos.de> .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/> -.\" Date: 2020-03-19 +.\" Date: 2021-01-03 .\" Manual: dvisvgm Manual -.\" Source: dvisvgm 2.9.1 +.\" Source: dvisvgm 2.11.1 .\" Language: English .\" -.TH "DVISVGM" "1" "2020\-03\-19" "dvisvgm 2\&.9\&.1" "dvisvgm Manual" +.TH "DVISVGM" "1" "2021\-01\-03" "dvisvgm 2\&.11\&.1" "dvisvgm Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -46,7 +46,7 @@ SVG is a vector\-based graphics format and therefore dvisvgm tries to convert th .sp However, TeX\(cqs main source for font descriptions is Metafont, which produces bitmap output (GF files)\&. That\(cqs why not all obtainable TeX fonts are available in a scalable format\&. In these cases, dvisvgm tries to vectorize Metafont\(cqs output by tracing the glyph bitmaps\&. The results are not as perfect as most (manually optimized) PFB or OTF counterparts, but are nonetheless really nice in most cases\&. .sp -When running dvisvgm without option \fB\-\-no\-fonts\fR, it creates \fIfont\fR elements (\fB<font>\fR\&...\fB</font>\fR) to embed the font data into the SVG files\&. Unfortunately, only few SVG renderers support these elements yet\&. Most web browsers and vector graphics applications don\(cqt evaluate them properly so that the text components of the resulting graphics might look strange\&. In order to create more compatible SVG files, command\-line option \fB\-\-no\-fonts\fR can be given to replace the font elements by plain graphics paths\&. Most web browsers (but only few external SVG renderers) also suppport WOFF and WOFF2 fonts that can be used instead of the default SVG fonts\&. Option \fB\-\-font\-format\fR offers the functionality to change the format applied to the fonts being embedded\&. +When running dvisvgm without option \fB\-\-no\-fonts\fR, it creates \fIfont\fR elements (\fB<font>\fR\&...\fB</font>\fR) to embed the font data into the SVG files\&. Unfortunately, only few SVG renderers support these elements yet\&. Most web browsers and vector graphics applications don\(cqt evaluate them properly so that the text components of the resulting graphics might look strange\&. In order to create more compatible SVG files, command\-line option \fB\-\-no\-fonts\fR can be given to replace the font elements by plain graphics paths\&. Most web browsers (but only few external SVG renderers) also suppport WOFF and WOFF2 fonts that can be used instead of the default SVG fonts\&. Option \fB\-\-font\-format\fR offers the functionality to change the format applied to the fonts being embedded\&. This, however, only works when converting DVI files\&. Text present in PDF and PostScript files is always converted to path elements\&. .SH "OPTIONS" .sp dvisvgm provides a POSIX\-compliant command\-line interface with short and long option names\&. They may be given before and/or after the name of the file to be converted\&. Also, the order of specifying the options is not significant, i\&.e\&. you can add them in any order without changing dvisvgm\(cqs behavior\&. Certain options accept or require additional parameters which are directly appended to or separated by whitespace from a short option (e\&.g\&. \fB\-v0\fR or \fB\-v 0\fR)\&. Long options require an additional equals sign (\fB=\fR) between option name and argument but without any surrounding whitespace (e\&.g\&. \fB\-\-verbosity=0\fR)\&. Multiple short options that don\(cqt expect a further parameter can be combined after a single dash (e\&.g\&. \fB\-ejs\fR rather than \fB\-e \-j \-s\fR)\&. @@ -55,7 +55,9 @@ Long option names may also be shortened by omitting trailing characters\&. As lo .PP \fB\-b, \-\-bbox\fR=\fIfmt\fR .RS 4 -Sets the bounding box of the generated graphic to the specified format\&. The parameter +Sets the bounding box of the generated SVG graphic to the specified format\&. This option only affects the conversion of DVI files\&. SVG documents generated from PDF and PostScript always inherit the bounding boxes of the input files\&. +.sp +Parameter \fIfmt\fR takes either one of the format specifiers listed below, or a sequence of four comma\- or whitespace\-separated length values \fIx1\fR, @@ -315,7 +317,9 @@ given, dvisvgm analyzes the actual shape of each character and derives a usually .PP \fB\-f, \-\-font\-format\fR=\fIformat\fR .RS 4 -Selects the file format used to embed the font data into the SVG files\&. Following formats are supported: +Selects the file format used to embed font data into the generated SVG output when converting DVI files\&. It has no effect when converting PDF or PostScript files\&. Text fragments present in these files are always converted to path elements\&. +.sp +Following formats are supported: \fBSVG\fR (that\(cqs the default), \fBTTF\fR @@ -775,7 +779,7 @@ of option \fBMD5\fR, \fBXXH32\fR, and \fBXXH64\fR, where the names can be given in lower case too, like -\fB\-\-page\-hashes=md5\fR\&. Since version 0\&.7\&.1, xxHash provides an experimental 128\-bit hash function, whose algorithm may still change with the next versions of the library\&. If the corresponding API is available, dvisvgm supports the new hash function and option +\fB\-\-page\-hashes=md5\fR\&. Since version 0\&.7\&.1, xxHash provides an experimental 128\-bit hash function whose algorithm has been stabilized as of version 0\&.8\&. When using a version prior to 0\&.8, the 128\-bit hash values can vary depending on the used xxHash version\&. If the corresponding API is available, dvisvgm supports the new hash function, and option \fB\-\-page\-hashes\fR additionally accepts the algorithm specifier \fBXXH128\fR\&. @@ -1688,4 +1692,4 @@ Please report bugs using the bug tracker at GitHub (\m[blue]https://github.com/m Written by Martin Gieseking <\m[blue]\fBmartin\&.gieseking@uos\&.de\fR\m[]> .SH "COPYING" .sp -Copyright \(co 2005\-2020 Martin Gieseking\&. Free use of this software is granted under the terms of the GNU General Public License (GPL) version 3 or, (at your option) any later version\&. +Copyright \(co 2005\-2021 Martin Gieseking\&. Free use of this software is granted under the terms of the GNU General Public License (GPL) version 3 or, (at your option) any later version\&. diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.txt.in b/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.txt.in index 2b51b57c32d..739f6e5c16d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.txt.in +++ b/Build/source/texk/dvisvgm/dvisvgm-src/doc/dvisvgm.txt.in @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////// // This file is part of dvisvgm -- a fast DVI to SVG converter // -// Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> // +// Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> // // // // This program is free software; you can redistribute it and/or // // modify it under the terms of the GNU General Public License as // @@ -22,7 +22,7 @@ Martin Gieseking <@PACKAGE_BUGREPORT@> :man source: dvisvgm :man version: @VERSION@ :man manual: dvisvgm Manual -:revdate: 2020-03-19 22:06 +0100 +:revdate: 2021-01-03 19:25 +0100 Name ---- @@ -71,7 +71,9 @@ that the text components of the resulting graphics might look strange. In order compatible SVG files, command-line option *--no-fonts* can be given to replace the font elements by plain graphics paths. Most web browsers (but only few external SVG renderers) also suppport WOFF and WOFF2 fonts that can be used instead of the default SVG fonts. Option *--font-format* -offers the functionality to change the format applied to the fonts being embedded. +offers the functionality to change the format applied to the fonts being embedded. This, however, +only works when converting DVI files. Text present in PDF and PostScript files is always +converted to path elements. Options @@ -91,9 +93,12 @@ to +--exact+, +--exa+, or +--ex+. In case of an ambiguous abbreviation, dvisvgm message together with all matching option names. *-b, --bbox*='fmt':: -Sets the bounding box of the generated graphic to the specified format. The parameter 'fmt' -takes either one of the format specifiers listed below, or a sequence of four comma- or -whitespace-separated length values 'x1', 'y1', 'x2' and 'y2'. The latter define the absolute +Sets the bounding box of the generated SVG graphic to the specified format. This option only affects +the conversion of DVI files. SVG documents generated from PDF and PostScript always inherit the +bounding boxes of the input files. ++ +Parameter 'fmt' takes either one of the format specifiers listed below, or a sequence of four comma- +or whitespace-separated length values 'x1', 'y1', 'x2' and 'y2'. The latter define the absolute coordinates of two diagonal corners of the bounding box. Each length value consists of a floating point number and an optional length unit (pt, bp, cm, mm, in, pc, dd, cc, or sp). If the unit is omitted, TeX points (pt) are assumed. @@ -218,9 +223,12 @@ this can lead to clipped characters at the bounds of the SVG graphics. With opti given, dvisvgm analyzes the actual shape of each character and derives a usually tight bounding box. *-f, --font-format*='format':: -Selects the file format used to embed the font data into the SVG files. Following formats are -supported: +SVG+ (that's the default), +TTF+ (TrueType), +WOFF+, and +WOFF2+ (Web Open Font Format -version 1 and 2). +Selects the file format used to embed font data into the generated SVG output when converting DVI +files. It has no effect when converting PDF or PostScript files. Text fragments present in these +files are always converted to path elements. ++ +Following formats are supported: +SVG+ (that's the default), +TTF+ (TrueType), +WOFF+, and +WOFF2+ +(Web Open Font Format version 1 and 2). By default, dvisvgm creates unhinted fonts that might look bad on low-resolution devices. In order to improve the display quality, the generated TrueType, WOFF, or WOFF2 fonts can be autohinted. The autohinter is enabled by appending +,autohint+ or +,ah+ to the font format, @@ -518,9 +526,10 @@ By default, dvisvgm uses the fast XXH64 hash algorithm to compute the values pro XXH32 and MD5 can be used as well. The desired algorithm is specified by argument 'params' of option *--page-hashes*. It takes one of the strings +MD5+, +XXH32+, and +XXH64+, where the names can be given in lower case too, like +--page-hashes=md5+. Since version 0.7.1, xxHash provides an experimental 128-bit -hash function, whose algorithm may still change with the next versions of the library. If the -corresponding API is available, dvisvgm supports the new hash function and option *--page-hashes* -additionally accepts the algorithm specifier +XXH128+. +hash function whose algorithm has been stabilized as of version 0.8. When using a version prior to 0.8, +the 128-bit hash values can vary depending on the used xxHash version. If the corresponding API is +available, dvisvgm supports the new hash function, and option *--page-hashes* additionally accepts the +algorithm specifier +XXH128+. + Finally, option *--page-hashes* can take a second argument that must be separated by a comma. Currently, only the two parameters 'list' and 'replace' are evaluated, e.g. +--page-hashes=md5,list+ @@ -992,7 +1001,7 @@ Written by {author} <{email}> Copying ------- -Copyright (C) 2005-2020 Martin Gieseking. Free use of this software is +Copyright (C) 2005-2021 Martin Gieseking. Free use of this software is granted under the terms of the GNU General Public License (GPL) version 3 or, (at your option) any later version. diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/doc/tweak-db-refentry.xsl b/Build/source/texk/dvisvgm/dvisvgm-src/doc/tweak-db-refentry.xsl index 1750d7a4f7c..fc77008ed1e 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/doc/tweak-db-refentry.xsl +++ b/Build/source/texk/dvisvgm/dvisvgm-src/doc/tweak-db-refentry.xsl @@ -1,6 +1,6 @@ <?xml version="1.0"?> <!-- This file is part of dvisvgm --> -<!-- Copyright (C) 2015-2020 Martin Gieseking <martin.gieseking@uos.de> --> +<!-- Copyright (C) 2015-2021 Martin Gieseking <martin.gieseking@uos.de> --> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:date="http://exslt.org/dates-and-times" diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/doc/tweak-dblatex-pdf.xsl b/Build/source/texk/dvisvgm/dvisvgm-src/doc/tweak-dblatex-pdf.xsl index d1762adecba..d4e3c8b0c1f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/doc/tweak-dblatex-pdf.xsl +++ b/Build/source/texk/dvisvgm/dvisvgm-src/doc/tweak-dblatex-pdf.xsl @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- This file is part of dvisvgm --> -<!-- Copyright (C) 2015-2020 Martin Gieseking <martin.gieseking@uos.de> --> +<!-- Copyright (C) 2015-2021 Martin Gieseking <martin.gieseking@uos.de> --> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output doctype-public="-//OASIS//DTD DocBook XML V4.5//EN" doctype-system="http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"/> diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/Makefile.am b/Build/source/texk/dvisvgm/dvisvgm-src/libs/Makefile.am index 6b6e0433e46..e756a6be097 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/Makefile.am +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/Makefile.am @@ -1,5 +1,5 @@ ## This file is part of dvisvgm -## Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> +## Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ## ## Process this file with automake. diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/Makefile.am b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/Makefile.am index 1c3336c48e2..7e8eae7d3d1 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/Makefile.am +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/Makefile.am @@ -1,10 +1,13 @@ if !HAVE_BROTLI noinst_LIBRARIES = libbrotli.a libbrotli_a_SOURCES = \ + common/constants.c \ common/constants.h \ + common/context.c \ common/context.h \ common/dictionary.c \ common/dictionary.h \ + common/platform.c \ common/platform.h \ common/transform.c \ common/transform.h \ @@ -26,6 +29,7 @@ libbrotli_a_SOURCES = \ enc/cluster.c \ enc/cluster.h \ enc/cluster_inc.h \ + enc/command.c \ enc/command.h \ enc/compress_fragment.c \ enc/compress_fragment.h \ @@ -39,6 +43,7 @@ libbrotli_a_SOURCES = \ enc/entropy_encode.c \ enc/entropy_encode.h \ enc/entropy_encode_static.h \ + enc/fast_log.c \ enc/fast_log.h \ enc/find_match_length.h \ enc/hash_composite_inc.h \ diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/Makefile.in b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/Makefile.in index fd9ea2f425a..61d3155453f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/Makefile.in +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/Makefile.in @@ -119,8 +119,9 @@ am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libbrotli_a_AR = $(AR) $(ARFLAGS) libbrotli_a_LIBADD = -am__libbrotli_a_SOURCES_DIST = common/constants.h common/context.h \ - common/dictionary.c common/dictionary.h common/platform.h \ +am__libbrotli_a_SOURCES_DIST = common/constants.c common/constants.h \ + common/context.c common/context.h common/dictionary.c \ + common/dictionary.h common/platform.c common/platform.h \ common/transform.c common/transform.h common/version.h \ enc/backward_references.c enc/backward_references.h \ enc/backward_references_hq.c enc/backward_references_hq.h \ @@ -129,12 +130,13 @@ am__libbrotli_a_SOURCES_DIST = common/constants.h common/context.h \ enc/block_splitter.c enc/block_splitter.h \ enc/block_splitter_inc.h enc/brotli_bit_stream.c \ enc/brotli_bit_stream.h enc/cluster.c enc/cluster.h \ - enc/cluster_inc.h enc/command.h enc/compress_fragment.c \ - enc/compress_fragment.h enc/compress_fragment_two_pass.c \ + enc/cluster_inc.h enc/command.c enc/command.h \ + enc/compress_fragment.c enc/compress_fragment.h \ + enc/compress_fragment_two_pass.c \ enc/compress_fragment_two_pass.h enc/dictionary_hash.c \ enc/dictionary_hash.h enc/encode.c enc/encoder_dict.c \ enc/encoder_dict.h enc/entropy_encode.c enc/entropy_encode.h \ - enc/entropy_encode_static.h enc/fast_log.h \ + enc/entropy_encode_static.h enc/fast_log.c enc/fast_log.h \ enc/find_match_length.h enc/hash_composite_inc.h \ enc/hash_forgetful_chain_inc.h enc/hash.h \ enc/hash_longest_match64_inc.h enc/hash_longest_match_inc.h \ @@ -150,20 +152,24 @@ am__libbrotli_a_SOURCES_DIST = common/constants.h common/context.h \ include/brotli/types.h am__dirstamp = $(am__leading_dot)dirstamp @HAVE_BROTLI_FALSE@am_libbrotli_a_OBJECTS = \ +@HAVE_BROTLI_FALSE@ common/constants.$(OBJEXT) \ +@HAVE_BROTLI_FALSE@ common/context.$(OBJEXT) \ @HAVE_BROTLI_FALSE@ common/dictionary.$(OBJEXT) \ +@HAVE_BROTLI_FALSE@ common/platform.$(OBJEXT) \ @HAVE_BROTLI_FALSE@ common/transform.$(OBJEXT) \ @HAVE_BROTLI_FALSE@ enc/backward_references.$(OBJEXT) \ @HAVE_BROTLI_FALSE@ enc/backward_references_hq.$(OBJEXT) \ @HAVE_BROTLI_FALSE@ enc/bit_cost.$(OBJEXT) \ @HAVE_BROTLI_FALSE@ enc/block_splitter.$(OBJEXT) \ @HAVE_BROTLI_FALSE@ enc/brotli_bit_stream.$(OBJEXT) \ -@HAVE_BROTLI_FALSE@ enc/cluster.$(OBJEXT) \ +@HAVE_BROTLI_FALSE@ enc/cluster.$(OBJEXT) enc/command.$(OBJEXT) \ @HAVE_BROTLI_FALSE@ enc/compress_fragment.$(OBJEXT) \ @HAVE_BROTLI_FALSE@ enc/compress_fragment_two_pass.$(OBJEXT) \ @HAVE_BROTLI_FALSE@ enc/dictionary_hash.$(OBJEXT) \ @HAVE_BROTLI_FALSE@ enc/encode.$(OBJEXT) \ @HAVE_BROTLI_FALSE@ enc/encoder_dict.$(OBJEXT) \ @HAVE_BROTLI_FALSE@ enc/entropy_encode.$(OBJEXT) \ +@HAVE_BROTLI_FALSE@ enc/fast_log.$(OBJEXT) \ @HAVE_BROTLI_FALSE@ enc/histogram.$(OBJEXT) \ @HAVE_BROTLI_FALSE@ enc/literal_cost.$(OBJEXT) \ @HAVE_BROTLI_FALSE@ enc/memory.$(OBJEXT) \ @@ -186,19 +192,21 @@ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/../../build-aux/depcomp am__maybe_remake_depfiles = depfiles -am__depfiles_remade = common/$(DEPDIR)/dictionary.Po \ - common/$(DEPDIR)/transform.Po \ +am__depfiles_remade = common/$(DEPDIR)/constants.Po \ + common/$(DEPDIR)/context.Po common/$(DEPDIR)/dictionary.Po \ + common/$(DEPDIR)/platform.Po common/$(DEPDIR)/transform.Po \ enc/$(DEPDIR)/backward_references.Po \ enc/$(DEPDIR)/backward_references_hq.Po \ enc/$(DEPDIR)/bit_cost.Po enc/$(DEPDIR)/block_splitter.Po \ enc/$(DEPDIR)/brotli_bit_stream.Po enc/$(DEPDIR)/cluster.Po \ - enc/$(DEPDIR)/compress_fragment.Po \ + enc/$(DEPDIR)/command.Po enc/$(DEPDIR)/compress_fragment.Po \ enc/$(DEPDIR)/compress_fragment_two_pass.Po \ enc/$(DEPDIR)/dictionary_hash.Po enc/$(DEPDIR)/encode.Po \ enc/$(DEPDIR)/encoder_dict.Po enc/$(DEPDIR)/entropy_encode.Po \ - enc/$(DEPDIR)/histogram.Po enc/$(DEPDIR)/literal_cost.Po \ - enc/$(DEPDIR)/memory.Po enc/$(DEPDIR)/metablock.Po \ - enc/$(DEPDIR)/static_dict.Po enc/$(DEPDIR)/utf8_util.Po + enc/$(DEPDIR)/fast_log.Po enc/$(DEPDIR)/histogram.Po \ + enc/$(DEPDIR)/literal_cost.Po enc/$(DEPDIR)/memory.Po \ + enc/$(DEPDIR)/metablock.Po enc/$(DEPDIR)/static_dict.Po \ + enc/$(DEPDIR)/utf8_util.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -402,10 +410,13 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @HAVE_BROTLI_FALSE@noinst_LIBRARIES = libbrotli.a @HAVE_BROTLI_FALSE@libbrotli_a_SOURCES = \ +@HAVE_BROTLI_FALSE@ common/constants.c \ @HAVE_BROTLI_FALSE@ common/constants.h \ +@HAVE_BROTLI_FALSE@ common/context.c \ @HAVE_BROTLI_FALSE@ common/context.h \ @HAVE_BROTLI_FALSE@ common/dictionary.c \ @HAVE_BROTLI_FALSE@ common/dictionary.h \ +@HAVE_BROTLI_FALSE@ common/platform.c \ @HAVE_BROTLI_FALSE@ common/platform.h \ @HAVE_BROTLI_FALSE@ common/transform.c \ @HAVE_BROTLI_FALSE@ common/transform.h \ @@ -427,6 +438,7 @@ top_srcdir = @top_srcdir@ @HAVE_BROTLI_FALSE@ enc/cluster.c \ @HAVE_BROTLI_FALSE@ enc/cluster.h \ @HAVE_BROTLI_FALSE@ enc/cluster_inc.h \ +@HAVE_BROTLI_FALSE@ enc/command.c \ @HAVE_BROTLI_FALSE@ enc/command.h \ @HAVE_BROTLI_FALSE@ enc/compress_fragment.c \ @HAVE_BROTLI_FALSE@ enc/compress_fragment.h \ @@ -440,6 +452,7 @@ top_srcdir = @top_srcdir@ @HAVE_BROTLI_FALSE@ enc/entropy_encode.c \ @HAVE_BROTLI_FALSE@ enc/entropy_encode.h \ @HAVE_BROTLI_FALSE@ enc/entropy_encode_static.h \ +@HAVE_BROTLI_FALSE@ enc/fast_log.c \ @HAVE_BROTLI_FALSE@ enc/fast_log.h \ @HAVE_BROTLI_FALSE@ enc/find_match_length.h \ @HAVE_BROTLI_FALSE@ enc/hash_composite_inc.h \ @@ -520,8 +533,14 @@ common/$(am__dirstamp): common/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) common/$(DEPDIR) @: > common/$(DEPDIR)/$(am__dirstamp) +common/constants.$(OBJEXT): common/$(am__dirstamp) \ + common/$(DEPDIR)/$(am__dirstamp) +common/context.$(OBJEXT): common/$(am__dirstamp) \ + common/$(DEPDIR)/$(am__dirstamp) common/dictionary.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) +common/platform.$(OBJEXT): common/$(am__dirstamp) \ + common/$(DEPDIR)/$(am__dirstamp) common/transform.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) enc/$(am__dirstamp): @@ -542,6 +561,8 @@ enc/brotli_bit_stream.$(OBJEXT): enc/$(am__dirstamp) \ enc/$(DEPDIR)/$(am__dirstamp) enc/cluster.$(OBJEXT): enc/$(am__dirstamp) \ enc/$(DEPDIR)/$(am__dirstamp) +enc/command.$(OBJEXT): enc/$(am__dirstamp) \ + enc/$(DEPDIR)/$(am__dirstamp) enc/compress_fragment.$(OBJEXT): enc/$(am__dirstamp) \ enc/$(DEPDIR)/$(am__dirstamp) enc/compress_fragment_two_pass.$(OBJEXT): enc/$(am__dirstamp) \ @@ -554,6 +575,8 @@ enc/encoder_dict.$(OBJEXT): enc/$(am__dirstamp) \ enc/$(DEPDIR)/$(am__dirstamp) enc/entropy_encode.$(OBJEXT): enc/$(am__dirstamp) \ enc/$(DEPDIR)/$(am__dirstamp) +enc/fast_log.$(OBJEXT): enc/$(am__dirstamp) \ + enc/$(DEPDIR)/$(am__dirstamp) enc/histogram.$(OBJEXT): enc/$(am__dirstamp) \ enc/$(DEPDIR)/$(am__dirstamp) enc/literal_cost.$(OBJEXT): enc/$(am__dirstamp) \ @@ -580,7 +603,10 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/constants.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/context.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/dictionary.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/platform.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/transform.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@enc/$(DEPDIR)/backward_references.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@enc/$(DEPDIR)/backward_references_hq.Po@am__quote@ # am--include-marker @@ -588,12 +614,14 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@enc/$(DEPDIR)/block_splitter.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@enc/$(DEPDIR)/brotli_bit_stream.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@enc/$(DEPDIR)/cluster.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@enc/$(DEPDIR)/command.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@enc/$(DEPDIR)/compress_fragment.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@enc/$(DEPDIR)/compress_fragment_two_pass.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@enc/$(DEPDIR)/dictionary_hash.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@enc/$(DEPDIR)/encode.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@enc/$(DEPDIR)/encoder_dict.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@enc/$(DEPDIR)/entropy_encode.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@enc/$(DEPDIR)/fast_log.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@enc/$(DEPDIR)/histogram.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@enc/$(DEPDIR)/literal_cost.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@enc/$(DEPDIR)/memory.Po@am__quote@ # am--include-marker @@ -767,7 +795,10 @@ clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ mostlyclean-am distclean: distclean-am - -rm -f common/$(DEPDIR)/dictionary.Po + -rm -f common/$(DEPDIR)/constants.Po + -rm -f common/$(DEPDIR)/context.Po + -rm -f common/$(DEPDIR)/dictionary.Po + -rm -f common/$(DEPDIR)/platform.Po -rm -f common/$(DEPDIR)/transform.Po -rm -f enc/$(DEPDIR)/backward_references.Po -rm -f enc/$(DEPDIR)/backward_references_hq.Po @@ -775,12 +806,14 @@ distclean: distclean-am -rm -f enc/$(DEPDIR)/block_splitter.Po -rm -f enc/$(DEPDIR)/brotli_bit_stream.Po -rm -f enc/$(DEPDIR)/cluster.Po + -rm -f enc/$(DEPDIR)/command.Po -rm -f enc/$(DEPDIR)/compress_fragment.Po -rm -f enc/$(DEPDIR)/compress_fragment_two_pass.Po -rm -f enc/$(DEPDIR)/dictionary_hash.Po -rm -f enc/$(DEPDIR)/encode.Po -rm -f enc/$(DEPDIR)/encoder_dict.Po -rm -f enc/$(DEPDIR)/entropy_encode.Po + -rm -f enc/$(DEPDIR)/fast_log.Po -rm -f enc/$(DEPDIR)/histogram.Po -rm -f enc/$(DEPDIR)/literal_cost.Po -rm -f enc/$(DEPDIR)/memory.Po @@ -832,7 +865,10 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f common/$(DEPDIR)/dictionary.Po + -rm -f common/$(DEPDIR)/constants.Po + -rm -f common/$(DEPDIR)/context.Po + -rm -f common/$(DEPDIR)/dictionary.Po + -rm -f common/$(DEPDIR)/platform.Po -rm -f common/$(DEPDIR)/transform.Po -rm -f enc/$(DEPDIR)/backward_references.Po -rm -f enc/$(DEPDIR)/backward_references_hq.Po @@ -840,12 +876,14 @@ maintainer-clean: maintainer-clean-am -rm -f enc/$(DEPDIR)/block_splitter.Po -rm -f enc/$(DEPDIR)/brotli_bit_stream.Po -rm -f enc/$(DEPDIR)/cluster.Po + -rm -f enc/$(DEPDIR)/command.Po -rm -f enc/$(DEPDIR)/compress_fragment.Po -rm -f enc/$(DEPDIR)/compress_fragment_two_pass.Po -rm -f enc/$(DEPDIR)/dictionary_hash.Po -rm -f enc/$(DEPDIR)/encode.Po -rm -f enc/$(DEPDIR)/encoder_dict.Po -rm -f enc/$(DEPDIR)/entropy_encode.Po + -rm -f enc/$(DEPDIR)/fast_log.Po -rm -f enc/$(DEPDIR)/histogram.Po -rm -f enc/$(DEPDIR)/literal_cost.Po -rm -f enc/$(DEPDIR)/memory.Po diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/constants.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/constants.h index d1b88d12af3..e848195a0dc 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/constants.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/constants.h @@ -4,9 +4,18 @@ See file LICENSE for detail or copy at https://opensource.org/licenses/MIT */ +/** + * @file + * Common constants used in decoder and encoder API. + */ + #ifndef BROTLI_COMMON_CONSTANTS_H_ #define BROTLI_COMMON_CONSTANTS_H_ +#include "./platform.h" +#include <brotli/port.h> +#include <brotli/types.h> + /* Specification: 7.3. Encoding of the context map */ #define BROTLI_CONTEXT_MAP_MAX_RLE 16 @@ -29,12 +38,31 @@ #define BROTLI_INITIAL_REPEATED_CODE_LENGTH 8 /* "Large Window Brotli" */ + +/** + * The theoretical maximum number of distance bits specified for large window + * brotli, for 64-bit encoders and decoders. Even when in practice 32-bit + * encoders and decoders only support up to 30 max distance bits, the value is + * set to 62 because it affects the large window brotli file format. + * Specifically, it affects the encoding of simple huffman tree for distances, + * see Specification RFC 7932 chapter 3.4. + */ #define BROTLI_LARGE_MAX_DISTANCE_BITS 62U #define BROTLI_LARGE_MIN_WBITS 10 +/** + * The maximum supported large brotli window bits by the encoder and decoder. + * Large window brotli allows up to 62 bits, however the current encoder and + * decoder, designed for 32-bit integers, only support up to 30 bits maximum. + */ #define BROTLI_LARGE_MAX_WBITS 30 /* Specification: 4. Encoding of distances */ #define BROTLI_NUM_DISTANCE_SHORT_CODES 16 +/** + * Maximal number of "postfix" bits. + * + * Number of "postfix" bits is stored as 2 bits in meta-block header. + */ #define BROTLI_MAX_NPOSTFIX 3 #define BROTLI_MAX_NDIRECT 120 #define BROTLI_MAX_DISTANCE_BITS 24U @@ -45,9 +73,22 @@ #define BROTLI_NUM_DISTANCE_SYMBOLS \ BROTLI_DISTANCE_ALPHABET_SIZE( \ BROTLI_MAX_NDIRECT, BROTLI_MAX_NPOSTFIX, BROTLI_LARGE_MAX_DISTANCE_BITS) + +/* ((1 << 26) - 4) is the maximal distance that can be expressed in RFC 7932 + brotli stream using NPOSTFIX = 0 and NDIRECT = 0. With other NPOSTFIX and + NDIRECT values distances up to ((1 << 29) + 88) could be expressed. */ #define BROTLI_MAX_DISTANCE 0x3FFFFFC + +/* ((1 << 31) - 4) is the safe distance limit. Using this number as a limit + allows safe distance calculation without overflows, given the distance + alphabet size is limited to corresponding size + (see kLargeWindowDistanceCodeLimits). */ #define BROTLI_MAX_ALLOWED_DISTANCE 0x7FFFFFFC + +/* Specification: 4. Encoding of Literal Insertion Lengths and Copy Lengths */ +#define BROTLI_NUM_INS_COPY_CODES 24 + /* 7.1. Context modes and context ID lookup for literals */ /* "context IDs for literals are in the range of 0..63" */ #define BROTLI_LITERAL_CONTEXT_BITS 6 @@ -61,4 +102,99 @@ #define BROTLI_WINDOW_GAP 16 #define BROTLI_MAX_BACKWARD_LIMIT(W) (((size_t)1 << (W)) - BROTLI_WINDOW_GAP) +typedef struct BrotliDistanceCodeLimit { + uint32_t max_alphabet_size; + uint32_t max_distance; +} BrotliDistanceCodeLimit; + +/* This function calculates maximal size of distance alphabet, such that the + distances greater than the given values can not be represented. + + This limits are designed to support fast and safe 32-bit decoders. + "32-bit" means that signed integer values up to ((1 << 31) - 1) could be + safely expressed. + + Brotli distance alphabet symbols do not represent consecutive distance + ranges. Each distance alphabet symbol (excluding direct distances and short + codes), represent interleaved (for NPOSTFIX > 0) range of distances. + A "group" of consecutive (1 << NPOSTFIX) symbols represent non-interleaved + range. Two consecutive groups require the same amount of "extra bits". + + It is important that distance alphabet represents complete "groups". + To avoid complex logic on encoder side about interleaved ranges + it was decided to restrict both sides to complete distance code "groups". + */ +BROTLI_UNUSED_FUNCTION BrotliDistanceCodeLimit BrotliCalculateDistanceCodeLimit( + uint32_t max_distance, uint32_t npostfix, uint32_t ndirect) { + BrotliDistanceCodeLimit result; + /* Marking this function as unused, because not all files + including "constants.h" use it -> compiler warns about that. */ + BROTLI_UNUSED(&BrotliCalculateDistanceCodeLimit); + if (max_distance <= ndirect) { + /* This case never happens / exists only for the sake of completeness. */ + result.max_alphabet_size = max_distance + BROTLI_NUM_DISTANCE_SHORT_CODES; + result.max_distance = max_distance; + return result; + } else { + /* The first prohibited value. */ + uint32_t forbidden_distance = max_distance + 1; + /* Subtract "directly" encoded region. */ + uint32_t offset = forbidden_distance - ndirect - 1; + uint32_t ndistbits = 0; + uint32_t tmp; + uint32_t half; + uint32_t group; + /* Postfix for the last dcode in the group. */ + uint32_t postfix = (1u << npostfix) - 1; + uint32_t extra; + uint32_t start; + /* Remove postfix and "head-start". */ + offset = (offset >> npostfix) + 4; + /* Calculate the number of distance bits. */ + tmp = offset / 2; + /* Poor-man's log2floor, to avoid extra dependencies. */ + while (tmp != 0) {ndistbits++; tmp = tmp >> 1;} + /* One bit is covered with subrange addressing ("half"). */ + ndistbits--; + /* Find subrange. */ + half = (offset >> ndistbits) & 1; + /* Calculate the "group" part of dcode. */ + group = ((ndistbits - 1) << 1) | half; + /* Calculated "group" covers the prohibited distance value. */ + if (group == 0) { + /* This case is added for correctness; does not occur for limit > 128. */ + result.max_alphabet_size = ndirect + BROTLI_NUM_DISTANCE_SHORT_CODES; + result.max_distance = ndirect; + return result; + } + /* Decrement "group", so it is the last permitted "group". */ + group--; + /* After group was decremented, ndistbits and half must be recalculated. */ + ndistbits = (group >> 1) + 1; + /* The last available distance in the subrange has all extra bits set. */ + extra = (1u << ndistbits) - 1; + /* Calculate region start. NB: ndistbits >= 1. */ + start = (1u << (ndistbits + 1)) - 4; + /* Move to subregion. */ + start += (group & 1) << ndistbits; + /* Calculate the alphabet size. */ + result.max_alphabet_size = ((group << npostfix) | postfix) + ndirect + + BROTLI_NUM_DISTANCE_SHORT_CODES + 1; + /* Calculate the maximal distance representable by alphabet. */ + result.max_distance = ((start + extra) << npostfix) + postfix + ndirect + 1; + return result; + } +} + +/* Represents the range of values belonging to a prefix code: + [offset, offset + 2^nbits) */ +typedef struct { + uint16_t offset; + uint8_t nbits; +} BrotliPrefixCodeRange; + +/* "Soft-private", it is exported, but not "advertised" as API. */ +BROTLI_COMMON_API extern const BrotliPrefixCodeRange + _kBrotliPrefixCodeRanges[BROTLI_NUM_BLOCK_LEN_SYMBOLS]; + #endif /* BROTLI_COMMON_CONSTANTS_H_ */ diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/context.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/context.h index 24b3eb48f53..685a279dc06 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/context.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/context.h @@ -88,6 +88,7 @@ #ifndef BROTLI_COMMON_CONTEXT_H_ #define BROTLI_COMMON_CONTEXT_H_ +#include <brotli/port.h> #include <brotli/types.h> typedef enum ContextType { @@ -97,163 +98,14 @@ typedef enum ContextType { CONTEXT_SIGNED = 3 } ContextType; +/* "Soft-private", it is exported, but not "advertised" as API. */ /* Common context lookup table for all context modes. */ -static const uint8_t kContextLookup[2048] = { - /* CONTEXT_LSB6, last byte. */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - - /* CONTEXT_LSB6, second last byte, */ - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - - /* CONTEXT_MSB6, last byte. */ - 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, - 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, - 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, - 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, - 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, - 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, - 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, - 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, - 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35, - 36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, - 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, - 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, - 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, - 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, - 56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, - 60, 60, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63, - - /* CONTEXT_MSB6, second last byte, */ - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - - /* CONTEXT_UTF8, last byte. */ - /* ASCII range. */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 8, 12, 16, 12, 12, 20, 12, 16, 24, 28, 12, 12, 32, 12, 36, 12, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 32, 32, 24, 40, 28, 12, - 12, 48, 52, 52, 52, 48, 52, 52, 52, 48, 52, 52, 52, 52, 52, 48, - 52, 52, 52, 52, 52, 48, 52, 52, 52, 52, 52, 24, 12, 28, 12, 12, - 12, 56, 60, 60, 60, 56, 60, 60, 60, 56, 60, 60, 60, 60, 60, 56, - 60, 60, 60, 60, 60, 56, 60, 60, 60, 60, 60, 24, 12, 28, 12, 0, - /* UTF8 continuation byte range. */ - 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, - 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, - 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, - 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, - /* UTF8 lead byte range. */ - 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, - 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, - 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, - 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, - - /* CONTEXT_UTF8 second last byte. */ - /* ASCII range. */ - 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, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, - 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, - 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 0, - /* UTF8 continuation byte range. */ - 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, - 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, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* UTF8 lead byte range. */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - - /* CONTEXT_SIGNED, last byte, same as the above values shifted by 3 bits. */ - 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 56, - - /* CONTEXT_SIGNED, second last byte. */ - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, -}; +BROTLI_COMMON_API extern const uint8_t _kBrotliContextLookupTable[2048]; typedef const uint8_t* ContextLut; /* typeof(MODE) == ContextType; returns ContextLut */ -#define BROTLI_CONTEXT_LUT(MODE) (&kContextLookup[(MODE) << 9]) +#define BROTLI_CONTEXT_LUT(MODE) (&_kBrotliContextLookupTable[(MODE) << 9]) /* typeof(LUT) == ContextLut */ #define BROTLI_CONTEXT(P1, P2, LUT) ((LUT)[P1] | ((LUT) + 256)[P2]) diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/dictionary.c b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/dictionary.c index 64822a381bb..f9e30417c00 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/dictionary.c +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/dictionary.c @@ -5,12 +5,13 @@ */ #include "./dictionary.h" +#include "./platform.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif -#ifndef BROTLI_EXTERNAL_DICTIONARY_DATA +#if !defined(BROTLI_EXTERNAL_DICTIONARY_DATA) static const uint8_t kBrotliDictionaryData[] = { 116,105,109,101,100,111,119,110,108,105,102,101,108,101,102,116,98,97,99,107,99, @@ -5862,7 +5863,11 @@ static const uint8_t kBrotliDictionaryData[] = ; #endif /* !BROTLI_EXTERNAL_DICTIONARY_DATA */ +#if !defined(BROTLI_EXTERNAL_DICTIONARY_DATA) +static const BrotliDictionary kBrotliDictionary = { +#else static BrotliDictionary kBrotliDictionary = { +#endif /* size_bits_by_length */ { 0, 0, 0, 0, 10, 10, 11, 11, @@ -5895,9 +5900,13 @@ const BrotliDictionary* BrotliGetDictionary() { } void BrotliSetDictionaryData(const uint8_t* data) { +#if defined(BROTLI_EXTERNAL_DICTIONARY_DATA) if (!!data && !kBrotliDictionary.data) { kBrotliDictionary.data = data; } +#else + BROTLI_UNUSED(data); // Appease -Werror=unused-parameter +#endif } #if defined(__cplusplus) || defined(c_plusplus) diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/platform.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/platform.h index 84c448c4cf8..f5ca4435bc0 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/platform.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/platform.h @@ -24,12 +24,11 @@ #define BROTLI_COMMON_PLATFORM_H_ #include <string.h> /* memcpy */ -#include <stdlib.h> /* malloc, free */ #include <brotli/port.h> #include <brotli/types.h> -#if defined(OS_LINUX) || defined(OS_CYGWIN) +#if defined(OS_LINUX) || defined(OS_CYGWIN) || defined(__EMSCRIPTEN__) #include <endian.h> #elif defined(OS_FREEBSD) #include <machine/endian.h> @@ -41,6 +40,10 @@ #define BROTLI_X_BIG_ENDIAN BIG_ENDIAN #endif +#if BROTLI_MSVC_VERSION_CHECK(12, 0, 0) +#include <intrin.h> +#endif + #if defined(BROTLI_ENABLE_LOG) || defined(BROTLI_DEBUG) #include <assert.h> #include <stdio.h> @@ -308,8 +311,7 @@ static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) { } #else /* BROTLI_ALIGNED_READ */ /* Unaligned memory access is allowed: just cast pointer to requested type. */ -#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \ - defined(MEMORY_SANITIZER) +#if BROTLI_SANITIZED /* Consider we have an unaligned load/store of 4 bytes from address 0x...05. AddressSanitizer will treat it as a 3-byte access to the range 05:07 and will miss a bug if 08 is the first unaddressable byte. @@ -334,7 +336,7 @@ extern "C" { #define BrotliUnalignedRead32 __sanitizer_unaligned_load32 #define BrotliUnalignedRead64 __sanitizer_unaligned_load64 #define BrotliUnalignedWrite64 __sanitizer_unaligned_store64 -#else +#else /* BROTLI_SANITIZED */ static BROTLI_INLINE uint16_t BrotliUnalignedRead16(const void* p) { return *(const uint16_t*)p; } @@ -356,7 +358,7 @@ static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) { typedef BROTLI_ALIGNED(1) uint64_t brotli_unaligned_uint64_t; static BROTLI_INLINE uint64_t BrotliUnalignedRead64(const void* p) { - return (uint64_t) ((brotli_unaligned_uint64_t*) p)[0]; + return (uint64_t) ((const brotli_unaligned_uint64_t*) p)[0]; } static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) { brotli_unaligned_uint64_t* dwords = (brotli_unaligned_uint64_t*) p; @@ -374,7 +376,7 @@ static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) { } #endif /* BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0) */ #endif /* BROTLI_64_BITS */ -#endif /* ASAN / TSAN / MSAN */ +#endif /* BROTLI_SANITIZED */ #endif /* BROTLI_ALIGNED_READ */ #if BROTLI_LITTLE_ENDIAN @@ -466,20 +468,20 @@ static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void* p, uint64_t v) { #endif #if defined(BROTLI_ENABLE_LOG) -#define BROTLI_DCHECK(x) assert(x) #define BROTLI_LOG(x) printf x #else -#define BROTLI_DCHECK(x) #define BROTLI_LOG(x) #endif #if defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG) +#define BROTLI_DCHECK(x) assert(x) static BROTLI_INLINE void BrotliDump(const char* f, int l, const char* fn) { fprintf(stderr, "%s:%d (%s)\n", f, l, fn); fflush(stderr); } #define BROTLI_DUMP() BrotliDump(__FILE__, __LINE__, __FUNCTION__) #else +#define BROTLI_DCHECK(x) #define BROTLI_DUMP() (void)(0) #endif @@ -523,17 +525,41 @@ BROTLI_MIN_MAX(size_t) BROTLI_MIN_MAX(uint32_t) BROTLI_MIN_MAX(uint8_t) (A)[(J)] = __brotli_swap_tmp; \ } -/* Default brotli_alloc_func */ -static void* BrotliDefaultAllocFunc(void* opaque, size_t size) { - BROTLI_UNUSED(opaque); - return malloc(size); +#if BROTLI_64_BITS +#if BROTLI_GNUC_HAS_BUILTIN(__builtin_ctzll, 3, 4, 0) || \ + BROTLI_INTEL_VERSION_CHECK(16, 0, 0) +#define BROTLI_TZCNT64 __builtin_ctzll +#elif BROTLI_MSVC_VERSION_CHECK(12, 0, 0) +#if defined(BROTLI_TARGET_X64) +#define BROTLI_TZCNT64 _tzcnt_u64 +#else /* BROTLI_TARGET_X64 */ +static BROTLI_INLINE uint32_t BrotliBsf64Msvc(uint64_t x) { + uint32_t lsb; + _BitScanForward64(&lsb, x); + return lsb; } +#define BROTLI_TZCNT64 BrotliBsf64Msvc +#endif /* BROTLI_TARGET_X64 */ +#endif /* __builtin_ctzll */ +#endif /* BROTLI_64_BITS */ -/* Default brotli_free_func */ -static void BrotliDefaultFreeFunc(void* opaque, void* address) { - BROTLI_UNUSED(opaque); - free(address); +#if BROTLI_GNUC_HAS_BUILTIN(__builtin_clz, 3, 4, 0) || \ + BROTLI_INTEL_VERSION_CHECK(16, 0, 0) +#define BROTLI_BSR32(x) (31u ^ (uint32_t)__builtin_clz(x)) +#elif BROTLI_MSVC_VERSION_CHECK(12, 0, 0) +static BROTLI_INLINE uint32_t BrotliBsr32Msvc(uint32_t x) { + unsigned long msb; + _BitScanReverse(&msb, x); + return (uint32_t)msb; } +#define BROTLI_BSR32 BrotliBsr32Msvc +#endif /* __builtin_clz */ + +/* Default brotli_alloc_func */ +BROTLI_COMMON_API void* BrotliDefaultAllocFunc(void* opaque, size_t size); + +/* Default brotli_free_func */ +BROTLI_COMMON_API void BrotliDefaultFreeFunc(void* opaque, void* address); BROTLI_UNUSED_FUNCTION void BrotliSuppressUnusedFunctions(void) { BROTLI_UNUSED(&BrotliSuppressUnusedFunctions); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/transform.c b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/transform.c index 426e635fd3d..f8fa4335e1c 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/transform.c +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/transform.c @@ -24,8 +24,8 @@ static const char kPrefixSuffix[217] = /* 8x _0 _ _3 _8 _C _E _ _1 _7 _F */ " not \3er \3al \4ful \4ive \5less \4es" /* Ax _5 _9 _D _2 _7 _D */ - "t \4ize \2\xc2\xa0\4ous \5 the \2e \0"; -/* Cx _2 _7___ ___ _A _F _5 _8 */ + "t \4ize \2\xc2\xa0\4ous \5 the \2e "; /* \0 - implicit trailing zero. */ +/* Cx _2 _7___ ___ _A _F _5 _8 */ static const uint16_t kPrefixSuffixMap[50] = { 0x00, 0x02, 0x05, 0x0E, 0x13, 0x16, 0x18, 0x1E, 0x23, 0x25, @@ -160,12 +160,13 @@ static const uint8_t kTransformsData[] = { 0, BROTLI_TRANSFORM_UPPERCASE_FIRST, 34, }; -static BrotliTransforms kBrotliTransforms = { +static const BrotliTransforms kBrotliTransforms = { sizeof(kPrefixSuffix), (const uint8_t*)kPrefixSuffix, kPrefixSuffixMap, sizeof(kTransformsData) / (3 * sizeof(kTransformsData[0])), kTransformsData, + NULL, /* no extra parameters */ {0, 12, 27, 23, 42, 63, 56, 48, 59, 64} }; @@ -190,6 +191,48 @@ static int ToUpperCase(uint8_t* p) { return 3; } +static int Shift(uint8_t* word, int word_len, uint16_t parameter) { + /* Limited sign extension: scalar < (1 << 24). */ + uint32_t scalar = + (parameter & 0x7FFFu) + (0x1000000u - (parameter & 0x8000u)); + if (word[0] < 0x80) { + /* 1-byte rune / 0sssssss / 7 bit scalar (ASCII). */ + scalar += (uint32_t)word[0]; + word[0] = (uint8_t)(scalar & 0x7Fu); + return 1; + } else if (word[0] < 0xC0) { + /* Continuation / 10AAAAAA. */ + return 1; + } else if (word[0] < 0xE0) { + /* 2-byte rune / 110sssss AAssssss / 11 bit scalar. */ + if (word_len < 2) return 1; + scalar += (uint32_t)((word[1] & 0x3Fu) | ((word[0] & 0x1Fu) << 6u)); + word[0] = (uint8_t)(0xC0 | ((scalar >> 6u) & 0x1F)); + word[1] = (uint8_t)((word[1] & 0xC0) | (scalar & 0x3F)); + return 2; + } else if (word[0] < 0xF0) { + /* 3-byte rune / 1110ssss AAssssss BBssssss / 16 bit scalar. */ + if (word_len < 3) return word_len; + scalar += (uint32_t)((word[2] & 0x3Fu) | ((word[1] & 0x3Fu) << 6u) | + ((word[0] & 0x0Fu) << 12u)); + word[0] = (uint8_t)(0xE0 | ((scalar >> 12u) & 0x0F)); + word[1] = (uint8_t)((word[1] & 0xC0) | ((scalar >> 6u) & 0x3F)); + word[2] = (uint8_t)((word[2] & 0xC0) | (scalar & 0x3F)); + return 3; + } else if (word[0] < 0xF8) { + /* 4-byte rune / 11110sss AAssssss BBssssss CCssssss / 21 bit scalar. */ + if (word_len < 4) return word_len; + scalar += (uint32_t)((word[3] & 0x3Fu) | ((word[2] & 0x3Fu) << 6u) | + ((word[1] & 0x3Fu) << 12u) | ((word[0] & 0x07u) << 18u)); + word[0] = (uint8_t)(0xF0 | ((scalar >> 18u) & 0x07)); + word[1] = (uint8_t)((word[1] & 0xC0) | ((scalar >> 12u) & 0x3F)); + word[2] = (uint8_t)((word[2] & 0xC0) | ((scalar >> 6u) & 0x3F)); + word[3] = (uint8_t)((word[3] & 0xC0) | (scalar & 0x3F)); + return 4; + } + return 1; +} + int BrotliTransformDictionaryWord(uint8_t* dst, const uint8_t* word, int len, const BrotliTransforms* transforms, int transform_idx) { int idx = 0; @@ -221,6 +264,19 @@ int BrotliTransformDictionaryWord(uint8_t* dst, const uint8_t* word, int len, uppercase += step; len -= step; } + } else if (t == BROTLI_TRANSFORM_SHIFT_FIRST) { + uint16_t param = (uint16_t)(transforms->params[transform_idx * 2] + + (transforms->params[transform_idx * 2 + 1] << 8u)); + Shift(&dst[idx - len], len, param); + } else if (t == BROTLI_TRANSFORM_SHIFT_ALL) { + uint16_t param = (uint16_t)(transforms->params[transform_idx * 2] + + (transforms->params[transform_idx * 2 + 1] << 8u)); + uint8_t* shift = &dst[idx - len]; + while (len > 0) { + int step = Shift(shift, len, param); + shift += step; + len -= step; + } } } { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/transform.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/transform.h index 456c12db9b2..b6f86cc7d5a 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/transform.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/transform.h @@ -37,6 +37,8 @@ enum BrotliWordTransformType { BROTLI_TRANSFORM_OMIT_FIRST_7 = 18, BROTLI_TRANSFORM_OMIT_FIRST_8 = 19, BROTLI_TRANSFORM_OMIT_FIRST_9 = 20, + BROTLI_TRANSFORM_SHIFT_FIRST = 21, + BROTLI_TRANSFORM_SHIFT_ALL = 22, BROTLI_NUM_TRANSFORM_TYPES /* Counts transforms, not a transform itself. */ }; @@ -50,6 +52,9 @@ typedef struct BrotliTransforms { uint32_t num_transforms; /* Each entry is a [prefix_id, transform, suffix_id] triplet. */ const uint8_t* transforms; + /* Shift for BROTLI_TRANSFORM_SHIFT_FIRST and BROTLI_TRANSFORM_SHIFT_ALL, + must be NULL if and only if no such transforms are present. */ + const uint8_t* params; /* Indices of transforms like ["", BROTLI_TRANSFORM_OMIT_LAST_#, ""]. 0-th element corresponds to ["", BROTLI_TRANSFORM_IDENTITY, ""]. -1, if cut-off transform does not exist. */ diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/version.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/version.h index 0d0d0c79676..01b2998e25d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/version.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/common/version.h @@ -14,13 +14,13 @@ BrotliEncoderVersion methods. */ /* Semantic version, calculated as (MAJOR << 24) | (MINOR << 12) | PATCH */ -#define BROTLI_VERSION 0x1000007 +#define BROTLI_VERSION 0x1000009 /* This macro is used by build system to produce Libtool-friendly soname. See https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html */ /* ABI version, calculated as (CURRENT << 24) | (REVISION << 12) | AGE */ -#define BROTLI_ABI_VERSION 0x1007000 +#define BROTLI_ABI_VERSION 0x1009000 #endif /* BROTLI_COMMON_VERSION_H_ */ diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/backward_references.c b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/backward_references.c index cd023d9b41c..a07a617a097 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/backward_references.c +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/backward_references.c @@ -9,6 +9,7 @@ #include "./backward_references.h" #include "../common/constants.h" +#include "../common/context.h" #include "../common/dictionary.h" #include "../common/platform.h" #include <brotli/types.h> @@ -119,17 +120,17 @@ static BROTLI_INLINE size_t ComputeDistanceCode(size_t distance, #undef CAT #undef EXPAND_CAT -void BrotliCreateBackwardReferences( - size_t num_bytes, size_t position, const uint8_t* ringbuffer, - size_t ringbuffer_mask, const BrotliEncoderParams* params, - HasherHandle hasher, int* dist_cache, size_t* last_insert_len, +void BrotliCreateBackwardReferences(size_t num_bytes, + size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, + ContextLut literal_context_lut, const BrotliEncoderParams* params, + Hasher* hasher, int* dist_cache, size_t* last_insert_len, Command* commands, size_t* num_commands, size_t* num_literals) { switch (params->hasher.type) { #define CASE_(N) \ case N: \ - CreateBackwardReferencesNH ## N( \ - num_bytes, position, ringbuffer, \ - ringbuffer_mask, params, hasher, dist_cache, \ + CreateBackwardReferencesNH ## N(num_bytes, \ + position, ringbuffer, ringbuffer_mask, \ + literal_context_lut, params, hasher, dist_cache, \ last_insert_len, commands, num_commands, num_literals); \ return; FOR_GENERIC_HASHERS(CASE_) diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/backward_references.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/backward_references.h index 3a4146647c4..9589cc15419 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/backward_references.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/backward_references.h @@ -10,6 +10,7 @@ #define BROTLI_ENC_BACKWARD_REFERENCES_H_ #include "../common/constants.h" +#include "../common/context.h" #include "../common/dictionary.h" #include "../common/platform.h" #include <brotli/types.h> @@ -25,10 +26,10 @@ extern "C" { initially the total amount of commands output by previous CreateBackwardReferences calls, and must be incremented by the amount written by this call. */ -BROTLI_INTERNAL void BrotliCreateBackwardReferences( - size_t num_bytes, size_t position, const uint8_t* ringbuffer, - size_t ringbuffer_mask, const BrotliEncoderParams* params, - HasherHandle hasher, int* dist_cache, size_t* last_insert_len, +BROTLI_INTERNAL void BrotliCreateBackwardReferences(size_t num_bytes, + size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, + ContextLut literal_context_lut, const BrotliEncoderParams* params, + Hasher* hasher, int* dist_cache, size_t* last_insert_len, Command* commands, size_t* num_commands, size_t* num_literals); #if defined(__cplusplus) || defined(c_plusplus) diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/backward_references_hq.c b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/backward_references_hq.c index 96b0e708de4..5651caeb7ac 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/backward_references_hq.c +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/backward_references_hq.c @@ -11,6 +11,7 @@ #include <string.h> /* memcpy, memset */ #include "../common/constants.h" +#include "../common/context.h" #include "../common/platform.h" #include <brotli/types.h> #include "./command.h" @@ -26,6 +27,7 @@ extern "C" { #endif +/* BrotliCalculateDistanceCodeLimit(BROTLI_MAX_ALLOWED_DISTANCE, 3, 120). */ #define BROTLI_MAX_EFFECTIVE_DISTANCE_ALPHABET_SIZE 544 static const float kInfinity = 1.7e38f; /* ~= 2 ^ 127 */ @@ -86,14 +88,10 @@ typedef struct ZopfliCostModel { static void InitZopfliCostModel( MemoryManager* m, ZopfliCostModel* self, const BrotliDistanceParams* dist, size_t num_bytes) { - uint32_t distance_histogram_size = dist->alphabet_size; - if (distance_histogram_size > BROTLI_MAX_EFFECTIVE_DISTANCE_ALPHABET_SIZE) { - distance_histogram_size = BROTLI_MAX_EFFECTIVE_DISTANCE_ALPHABET_SIZE; - } self->num_bytes_ = num_bytes; self->literal_costs_ = BROTLI_ALLOC(m, float, num_bytes + 2); - self->cost_dist_ = BROTLI_ALLOC(m, float, dist->alphabet_size); - self->distance_histogram_size = distance_histogram_size; + self->cost_dist_ = BROTLI_ALLOC(m, float, dist->alphabet_size_limit); + self->distance_histogram_size = dist->alphabet_size_limit; if (BROTLI_IS_OOM(m)) return; } @@ -408,9 +406,12 @@ static size_t UpdateNodes( const int* starting_dist_cache, const size_t num_matches, const BackwardMatch* matches, const ZopfliCostModel* model, StartPosQueue* queue, ZopfliNode* nodes) { + const size_t stream_offset = params->stream_offset; const size_t cur_ix = block_start + pos; const size_t cur_ix_masked = cur_ix & ringbuffer_mask; const size_t max_distance = BROTLI_MIN(size_t, cur_ix, max_backward_limit); + const size_t dictionary_start = BROTLI_MIN(size_t, + cur_ix + stream_offset, max_backward_limit); const size_t max_len = num_bytes - pos; const size_t max_zopfli_len = MaxZopfliLen(params); const size_t max_iters = MaxZopfliCandidates(params); @@ -419,8 +420,8 @@ static size_t UpdateNodes( size_t k; size_t gap = 0; - EvaluateNode(block_start, pos, max_backward_limit, gap, starting_dist_cache, - model, queue, nodes); + EvaluateNode(block_start + stream_offset, pos, max_backward_limit, gap, + starting_dist_cache, model, queue, nodes); { const PosData* posdata = StartPosQueueAt(queue, 0); @@ -453,7 +454,7 @@ static size_t UpdateNodes( if (cur_ix_masked + best_len > ringbuffer_mask) { break; } - if (BROTLI_PREDICT_FALSE(backward > max_distance + gap)) { + if (BROTLI_PREDICT_FALSE(backward > dictionary_start + gap)) { /* Word dictionary -> ignore. */ continue; } @@ -472,6 +473,8 @@ static size_t UpdateNodes( &ringbuffer[cur_ix_masked], max_len); } else { + /* "Gray" area. It is addressable by decoder, but this encoder + instance does not have that data -> should not touch it. */ continue; } { @@ -506,7 +509,7 @@ static size_t UpdateNodes( BackwardMatch match = matches[j]; size_t dist = match.distance; BROTLI_BOOL is_dictionary_match = - TO_BROTLI_BOOL(dist > max_distance + gap); + TO_BROTLI_BOOL(dist > dictionary_start + gap); /* We already tried all possible last distance matches, so we can use normal distance code here. */ size_t dist_code = dist + BROTLI_NUM_DISTANCE_SHORT_CODES - 1; @@ -569,6 +572,7 @@ void BrotliZopfliCreateCommands(const size_t num_bytes, const size_t block_start, const ZopfliNode* nodes, int* dist_cache, size_t* last_insert_len, const BrotliEncoderParams* params, Command* commands, size_t* num_literals) { + const size_t stream_offset = params->stream_offset; const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin); size_t pos = 0; uint32_t offset = nodes[0].u.next; @@ -587,9 +591,10 @@ void BrotliZopfliCreateCommands(const size_t num_bytes, { size_t distance = ZopfliNodeCopyDistance(next); size_t len_code = ZopfliNodeLengthCode(next); - size_t max_distance = - BROTLI_MIN(size_t, block_start + pos, max_backward_limit); - BROTLI_BOOL is_dictionary = TO_BROTLI_BOOL(distance > max_distance + gap); + size_t dictionary_start = BROTLI_MIN(size_t, + block_start + pos + stream_offset, max_backward_limit); + BROTLI_BOOL is_dictionary = + TO_BROTLI_BOOL(distance > dictionary_start + gap); size_t dist_code = ZopfliNodeDistanceCode(next); InitCommand(&commands[i], ¶ms->dist, insert_length, copy_length, (int)len_code - (int)copy_length, dist_code); @@ -613,6 +618,7 @@ static size_t ZopfliIterate(size_t num_bytes, size_t position, const BrotliEncoderParams* params, const size_t gap, const int* dist_cache, const ZopfliCostModel* model, const uint32_t* num_matches, const BackwardMatch* matches, ZopfliNode* nodes) { + const size_t stream_offset = params->stream_offset; const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin); const size_t max_zopfli_len = MaxZopfliLen(params); StartPosQueue queue; @@ -637,7 +643,7 @@ static size_t ZopfliIterate(size_t num_bytes, size_t position, while (skip) { i++; if (i + 3 >= num_bytes) break; - EvaluateNode(position, i, max_backward_limit, gap, + EvaluateNode(position + stream_offset, i, max_backward_limit, gap, dist_cache, model, &queue, nodes); cur_match_pos += num_matches[i]; skip--; @@ -650,8 +656,9 @@ static size_t ZopfliIterate(size_t num_bytes, size_t position, /* REQUIRES: nodes != NULL and len(nodes) >= num_bytes + 1 */ size_t BrotliZopfliComputeShortestPath(MemoryManager* m, size_t num_bytes, size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, - const BrotliEncoderParams* params, - const int* dist_cache, HasherHandle hasher, ZopfliNode* nodes) { + ContextLut literal_context_lut, const BrotliEncoderParams* params, + const int* dist_cache, Hasher* hasher, ZopfliNode* nodes) { + const size_t stream_offset = params->stream_offset; const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin); const size_t max_zopfli_len = MaxZopfliLen(params); ZopfliCostModel model; @@ -662,6 +669,7 @@ size_t BrotliZopfliComputeShortestPath(MemoryManager* m, size_t num_bytes, size_t i; size_t gap = 0; size_t lz_matches_offset = 0; + BROTLI_UNUSED(literal_context_lut); nodes[0].length = 0; nodes[0].u.cost = 0; InitZopfliCostModel(m, &model, ¶ms->dist, num_bytes); @@ -672,12 +680,14 @@ size_t BrotliZopfliComputeShortestPath(MemoryManager* m, size_t num_bytes, for (i = 0; i + HashTypeLengthH10() - 1 < num_bytes; i++) { const size_t pos = position + i; const size_t max_distance = BROTLI_MIN(size_t, pos, max_backward_limit); + const size_t dictionary_start = BROTLI_MIN(size_t, + pos + stream_offset, max_backward_limit); size_t skip; size_t num_matches; - num_matches = FindAllMatchesH10(hasher, + num_matches = FindAllMatchesH10(&hasher->privat._H10, ¶ms->dictionary, ringbuffer, ringbuffer_mask, pos, num_bytes - i, max_distance, - gap, params, &matches[lz_matches_offset]); + dictionary_start + gap, params, &matches[lz_matches_offset]); if (num_matches > 0 && BackwardMatchLength(&matches[num_matches - 1]) > max_zopfli_len) { matches[0] = matches[num_matches - 1]; @@ -692,13 +702,14 @@ size_t BrotliZopfliComputeShortestPath(MemoryManager* m, size_t num_bytes, } if (skip > 1) { /* Add the tail of the copy to the hasher. */ - StoreRangeH10(hasher, ringbuffer, ringbuffer_mask, pos + 1, BROTLI_MIN( + StoreRangeH10(&hasher->privat._H10, + ringbuffer, ringbuffer_mask, pos + 1, BROTLI_MIN( size_t, pos + skip, store_end)); skip--; while (skip) { i++; if (i + HashTypeLengthH10() - 1 >= num_bytes) break; - EvaluateNode(position, i, max_backward_limit, gap, + EvaluateNode(position + stream_offset, i, max_backward_limit, gap, dist_cache, &model, &queue, nodes); skip--; } @@ -710,15 +721,14 @@ size_t BrotliZopfliComputeShortestPath(MemoryManager* m, size_t num_bytes, void BrotliCreateZopfliBackwardReferences(MemoryManager* m, size_t num_bytes, size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, - const BrotliEncoderParams* params, - HasherHandle hasher, int* dist_cache, size_t* last_insert_len, + ContextLut literal_context_lut, const BrotliEncoderParams* params, + Hasher* hasher, int* dist_cache, size_t* last_insert_len, Command* commands, size_t* num_commands, size_t* num_literals) { - ZopfliNode* nodes; - nodes = BROTLI_ALLOC(m, ZopfliNode, num_bytes + 1); - if (BROTLI_IS_OOM(m)) return; + ZopfliNode* nodes = BROTLI_ALLOC(m, ZopfliNode, num_bytes + 1); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(nodes)) return; BrotliInitZopfliNodes(nodes, num_bytes + 1); *num_commands += BrotliZopfliComputeShortestPath(m, num_bytes, - position, ringbuffer, ringbuffer_mask, params, + position, ringbuffer, ringbuffer_mask, literal_context_lut, params, dist_cache, hasher, nodes); if (BROTLI_IS_OOM(m)) return; BrotliZopfliCreateCommands(num_bytes, position, nodes, dist_cache, @@ -728,9 +738,10 @@ void BrotliCreateZopfliBackwardReferences(MemoryManager* m, size_t num_bytes, void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, size_t num_bytes, size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, - const BrotliEncoderParams* params, - HasherHandle hasher, int* dist_cache, size_t* last_insert_len, + ContextLut literal_context_lut, const BrotliEncoderParams* params, + Hasher* hasher, int* dist_cache, size_t* last_insert_len, Command* commands, size_t* num_commands, size_t* num_literals) { + const size_t stream_offset = params->stream_offset; const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin); uint32_t* num_matches = BROTLI_ALLOC(m, uint32_t, num_bytes); size_t matches_size = 4 * num_bytes; @@ -747,10 +758,16 @@ void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, size_t num_bytes, BackwardMatch* matches = BROTLI_ALLOC(m, BackwardMatch, matches_size); size_t gap = 0; size_t shadow_matches = 0; - if (BROTLI_IS_OOM(m)) return; + BROTLI_UNUSED(literal_context_lut); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(num_matches) || + BROTLI_IS_NULL(matches)) { + return; + } for (i = 0; i + HashTypeLengthH10() - 1 < num_bytes; ++i) { const size_t pos = position + i; size_t max_distance = BROTLI_MIN(size_t, pos, max_backward_limit); + size_t dictionary_start = BROTLI_MIN(size_t, + pos + stream_offset, max_backward_limit); size_t max_length = num_bytes - i; size_t num_found_matches; size_t cur_match_end; @@ -759,10 +776,10 @@ void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, size_t num_bytes, BROTLI_ENSURE_CAPACITY(m, BackwardMatch, matches, matches_size, cur_match_pos + MAX_NUM_MATCHES_H10 + shadow_matches); if (BROTLI_IS_OOM(m)) return; - num_found_matches = FindAllMatchesH10(hasher, + num_found_matches = FindAllMatchesH10(&hasher->privat._H10, ¶ms->dictionary, ringbuffer, ringbuffer_mask, pos, max_length, - max_distance, gap, params, + max_distance, dictionary_start + gap, params, &matches[cur_match_pos + shadow_matches]); cur_match_end = cur_match_pos + num_found_matches; for (j = cur_match_pos; j + 1 < cur_match_end; ++j) { @@ -777,7 +794,8 @@ void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, size_t num_bytes, matches[cur_match_pos++] = matches[cur_match_end - 1]; num_matches[i] = 1; /* Add the tail of the copy to the hasher. */ - StoreRangeH10(hasher, ringbuffer, ringbuffer_mask, pos + 1, + StoreRangeH10(&hasher->privat._H10, + ringbuffer, ringbuffer_mask, pos + 1, BROTLI_MIN(size_t, pos + match_len, store_end)); memset(&num_matches[i + 1], 0, skip * sizeof(num_matches[0])); i += skip; @@ -791,7 +809,7 @@ void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, size_t num_bytes, memcpy(orig_dist_cache, dist_cache, 4 * sizeof(dist_cache[0])); orig_num_commands = *num_commands; nodes = BROTLI_ALLOC(m, ZopfliNode, num_bytes + 1); - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(nodes)) return; InitZopfliCostModel(m, &model, ¶ms->dist, num_bytes); if (BROTLI_IS_OOM(m)) return; for (i = 0; i < 2; i++) { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/backward_references_hq.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/backward_references_hq.h index 1e4275d403f..36b75f250d7 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/backward_references_hq.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/backward_references_hq.h @@ -10,6 +10,7 @@ #define BROTLI_ENC_BACKWARD_REFERENCES_HQ_H_ #include "../common/constants.h" +#include "../common/context.h" #include "../common/dictionary.h" #include "../common/platform.h" #include <brotli/types.h> @@ -23,15 +24,17 @@ extern "C" { #endif BROTLI_INTERNAL void BrotliCreateZopfliBackwardReferences(MemoryManager* m, - size_t num_bytes, size_t position, const uint8_t* ringbuffer, - size_t ringbuffer_mask, const BrotliEncoderParams* params, - HasherHandle hasher, int* dist_cache, size_t* last_insert_len, + size_t num_bytes, + size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, + ContextLut literal_context_lut, const BrotliEncoderParams* params, + Hasher* hasher, int* dist_cache, size_t* last_insert_len, Command* commands, size_t* num_commands, size_t* num_literals); BROTLI_INTERNAL void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, - size_t num_bytes, size_t position, const uint8_t* ringbuffer, - size_t ringbuffer_mask, const BrotliEncoderParams* params, - HasherHandle hasher, int* dist_cache, size_t* last_insert_len, + size_t num_bytes, + size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, + ContextLut literal_context_lut, const BrotliEncoderParams* params, + Hasher* hasher, int* dist_cache, size_t* last_insert_len, Command* commands, size_t* num_commands, size_t* num_literals); typedef struct ZopfliNode { @@ -77,8 +80,8 @@ BROTLI_INTERNAL void BrotliInitZopfliNodes(ZopfliNode* array, size_t length); BROTLI_INTERNAL size_t BrotliZopfliComputeShortestPath( MemoryManager* m, size_t num_bytes, size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, - const BrotliEncoderParams* params, - const int* dist_cache, HasherHandle hasher, ZopfliNode* nodes); + ContextLut literal_context_lut, const BrotliEncoderParams* params, + const int* dist_cache, Hasher* hasher, ZopfliNode* nodes); BROTLI_INTERNAL void BrotliZopfliCreateCommands( const size_t num_bytes, const size_t block_start, const ZopfliNode* nodes, diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/backward_references_inc.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/backward_references_inc.h index c18cdb00cb9..766bf91ffd2 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/backward_references_inc.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/backward_references_inc.h @@ -10,11 +10,13 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)( size_t num_bytes, size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, - const BrotliEncoderParams* params, - HasherHandle hasher, int* dist_cache, size_t* last_insert_len, + ContextLut literal_context_lut, const BrotliEncoderParams* params, + Hasher* hasher, int* dist_cache, size_t* last_insert_len, Command* commands, size_t* num_commands, size_t* num_literals) { + HASHER()* privat = &hasher->privat.FN(_); /* Set maximum distance, see section 9.1. of the spec. */ const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin); + const size_t position_offset = params->stream_offset; const Command* const orig_commands = commands; size_t insert_length = *last_insert_len; @@ -31,19 +33,23 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)( /* Minimum score to accept a backward reference. */ const score_t kMinScore = BROTLI_SCORE_BASE + 100; - FN(PrepareDistanceCache)(hasher, dist_cache); + BROTLI_UNUSED(literal_context_lut); + + FN(PrepareDistanceCache)(privat, dist_cache); while (position + FN(HashTypeLength)() < pos_end) { size_t max_length = pos_end - position; size_t max_distance = BROTLI_MIN(size_t, position, max_backward_limit); + size_t dictionary_start = BROTLI_MIN(size_t, + position + position_offset, max_backward_limit); HasherSearchResult sr; sr.len = 0; sr.len_code_delta = 0; sr.distance = 0; sr.score = kMinScore; - FN(FindLongestMatch)(hasher, ¶ms->dictionary, + FN(FindLongestMatch)(privat, ¶ms->dictionary, ringbuffer, ringbuffer_mask, dist_cache, position, max_length, - max_distance, gap, params->dist.max_distance, &sr); + max_distance, dictionary_start + gap, params->dist.max_distance, &sr); if (sr.score > kMinScore) { /* Found a match. Let's look for something even better ahead. */ int delayed_backward_references_in_row = 0; @@ -57,10 +63,13 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)( sr2.distance = 0; sr2.score = kMinScore; max_distance = BROTLI_MIN(size_t, position + 1, max_backward_limit); - FN(FindLongestMatch)(hasher, + dictionary_start = BROTLI_MIN(size_t, + position + 1 + position_offset, max_backward_limit); + FN(FindLongestMatch)(privat, ¶ms->dictionary, ringbuffer, ringbuffer_mask, dist_cache, position + 1, max_length, - max_distance, gap, params->dist.max_distance, &sr2); + max_distance, dictionary_start + gap, params->dist.max_distance, + &sr2); if (sr2.score >= sr.score + cost_diff_lazy) { /* Ok, let's just write one byte for now and start a match from the next byte. */ @@ -76,18 +85,19 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)( } apply_random_heuristics = position + 2 * sr.len + random_heuristics_window_size; - max_distance = BROTLI_MIN(size_t, position, max_backward_limit); + dictionary_start = BROTLI_MIN(size_t, + position + position_offset, max_backward_limit); { /* The first 16 codes are special short-codes, and the minimum offset is 1. */ size_t distance_code = ComputeDistanceCode( - sr.distance, max_distance + gap, dist_cache); - if ((sr.distance <= (max_distance + gap)) && distance_code > 0) { + sr.distance, dictionary_start + gap, dist_cache); + if ((sr.distance <= (dictionary_start + gap)) && distance_code > 0) { dist_cache[3] = dist_cache[2]; dist_cache[2] = dist_cache[1]; dist_cache[1] = dist_cache[0]; dist_cache[0] = (int)sr.distance; - FN(PrepareDistanceCache)(hasher, dist_cache); + FN(PrepareDistanceCache)(privat, dist_cache); } InitCommand(commands++, ¶ms->dist, insert_length, sr.len, sr.len_code_delta, distance_code); @@ -105,7 +115,7 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)( range_start = BROTLI_MIN(size_t, range_end, BROTLI_MAX(size_t, range_start, position + sr.len - (sr.distance << 2))); } - FN(StoreRange)(hasher, ringbuffer, ringbuffer_mask, range_start, + FN(StoreRange)(privat, ringbuffer, ringbuffer_mask, range_start, range_end); } position += sr.len; @@ -131,7 +141,7 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)( size_t pos_jump = BROTLI_MIN(size_t, position + 16, pos_end - kMargin); for (; position < pos_jump; position += 4) { - FN(Store)(hasher, ringbuffer, ringbuffer_mask, position); + FN(Store)(privat, ringbuffer, ringbuffer_mask, position); insert_length += 4; } } else { @@ -140,7 +150,7 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)( size_t pos_jump = BROTLI_MIN(size_t, position + 8, pos_end - kMargin); for (; position < pos_jump; position += 2) { - FN(Store)(hasher, ringbuffer, ringbuffer_mask, position); + FN(Store)(privat, ringbuffer, ringbuffer_mask, position); insert_length += 2; } } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/block_splitter.c b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/block_splitter.c index d308eca59d3..deb7c2e151a 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/block_splitter.c +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/block_splitter.c @@ -132,7 +132,7 @@ void BrotliSplitBlock(MemoryManager* m, { size_t literals_count = CountLiterals(cmds, num_commands); uint8_t* literals = BROTLI_ALLOC(m, uint8_t, literals_count); - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(literals)) return; /* Create a continuous array of literals. */ CopyLiteralsToByteArray(cmds, num_commands, data, pos, mask, literals); /* Create the block split on the array of literals. @@ -150,7 +150,7 @@ void BrotliSplitBlock(MemoryManager* m, /* Compute prefix codes for commands. */ uint16_t* insert_and_copy_codes = BROTLI_ALLOC(m, uint16_t, num_commands); size_t i; - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(insert_and_copy_codes)) return; for (i = 0; i < num_commands; ++i) { insert_and_copy_codes[i] = cmds[i].cmd_prefix_; } @@ -170,7 +170,7 @@ void BrotliSplitBlock(MemoryManager* m, uint16_t* distance_prefixes = BROTLI_ALLOC(m, uint16_t, num_commands); size_t j = 0; size_t i; - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(distance_prefixes)) return; for (i = 0; i < num_commands; ++i) { const Command* cmd = &cmds[i]; if (CommandCopyLen(cmd) && cmd->cmd_prefix_ >= 128) { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/block_splitter_inc.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/block_splitter_inc.h index 023712b84d3..e612d6a3707 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/block_splitter_inc.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/block_splitter_inc.h @@ -219,7 +219,12 @@ static void FN(ClusterBlocks)(MemoryManager* m, uint32_t symbols[HISTOGRAMS_PER_BATCH] = { 0 }; uint32_t remap[HISTOGRAMS_PER_BATCH] = { 0 }; - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(histogram_symbols) || + BROTLI_IS_NULL(block_lengths) || BROTLI_IS_NULL(all_histograms) || + BROTLI_IS_NULL(cluster_size) || BROTLI_IS_NULL(histograms) || + BROTLI_IS_NULL(pairs)) { + return; + } memset(block_lengths, 0, num_blocks * sizeof(uint32_t)); @@ -278,11 +283,11 @@ static void FN(ClusterBlocks)(MemoryManager* m, if (pairs_capacity < max_num_pairs + 1) { BROTLI_FREE(m, pairs); pairs = BROTLI_ALLOC(m, HistogramPair, max_num_pairs + 1); - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(pairs)) return; } clusters = BROTLI_ALLOC(m, uint32_t, num_clusters); - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(clusters)) return; for (i = 0; i < num_clusters; ++i) { clusters[i] = (uint32_t)i; } @@ -294,7 +299,7 @@ static void FN(ClusterBlocks)(MemoryManager* m, BROTLI_FREE(m, cluster_size); new_index = BROTLI_ALLOC(m, uint32_t, num_clusters); - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(new_index)) return; for (i = 0; i < num_clusters; ++i) new_index[i] = kInvalidIndex; pos = 0; { @@ -386,7 +391,7 @@ static void FN(SplitByteVector)(MemoryManager* m, return; } histograms = BROTLI_ALLOC(m, HistogramType, num_histograms); - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(histograms)) return; /* Find good entropy codes. */ FN(InitialEntropyCodes)(data, length, sampling_stride_length, @@ -405,7 +410,11 @@ static void FN(SplitByteVector)(MemoryManager* m, uint16_t* new_id = BROTLI_ALLOC(m, uint16_t, num_histograms); const size_t iters = params->quality < HQ_ZOPFLIFICATION_QUALITY ? 3 : 10; size_t i; - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(block_ids) || + BROTLI_IS_NULL(insert_cost) || BROTLI_IS_NULL(cost) || + BROTLI_IS_NULL(switch_signal) || BROTLI_IS_NULL(new_id)) { + return; + } for (i = 0; i < iters; ++i) { num_blocks = FN(FindBlocks)(data, length, block_switch_cost, diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/brotli_bit_stream.c b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/brotli_bit_stream.c index aaf2dad7dbd..9348a97e1b9 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/brotli_bit_stream.c +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/brotli_bit_stream.c @@ -34,33 +34,18 @@ extern "C" { BROTLI_DISTANCE_ALPHABET_SIZE(0, 0, BROTLI_LARGE_MAX_DISTANCE_BITS) /* MAX_SIMPLE_DISTANCE_ALPHABET_SIZE == 140 */ -/* Represents the range of values belonging to a prefix code: - [offset, offset + 2^nbits) */ -typedef struct PrefixCodeRange { - uint32_t offset; - uint32_t nbits; -} PrefixCodeRange; - -static const PrefixCodeRange - kBlockLengthPrefixCode[BROTLI_NUM_BLOCK_LEN_SYMBOLS] = { - { 1, 2}, { 5, 2}, { 9, 2}, {13, 2}, {17, 3}, { 25, 3}, { 33, 3}, - {41, 3}, {49, 4}, {65, 4}, {81, 4}, {97, 4}, {113, 5}, {145, 5}, - {177, 5}, { 209, 5}, { 241, 6}, { 305, 6}, { 369, 7}, { 497, 8}, - {753, 9}, {1265, 10}, {2289, 11}, {4337, 12}, {8433, 13}, {16625, 24} -}; - static BROTLI_INLINE uint32_t BlockLengthPrefixCode(uint32_t len) { uint32_t code = (len >= 177) ? (len >= 753 ? 20 : 14) : (len >= 41 ? 7 : 0); while (code < (BROTLI_NUM_BLOCK_LEN_SYMBOLS - 1) && - len >= kBlockLengthPrefixCode[code + 1].offset) ++code; + len >= _kBrotliPrefixCodeRanges[code + 1].offset) ++code; return code; } static BROTLI_INLINE void GetBlockLengthPrefixCode(uint32_t len, size_t* code, uint32_t* n_extra, uint32_t* extra) { *code = BlockLengthPrefixCode(len); - *n_extra = kBlockLengthPrefixCode[*code].nbits; - *extra = len - kBlockLengthPrefixCode[*code].offset; + *n_extra = _kBrotliPrefixCodeRanges[*code].nbits; + *extra = len - _kBrotliPrefixCodeRanges[*code].offset; } typedef struct BlockTypeCodeCalculator { @@ -450,7 +435,7 @@ void BrotliBuildAndStoreHuffmanTreeFast(MemoryManager* m, const size_t max_tree_size = 2 * length + 1; HuffmanTree* tree = BROTLI_ALLOC(m, HuffmanTree, max_tree_size); uint32_t count_limit; - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(tree)) return; for (count_limit = 1; ; count_limit *= 2) { HuffmanTree* node = tree; size_t l; @@ -714,7 +699,7 @@ static void EncodeContextMap(MemoryManager* m, } rle_symbols = BROTLI_ALLOC(m, uint32_t, context_map_size); - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(rle_symbols)) return; MoveToFrontTransform(context_map, context_map_size, rle_symbols); RunLengthCodeZeros(context_map_size, rle_symbols, &num_rle_symbols, &max_run_length_prefix); @@ -956,23 +941,21 @@ void BrotliStoreMetaBlock(MemoryManager* m, size_t pos = start_pos; size_t i; - uint32_t num_distance_symbols = params->dist.alphabet_size; - uint32_t num_effective_distance_symbols = num_distance_symbols; + uint32_t num_distance_symbols = params->dist.alphabet_size_max; + uint32_t num_effective_distance_symbols = params->dist.alphabet_size_limit; HuffmanTree* tree; ContextLut literal_context_lut = BROTLI_CONTEXT_LUT(literal_context_mode); BlockEncoder literal_enc; BlockEncoder command_enc; BlockEncoder distance_enc; const BrotliDistanceParams* dist = ¶ms->dist; - if (params->large_window && - num_effective_distance_symbols > BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS) { - num_effective_distance_symbols = BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS; - } + BROTLI_DCHECK( + num_effective_distance_symbols <= BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS); StoreCompressedMetaBlockHeader(is_last, length, storage_ix, storage); tree = BROTLI_ALLOC(m, HuffmanTree, MAX_HUFFMAN_TREE_SIZE); - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(tree)) return; InitBlockEncoder(&literal_enc, BROTLI_NUM_LITERAL_SYMBOLS, mb->literal_split.num_types, mb->literal_split.types, mb->literal_split.lengths, mb->literal_split.num_blocks); @@ -1163,7 +1146,7 @@ void BrotliStoreMetaBlockTrivial(MemoryManager* m, uint8_t dist_depth[MAX_SIMPLE_DISTANCE_ALPHABET_SIZE]; uint16_t dist_bits[MAX_SIMPLE_DISTANCE_ALPHABET_SIZE]; HuffmanTree* tree; - uint32_t num_distance_symbols = params->dist.alphabet_size; + uint32_t num_distance_symbols = params->dist.alphabet_size_max; StoreCompressedMetaBlockHeader(is_last, length, storage_ix, storage); @@ -1177,7 +1160,7 @@ void BrotliStoreMetaBlockTrivial(MemoryManager* m, BrotliWriteBits(13, 0, storage_ix, storage); tree = BROTLI_ALLOC(m, HuffmanTree, MAX_HUFFMAN_TREE_SIZE); - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(tree)) return; BuildAndStoreHuffmanTree(lit_histo.data_, BROTLI_NUM_LITERAL_SYMBOLS, BROTLI_NUM_LITERAL_SYMBOLS, tree, lit_depth, lit_bits, @@ -1206,7 +1189,7 @@ void BrotliStoreMetaBlockFast(MemoryManager* m, BROTLI_BOOL is_last, const BrotliEncoderParams* params, const Command* commands, size_t n_commands, size_t* storage_ix, uint8_t* storage) { - uint32_t num_distance_symbols = params->dist.alphabet_size; + uint32_t num_distance_symbols = params->dist.alphabet_size_max; uint32_t distance_alphabet_bits = Log2FloorNonZero(num_distance_symbols - 1) + 1; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/cluster_inc.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/cluster_inc.h index 22ecb3cca80..3d4f40e6012 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/cluster_inc.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/cluster_inc.h @@ -215,7 +215,7 @@ BROTLI_INTERNAL size_t FN(BrotliHistogramReindex)(MemoryManager* m, uint32_t next_index; HistogramType* tmp; size_t i; - if (BROTLI_IS_OOM(m)) return 0; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(new_index)) return 0; for (i = 0; i < length; ++i) { new_index[i] = kInvalidIndex; } @@ -229,7 +229,7 @@ BROTLI_INTERNAL size_t FN(BrotliHistogramReindex)(MemoryManager* m, /* TODO: by using idea of "cycle-sort" we can avoid allocation of tmp and reduce the number of copying by the factor of 2. */ tmp = BROTLI_ALLOC(m, HistogramType, next_index); - if (BROTLI_IS_OOM(m)) return 0; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(tmp)) return 0; next_index = 0; for (i = 0; i < length; ++i) { if (new_index[symbols[i]] == next_index) { @@ -259,7 +259,10 @@ BROTLI_INTERNAL void FN(BrotliClusterHistograms)( HistogramPair* pairs = BROTLI_ALLOC(m, HistogramPair, pairs_capacity + 1); size_t i; - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(cluster_size) || + BROTLI_IS_NULL(clusters) || BROTLI_IS_NULL(pairs)) { + return; + } for (i = 0; i < in_size; ++i) { cluster_size[i] = 1; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/command.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/command.h index 1aac85689be..d84e373d003 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/command.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/command.h @@ -20,14 +20,14 @@ extern "C" { #endif -static uint32_t kInsBase[] = { 0, 1, 2, 3, 4, 5, 6, 8, 10, 14, 18, 26, 34, 50, - 66, 98, 130, 194, 322, 578, 1090, 2114, 6210, 22594 }; -static uint32_t kInsExtra[] = { 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, - 5, 5, 6, 7, 8, 9, 10, 12, 14, 24 }; -static uint32_t kCopyBase[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 18, 22, 30, - 38, 54, 70, 102, 134, 198, 326, 582, 1094, 2118 }; -static uint32_t kCopyExtra[] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, - 4, 4, 5, 5, 6, 7, 8, 9, 10, 24 }; +BROTLI_INTERNAL extern const uint32_t + kBrotliInsBase[BROTLI_NUM_INS_COPY_CODES]; +BROTLI_INTERNAL extern const uint32_t + kBrotliInsExtra[BROTLI_NUM_INS_COPY_CODES]; +BROTLI_INTERNAL extern const uint32_t + kBrotliCopyBase[BROTLI_NUM_INS_COPY_CODES]; +BROTLI_INTERNAL extern const uint32_t + kBrotliCopyExtra[BROTLI_NUM_INS_COPY_CODES]; static BROTLI_INLINE uint16_t GetInsertLengthCode(size_t insertlen) { if (insertlen < 6) { @@ -89,19 +89,19 @@ static BROTLI_INLINE void GetLengthCode(size_t insertlen, size_t copylen, } static BROTLI_INLINE uint32_t GetInsertBase(uint16_t inscode) { - return kInsBase[inscode]; + return kBrotliInsBase[inscode]; } static BROTLI_INLINE uint32_t GetInsertExtra(uint16_t inscode) { - return kInsExtra[inscode]; + return kBrotliInsExtra[inscode]; } static BROTLI_INLINE uint32_t GetCopyBase(uint16_t copycode) { - return kCopyBase[copycode]; + return kBrotliCopyBase[copycode]; } static BROTLI_INLINE uint32_t GetCopyExtra(uint16_t copycode) { - return kCopyExtra[copycode]; + return kBrotliCopyExtra[copycode]; } typedef struct Command { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/compress_fragment_two_pass.c b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/compress_fragment_two_pass.c index f8a56063843..ca68b38139f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/compress_fragment_two_pass.c +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/compress_fragment_two_pass.c @@ -524,7 +524,7 @@ static void StoreCommands(MemoryManager* m, static BROTLI_BOOL ShouldCompress( const uint8_t* input, size_t input_size, size_t num_literals) { double corpus_size = (double)input_size; - if (num_literals < MIN_RATIO * corpus_size) { + if ((double)num_literals < MIN_RATIO * corpus_size) { return BROTLI_TRUE; } else { uint32_t literal_histo[256] = { 0 }; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/dictionary_hash.c b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/dictionary_hash.c index 3677d7ddb4e..16d853fe5aa 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/dictionary_hash.c +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/dictionary_hash.c @@ -13,1107 +13,1833 @@ extern "C" { #endif -BROTLI_INTERNAL const uint16_t kStaticDictionaryHash[32768] = { -32072,0,0,0,0,0,0,0,0,21860,0,0,0,0,0,0,0,40486,0,0,0,0,0,45798,0,0,0,0,0,0,1292 -,0,0,0,0,4964,278,23717,0,19972,0,0,0,0,0,0,0,0,0,0,0,0,2126,16102,0,0,0,14437,0 -,0,0,0,0,0,0,26727,2253,0,0,17252,0,0,0,0,0,0,0,0,0,3622,0,0,0,0,22984,0,0,0,0,0 -,0,16647,0,34247,0,0,0,0,0,48486,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2511,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,0,19532,0,0,24004,0,0,0,9828,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30853,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,0,31974,0,0,0,0,0,0,0,0,20650,2404,0,20773,1677,9031,0,6404,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51879,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6761,7206 -,0,0,21992,22983,0,0,3529,0,1864,0,0,0,0,0,0,11046,0,0,9641,0,0,0,6507,0,0,36934 -,21576,62375,0,0,0,0,0,0,0,0,0,8294,0,0,0,0,0,0,0,40807,0,0,0,39398,8136,0,0,0,0 -,0,0,0,8875,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7941,0,0,25609,0,0,0,936, -3716,3213,15687,0,0,0,0,0,52519,0,17381,0,0,0,0,1320,5797,0,21029,0,0,6472,807,0 -,0,0,0,0,0,0,0,0,0,13545,0,0,0,3624,0,0,0,29674,30820,0,31237,0,6596,0,0,0,0,0,0 -,0,0,0,64070,0,0,0,0,0,0,0,0,0,0,0,22278,0,37446,0,0,0,0,7240,423,0,24612,21705, -17636,0,0,0,0,0,0,1833,0,0,0,328,6021,0,0,0,19974,0,0,0,0,0,0,0,0,0,62119,4178,0 -,0,0,0,12100,8617,0,0,16900,0,36678,0,0,0,35366,0,51718,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,20998,0,62086,0,0,0,0,0,5542,0,0,0,0,0,0,0,0,0,0,0,14629,10952,25927,0,0,0 -,0,19849,0,0,0,0,0,0,0,30952,3046,14314,12998,0,0,0,15268,0,40582,30216,62118,0, -0,0,20132,0,0,0,0,0,12005,0,0,0,52358,0,0,0,0,24778,0,44,33095,0,0,0,0,0,26372,0 -,0,0,0,0,3781,0,0,17928,9479,0,0,0,0,0,0,0,0,32297,28613,0,0,0,0,0,0,0,0,0,0,0,0 -,0,47174,11723,0,0,0,0,0,0,0,0,0,2536,55143,0,0,6410,0,0,0,0,0,0,0,0,56294,11914 -,0,529,0,30184,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8261,0,0,28808,58854,22633, -965,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64135,0,0,331,3684,0,1605,0,0,0,0,0,0, -0,0,0,0,16650,37,0,23622,3144,15429,0,0,0,0,0,0,0,0,0,0,22443,69,0,0,0,0,0,0,0,0 -,17832,0,0,0,0,0,0,0,0,0,11113,0,0,0,0,18309,0,0,0,0,0,0,0,0,0,26630,0,0,25512, -25895,0,0,0,0,0,0,0,0,0,0,0,16901,0,0,0,27558,0,0,9418,0,0,0,3508,0,0,0,0,0,0,0, -0,37990,9289,8517,0,0,0,0,1578,1604,23944,0,0,14916,12781,0,0,0,0,0,0,0,12105,0, -16617,0,0,0,0,0,0,0,0,0,0,0,0,21348,11240,28870,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,5772,0,0,27812,0,0,0,0,0,0,0,8324,0,0,0,0,0,0,0,0,0,0,16748,1157,0,0,18794, -16324,25898,935,8333,0,0,0,0,0,0,0,0,18246,0,18086,0,46854,0,0,0,0,0,0,339,0,0, -25188,12780,12166,6409,0,0,0,0,16516,0,27012,28395,0,0,0,0,0,0,0,1420,0,0,0,9768 -,52967,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25163,324,0,0,0,0,0,0,0,0,0,64998,0,0,0,0,0, -21893,0,0,0,0,0,47366,0,0,0,870,0,0,0,12646,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,26020,16360,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1809,0,0,0,6601,15878,0,0,0,0,0, -29092,0,28516,0,0,0,0,0,0,0,0,0,21988,0,0,0,42950,0,0,0,0,0,0,0,0,0,0,5133,1318, -0,0,0,0,0,0,0,0,0,0,0,54982,24904,0,0,0,0,0,0,0,0,0,0,51526,0,0,0,0,0,3685,0,0,0 -,0,10062,9412,0,0,0,31460,5708,6181,0,0,0,0,0,0,0,0,0,5575,0,0,0,0,0,0,0,0,0,0, -27144,57478,0,0,0,0,0,0,7084,0,21993,53126,0,0,0,0,8397,0,0,5733,0,0,0,0,0,2116, -0,24742,0,11271,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1133,0,4873,0,0,38310,0,0,0,0,0, -0,0,0,0,0,0,0,17932,0,0,18053,0,0,0,25510,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17798,0, -26214,0,0,0,0,0,0,0,0,23016,17415,20392,164,0,0,0,0,0,0,0,0,0,0,0,3239,0,46119,0 -,0,0,28580,0,0,0,0,0,0,0,0,0,7621,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41478,0,0,31016, -55334,10056,1924,0,0,0,0,0,36614,0,36711,0,0,0,0,0,0,0,0,0,0,13994,59303,0,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,26501,0,5639,0,0,0,0,0,0,13897,1253,0,0,0,0,0,5095,0,0,0, -28869,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8646,0,0,0,0,25641,17796,0,0,0,0,0,0,0, -13316,620,6309,11819,0,0,0,0,0,0,0,0,0,904,1095,0,24229,0,0,28744,49703,0,23077, -0,0,0,0,32392,0,0,0,0,35271,0,28740,5866,0,0,0,0,0,0,0,4361,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,0,0,0,7917,8869,0,0,0,13924,0,0,0,0, -0,41958,0,0,0,0,0,0,6766,13989,0,0,0,903,0,0,24010,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,0,64390,0,22468,0,25861,0,0,0,0,23656,5317,0,0,0,0,0,0,23017,5445,16009 -,0,0,0,0,0,0,0,0,48006,10473,0,0,14404,0,0,0,42183,0,0,0,51270,0,0,10602,24132,0 -,0,0,0,0,43782,0,0,17834,0,0,0,25576,27205,0,0,0,0,0,0,0,0,29066,0,0,0,0,0,626, -1988,14700,0,0,0,0,0,0,0,0,0,0,0,0,57670,0,0,0,0,0,0,0,0,0,44710,0,0,0,0,3848, -7623,0,0,0,0,0,0,0,0,0,0,0,42374,0,0,0,0,0,0,0,0,19272,6436,0,0,5256,0,0,0,0,0,0 -,0,0,0,0,0,0,0,0,19685,0,0,0,0,0,0,0,0,0,0,0,0,0,39783,0,0,0,0,30984,0,0,0,0,0,0 -,28230,0,0,0,29028,10538,3205,0,0,0,0,0,0,0,0,0,0,0,5636,840,295,0,0,8488,8198,0 -,0,0,0,0,0,0,0,0,20580,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4074,19526,0,0,0,0, -31144,64038,0,0,0,0,0,0,16716,0,0,0,0,0,0,0,0,0,0,0,17706,0,0,0,0,0,0,50630,0, -50503,0,0,0,0,0,0,0,0,0,0,0,25446,0,0,0,13831,0,0,0,0,0,0,2696,4039,0,0,0,0, -25288,0,12076,2054,0,48934,0,0,0,0,16969,59431,17259,35335,0,0,0,0,0,0,0,0,0,0,0 -,0,31275,0,0,0,1097,0,0,0,0,0,0,0,0,0,0,0,776,839,0,0,29386,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,5864,12134,0,0,0,0,0,0,0,25349,0,0,0,0,0,0,0,0,0,61447 -,0,0,0,0,0,0,0,0,0,24678,0,0,0,63335,0,28836,8142,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,0,0,0,4494,0,0,0,0,0,14088,1188,0,16260,0,0,0, -16421,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,276,0,0,17060,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,24076,29445,0,33543,0,4901,0 -,0,12522,0,0,62471,0,0,0,0,0,0,0,0,0,0,4046,0,0,0,0,20486,0,15460,2217,51719,0,0 -,0,0,0,23495,0,0,0,0,0,0,15370,0,15849,0,15113,0,0,0,0,0,0,0,0,27972,7337,0,0,0, -0,30342,0,0,0,0,0,0,0,0,32299,23940,0,17766,0,0,0,0,0,0,6184,0,20904,0,0,0,0,0,0 -,0,0,0,0,31492,0,0,0,5509,0,0,0,0,0,0,0,0,2669,50182,0,0,12299,0,0,0,0,0,0,0, -5257,28167,0,0,0,0,0,0,0,0,0,0,0,11750,3890,0,0,26500,0,0,0,0,0,0,0,49318,0,0,0, -0,0,0,0,10981,0,0,0,0,0,0,0,0,17961,1831,0,0,0,0,0,0,0,29638,0,0,0,0,26473,0, -6216,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,711,0,0,0,0,0,0,0,0,0,0,28683,39975 -,0,0,0,0,0,51654,0,0,0,27527,0,0,0,0,0,0,0,0,30859,3268,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,28772,0,18212,0,0,0,0,25448,65446,0,0,0,0, -0,0,3337,1670,0,0,0,0,0,19332,0,0,0,0,24936,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1043,0 -,0,0,0,15814,0,21670,0,0,0,0,0,0,0,16263,0,0,0,0,0,0,0,0,0,32454,0,30630,0,0, -20170,9926,0,0,0,18247,0,0,14376,0,2056,17191,0,0,0,0,0,0,0,7812,0,0,0,0,0,0,0,0 -,0,0,0,0,0,0,22474,52806,1588,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10825,0, -0,0,0,40934,0,0,0,0,0,0,0,28677,0,0,5714,0,0,0,0,0,0,0,0,0,0,0,0,0,25865,22246,0 -,0,0,0,17256,35751,0,0,0,0,0,0,0,0,8236,0,32108,0,0,0,43,14342,0,16517,0,0,30732 -,0,4012,133,0,40583,971,23942,0,0,27275,0,0,0,204,0,0,27140,7564,44327,27592, -57958,0,0,0,0,22344,25701,0,0,0,0,0,0,0,19524,31755,0,0,28102,0,59111,0,0,0,0,0, -0,0,12261,0,44934,0,0,0,0,31560,0,11114,0,0,0,0,0,0,0,0,0,0,0,18953,18311,0, -45159,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2059,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -19399,0,0,0,0,0,0,0,0,0,0,0,0,0,58534,0,0,0,0,0,0,0,0,0,0,0,0,22411,23943,0,0,0, -0,0,0,11690,0,0,4069,0,0,2668,6342,0,0,0,0,0,0,27658,1766,0,0,0,0,23240,56070,0, -0,0,0,0,0,0,0,0,0,0,0,0,34119,0,24453,0,0,0,0,21867,0,17610,9894,0,0,27976,38790 -,0,0,0,43654,0,31559,12202,23142,0,0,0,50343,0,0,0,0,0,32806,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,0,0,0,0,0,49895,0,0,0,0,15786,4263,0,0,0,0,4746,3814,0,0,0,0,0,0,17192, -453,17323,0,20328,4036,0,0,0,15844,0,0,0,0,27561,31940,32296,0,0,0,0,0,0,0,11499 -,11782,0,0,0,0,9738,50471,0,0,0,0,0,35430,0,0,0,0,0,29734,0,0,0,36551,0,0,0,0, -9257,5606,0,13829,0,7015,0,0,0,0,0,25127,0,0,19051,0,0,0,0,0,0,0,0,0,0,0,0,0, -2572,0,0,0,0,0,0,29797,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42342,0,0,0,0,9293, -0,17896,56038,4077,0,0,0,29899,37351,0,30823,0,8326,0,0,0,18342,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18569,54054,0,0,0,0,0,0,0,0,0,37254,0,0,31433, -61510,0,2022,0,0,0,0,0,25381,0,0,0,0,0,0,0,0,0,0,0,0,0,2149,25289,0,0,0,0,0,0,0, -0,0,0,12516,14185,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8676,0,0,0,0,0 -,0,0,0,0,0,0,36486,0,0,0,0,10889,9607,0,28711,0,0,0,0,0,0,0,0,0,0,28490,0,0,0,0, -26181,10283,1701,0,0,0,0,0,0,0,0,0,14980,0,7783,0,27846,0,0,0,56486,3892,0,0,0, -5770,16583,0,26309,13422,20292,0,0,0,0,0,0,0,0,0,28742,0,0,0,0,14536,1158,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25801,0,0,0,0,0,0,0,0,0,0,0,0,42438,0,3332,0,0 -,0,0,0,0,0,0,0,8327,0,0,0,0,0,0,0,0,0,0,0,0,17353,1447,0,0,8427,48518,1359,0,0,0 -,0,0,14986,0,32168,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9230,2791,0,0,0,0,0,0,0,0, -16073,31623,4269,0,0,0,0,0,0,4519,0,0,27912,58950,0,0,0,0,0,0,0,0,8361,19812,0,0 -,0,0,6056,7877,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21701,0,0,0,0,0,0,0,0,0,0,0 -,0,9128,1125,0,16548,0,0,0,0,0,0,0,0,0,0,17292,6854,21352,0,2380,0,0,4007,0,0,0, -0,0,24357,4202,0,0,0,0,0,0,0,0,0,0,0,0,0,10664,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,42823,3022,0,0,0,0,0,0,0,0,0,0,0,0,14373,0,20677,3304,2759,20522,64903,0, -0,0,38,0,0,0,0,0,0,0,0,0,0,0,27814,2802,8870,3758,1255,0,0,0,0,0,0,0,0,30027, -9510,0,0,0,0,17864,14855,0,0,0,0,0,0,0,0,0,0,23404,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -51462,0,0,0,0,0,0,0,45734,0,0,23467,32327,0,0,10826,52999,0,0,0,33222,31336, -64326,0,0,0,0,0,0,0,32166,0,0,3891,0,0,0,7017,645,0,0,0,0,0,0,27915,46087,0,0,0, -21863,0,34246,0,0,16715,0,0,0,0,14052,21416,0,0,0,0,0,0,0,0,39846,0,0,0,0,0, -38982,0,0,17512,7460,0,0,0,0,0,0,0,0,0,15428,0,0,0,0,0,0,0,28356,0,0,0,0,0,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,25445,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11879,0,0,0,0,0,0 -,0,0,0,0,0,0,0,19911,0,20007,0,0,0,10855,943,0,0,10821,0,0,0,0,4170,0,0,0,0,0,0, -0,0,0,9836,0,0,0,0,0,0,0,0,0,0,65415,0,0,0,0,0,0,0,0,9865,24646,0,0,0,0,0,40519, -0,0,0,0,0,0,0,0,0,12804,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22091,23655,0,0,0,0,0,0, -0,31686,0,0,0,58599,0,0,0,0,0,0,0,0,0,0,0,0,0,19620,0,0,0,0,0,0,0,0,0,0,0,0,0, -24421,0,28100,0,0,0,31268,0,3204,0,0,0,0,0,0,0,0,0,14822,0,0,0,0,19947,10182,0,0 -,9480,14821,4398,0,0,14532,0,0,0,48871,1873,0,0,0,0,0,0,0,589,1541,0,0,0,0,0, -23333,0,0,0,14149,0,0,0,0,1296,14374,0,27300,0,0,0,0,0,0,7276,0,0,0,0,0,0,47718, -0,0,0,0,0,0,0,0,0,0,5164,1765,0,14405,0,37574,1994,0,6636,0,0,0,0,0,0,0,0,27815, -0,0,0,0,2568,6820,0,0,0,0,0,0,0,0,0,0,11336,26247,0,0,23912,0,0,0,30536,0,0, -34342,0,17799,0,0,0,22149,0,6118,0,25732,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,26600,5190,0,0,1142,0,0,0,0,0,0,0,0,39527,0,0,0,0,0,39494,0,0,0,0,0,0,0 -,0,0,0,3085,0,0,0,0,0,0,0,4786,0,0,0,28873,6532,0,0,26664,0,9193,11719,0,0,0,0,0 -,0,31752,64646,0,0,0,0,0,0,0,0,0,0,0,11397,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25094,0 -,0,18153,20167,0,0,0,17254,0,0,878,0,0,0,0,0,0,0,0,0,0,24166,0,0,0,0,0,0,0,0,0,0 -,0,0,26059,0,0,0,0,0,0,0,0,0,0,0,0,0,31592,0,0,8167,24362,6212,0,34758,0,0,0,0,0 -,0,32520,0,0,44679,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17989,8681,29222,0,0,0, -0,0,0,0,0,10251,4902,1452,15207,0,0,0,0,0,0,0,22822,0,10469,0,0,0,0,0,0,19337, -17670,107,11494,0,0,0,0,27305,2565,0,0,0,0,0,0,0,64518,200,28389,0,0,0,0,31208,0 -,30762,0,0,0,0,0,29321,60518,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3209,3237, -12490,22663,0,0,0,18789,31464,16391,0,0,0,0,0,0,0,0,0,0,0,20646,0,0,0,27238,0,0, -0,0,0,15940,4488,6951,0,0,0,46342,0,0,0,0,0,0,0,0,0,28965,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,20584,3367,0,25350,0,0,0,0,0,0,0,0,0,0,0,0,1814,0,0,0,0,0,0,0,0,0,0,17125, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,55943,0,0,0,0,0,24133,0,0,0,0,0,0,0,0,0,0,0,0,2929 -,0,0,50086,0,2918,25356,30052,115,11846,0,0,0,0,3056,0,0,0,0,17639,239,19815,0,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36806,0,0,0,0,0,0,0,0,0,0,0,0,0,21479,0,0,0,0,0, -28420,11786,4772,0,0,3368,36295,0,31463,0,0,14665,996,0,20582,0,0,0,9988,0,23685 -,0,0,0,52551,0,0,0,0,0,0,0,7556,0,0,0,0,0,0,0,1895,2186,0,0,0,0,0,27755,25447,0, -0,0,0,31052,63270,0,0,0,0,0,0,0,36742,0,24804,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,31048,0,0,0,0,0,0,0,0,0,21290,2276,0,0,0,0,26475,0,0,0,0,0,0,0,0,0 -,0,15332,0,0,0,0,0,0,0,0,3176,19431,0,0,0,0,0,0,0,62726,0,0,0,25380,0,0,27883, -1316,0,0,7724,3015,0,0,0,0,6697,0,0,47910,0,0,0,0,0,0,0,0,0,3141,0,0,0,14820,0,0 -,0,0,9326,0,0,0,0,0,0,0,0,0,0,31493,0,0,0,0,0,6566,0,0,0,0,0,0,6569,1348,0,25638 -,0,0,0,0,0,20324,0,0,17067,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11876,0,41030,0,0,0,26405 -,0,0,0,0,0,0,0,0,0,11431,28137,14950,0,10151,0,0,0,0,0,0,0,29574,0,0,0,0,27176, -57446,0,0,0,0,28650,57574,1387,0,0,0,0,0,0,0,0,0,0,58247,0,0,0,0,0,0,0,16805,0,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3526,0,15781,0,5572,13352,0,0,0,0,0,18665 -,23463,0,0,0,0,0,0,15405,6885,0,0,0,0,15272,0,0,0,0,0,0,0,0,9861,0,0,0,0,0,0,0,0 -,9512,4037,0,0,11563,49639,0,0,0,0,0,0,27880,57830,0,0,0,0,0,41831,0,21924,0,0,0 -,0,0,0,0,25509,0,27462,0,18085,0,0,0,0,0,0,0,0,0,0,0,0,13898,8068,26441,0,0,0,0, -0,0,25316,0,0,0,0,16298,7397,5706,19239,0,0,0,0,0,0,0,0,1392,50919,0,0,0,0,0, -53863,0,0,0,0,1451,0,0,0,0,0,0,0,0,0,0,35847,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,17801,15813,0,12740,0,0,0,32967,0,0,0,0,0,0,5389,0,0,0,0,0,0,0,0,0,0,31143,0, -20548,0,0,0,0,0,0,0,0,0,51686,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -12109,19015,0,34983,0,21732,3600,0,0,0,0,47750,17288,43975,22857,47559,0,0,0,0, -26408,48358,0,0,0,0,0,0,0,0,0,0,0,0,0,30470,0,0,23560,4581,0,22404,0,49286,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,49831,0,0,0,27525,31691,7,0,0,25835,0,0,0,0,0, -4201,16485,0,20676,0,0,0,0,3753,23303,16264,3878,0,0,0,0,0,0,11434,0,0,0,0,0,0, -7589,0,0,0,0,0,0,0,0,0,57095,0,0,0,0,0,0,0,0,0,0,0,22820,11146,49158,0,23623,0,0 -,0,0,0,0,0,13893,0,0,0,0,0,0,11722,60071,1258,0,0,0,0,0,0,18564,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,27945,0,0,0,0,5479,0,20006,17608,3431,10988,30180,0,0,0,0,0,0,0, -24581,14,0,0,0,0,0,0,25572,0,0,0,28612,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53543,0 -,0,0,0,0,0,0,0,0,0,0,33670,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8710,0,14116,0,0,116, -292,0,0,0,37831,0,43078,0,0,0,0,0,0,0,0,21832,0,0,32134,783,0,0,30982,0,0,0,68,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,5932,0,0,0,18505, -15175,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3630,16965,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,17797,0,0,0,0,0,0,520,42150,0,0,3122,0,0,0,22506,0,0,0,0,0,0,0,0,28550,0, -0,0,50278,0,0,13641,5958,0,35238,0,0,0,0,0,0,0,0,29993,18724,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,0,0,20619,9319,0,0,0,0,23977,0,5193,0,0,12196,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,24390,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20105,677,0,0,0,0 -,0,0,0,0,29419,0,0,0,0,0,0,0,0,0,20266,0,0,0,0,10631,0,0,0,0,0,0,0,0,0,47655,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,26628,12744,0,20648,0,0,0,432,0,0 -,0,0,0,0,0,0,0,0,646,0,25604,0,0,0,0,0,0,0,0,0,0,0,0,0,63782,0,0,0,0,24616,0,0,0 -,21291,0,0,0,0,0,0,0,0,0,0,45638,0,0,0,0,1931,0,0,0,20521,59975,0,20614,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,56231,0,0,0,0,0,29991,0,52871,0,20934,0,0,0,0,0,0,0,16871, -0,0,0,0,0,0,0,0,0,0,0,0,0,7237,0,0,0,0,0,47558,0,0,0,0,0,0,0,0,0,0,0,10406,0,0,0 -,0,0,0,0,43046,0,0,2930,0,12936,0,0,0,0,0,0,0,0,0,0,0,0,31141,0,0,0,0,0,0,0, -37639,0,17572,0,0,0,0,0,0,0,0,0,0,31240,0,0,0,0,0,688,0,0,0,0,0,1648,0,0,0,0, -10055,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,146,0,0,0,0,0,0,0,0,0,6345,199,0,34982,0,0 -,0,0,0,0,0,0,0,0,0,0,0,56839,0,0,0,0,0,48902,0,13412,0,0,0,0,0,0,0,0,2441,4420,0 -,0,0,0,20428,933,0,0,0,0,0,0,0,45383,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,54726,0,0,0,0,0,0,0,0,0,0,0,0,17036,741,0,0,0,0,0,0,0,27589,0,0,30282 -,18950,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2248,0,0,0,0,0,0,0,0,0,25993,0,0,0, -2443,0,0,31622,0,14150,0,0,0,28679,0,0,0,0,0,0,15464,0,0,0,0,54694,0,0,0,0,0,0, -3827,0,0,0,3756,0,9897,0,0,0,0,0,19082,31239,0,0,0,0,0,0,0,0,0,0,0,24580,0,0,0,0 -,0,0,0,0,0,16580,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27625,0,0,0,784,4647,32652,0,0, -63494,0,0,0,0,0,0,0,21062,0,0,0,0,0,0,0,0,0,0,3404,58470,0,32325,0,0,0,0,0,0,0,0 -,0,0,0,0,0,0,0,0,18634,2789,0,0,0,0,0,0,0,8548,0,0,0,22501,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,15881,0,0,0,0,35879,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7978,17956,0,0,0, -0,0,0,0,24324,0,0,4937,0,0,0,8168,0,13420,10340,0,0,0,0,0,11780,0,0,0,0,0,0,0,0, -0,0,16712,0,0,0,0,0,0,0,17640,17991,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,2953,0,0,0,0,0,0,0,9100,16806,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30667,0,0, -19013,0,0,0,0,0,0,205,15334,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1969,0,0,0,0,0,0,0,26248 -,52518,0,49798,0,0,0,0,0,0,0,9668,0,0,0,0,0,4742,0,0,21641,0,0,0,0,0,0,53574,0,0 -,0,0,0,0,5707,0,0,0,0,0,0,0,3018,12454,0,0,0,0,2920,262,0,0,0,0,0,0,0,0,0,0,3593 -,0,0,0,0,0,0,0,0,0,0,23910,0,0,0,0,0,0,0,55879,0,0,0,0,0,775,0,43270,5066,48967, -0,0,22986,4165,8971,44838,0,0,0,0,0,62279,272,0,0,0,0,51430,0,0,0,0,0,0,28234,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13349,0,0,0,51111,20265,13861,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,585,7494,0,0,0,0,0,0,0,0,21768,62407,0,0,0,0,7979,166,0, -0,0,0,0,0,0,0,0,38918,0,56742,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16296,5767,0,0,0,0,0,0 -,0,32068,0,0,0,0,0,0,0,0,0,0,0,0,0,29796,0,0,0,0,0,0,0,0,23916,30183,0,58791,0,0 -,0,0,0,0,0,20518,0,0,0,0,8969,0,0,0,183,0,0,0,0,0,2314,17445,0,0,0,0,0,0,0,0,0, -23748,0,0,8139,4839,27914,0,0,0,0,0,0,0,0,0,0,0,0,29478,0,0,16552,26663,0,53767, -0,0,13960,8039,18696,0,0,0,0,0,0,0,0,0,0,0,782,16005,0,0,0,0,0,0,0,0,6258,56806, -16456,12455,0,0,0,0,0,0,0,23780,0,0,0,0,0,0,9355,0,0,0,7273,41063,24780,57766,0, -0,0,0,0,0,0,0,0,0,3820,2597,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29225,61126,0,0,0,58439, -15691,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37190,22408,967,0,0,0, -23078,26858,0,0,0,19753,0,0,0,0,0,0,0,0,0,5416,13702,0,0,0,0,0,52742,20394,38567 -,0,0,0,51079,0,0,136,8516,0,0,0,0,0,0,0,0,0,0,0,27588,0,0,0,0,0,0,0,0,0,0,531,0, -0,0,0,0,0,0,0,0,8936,5031,12520,19334,0,0,22827,30247,28074,31140,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,27497,18148,20104,59079,0,0,0,0,0,0,0,0,0,24389,0,0,6125,0,0,0,0, -9541,0,0,24553,29095,0,0,0,0,0,0,0,25444,0,0,9643,0,0,63047,0,0,0,0,0,0,0,0,0, -39558,0,0,0,0,0,0,20620,11815,499,0,5128,2278,0,0,0,0,0,46310,0,0,0,0,0,0,0,0, -23530,40166,2440,0,0,0,0,0,0,0,0,0,0,15174,0,0,0,0,0,0,0,0,0,0,26922,0,0,0,0,0,0 -,0,0,0,0,26758,0,0,0,0,0,51911,0,0,23532,0,0,0,0,51238,25737,44486,12622,0,0,0,0 -,0,0,3078,0,9253,0,0,1128,22023,0,0,0,21350,0,16420,0,0,0,0,0,0,0,65094,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22532,0,48774,0,34503,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,9797,0,0,0,0,0,0,0,13797,0,38279,0,0,1738,0,489,46343,0,45382,0,0,0,0,0,0, -0,0,0,29030,0,0,0,0,0,0,6220,56550,0,0,0,0,0,26885,0,28806,0,0,0,0,0,0,0,0,0,0,0 -,45958,0,0,0,0,20553,49927,0,0,0,0,0,0,3019,12358,0,0,0,0,0,0,0,0,0,0,26571, -13319,0,0,653,23399,0,0,0,0,0,0,0,0,22316,0,0,21188,0,0,0,0,0,0,0,0,0,27556,0,0, -0,0,0,0,0,27878,21483,27653,0,29701,237,0,10632,0,0,0,0,33766,0,0,0,0,0,0,31563, -0,0,0,0,0,1416,2439,0,0,0,0,0,0,0,0,0,0,9611,0,0,0,0,0,0,0,5611,16581,26601, -35462,0,0,0,26756,0,59271,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26984,57734,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,7882,0,0,0,19528,6469,0,0,1161,0,0,0,7688,20935,425,0, -0,0,0,0,0,0,0,12519,0,12902,0,0,0,0,0,0,0,0,0,0,2411,0,11725,26086,0,0,20201,0,0 -,0,0,0,0,0,0,11045,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30471,0,0,0,0,0,0,0,0,0,0,0, -21541,1141,21190,0,9188,0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,1093,0,0,0,0,0,0,0,0, -4842,0,13672,0,0,12230,0,0,0,10532,0,0,8937,0,0,0,0,0,0,0,0,0,0,28996,0,0,11720, -26982,0,46182,0,43911,31754,0,1160,3940,0,20772,0,0,0,0,0,24549,0,32582,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,31845,0,0,0,0,0,0,0,2310,11788,0,0,43047,0,0,0,18853,0 -,0,0,0,0,0,0,0,0,63622,0,0,7048,17318,0,0,0,21957,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,1039,6279,0,0,0,0,0,0,0,0,0,0,0,0,0,12197,0,0,0,0,0,0,0,0,0, -46470,0,0,24,19719,0,0,0,0,0,0,0,0,0,39335,0,0,0,0,0,0,0,0,0,0,21353,3846,0,0,0, -0,0,0,0,36679,0,0,0,0,0,0,0,0,0,0,0,11268,0,0,0,0,0,9382,0,0,0,0,0,0,0,0,0,0,0,0 -,0,29926,0,33606,0,4708,2828,0,0,29543,0,0,0,0,0,29893,0,0,0,0,0,0,0,0,3663,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,10920,7111,0,0,0,0,0,0,0,0,0,0 -,9384,0,0,0,0,0,0,0,0,0,0,0,0,20388,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37094,0,0,0, -27110,0,0,0,0,0,0,21865,0,27753,30214,0,0,0,0,0,57895,0,0,0,0,0,0,0,0,0,0,12648, -5446,0,0,0,0,0,0,0,0,0,0,19784,17124,0,52007,0,0,0,0,0,0,0,0,758,0,0,0,0,0,0,0,0 -,0,0,0,0,0,0,0,0,0,0,24900,0,0,0,0,0,1476,0,65031,0,0,1205,46663,0,30023,11625, -1094,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10058,0,0,0,0,0,0,28455,0,0,0,0,0,0,0,0,0,0,0, -14788,0,0,0,0,16808,0,0,742,0,0,0,0,0,0,0,0,0,0,0,21636,0,0,0,0,0,0,0,0,0,0,0,0, -15944,23207,0,0,0,0,247,0,0,0,0,24743,0,0,0,5252,0,0,0,0,0,0,0,0,29961,18660, -21099,46791,0,7045,0,0,0,0,25707,0,0,17412,3828,0,0,0,0,0,0,0,0,0,0,0,5803,5637, -0,38151,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60103,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,853,0,0,0,0,0,0,30215,0,0,0,0,0,0,0,8741,0,0,0,0,0,27366,0,0,0,0,171, -4070,0,0,0,0,0,0,0,0,24073,7366,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2184,5189,0, -20932,1545,4996,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,7684,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,6313,0,0,0,0,0,0,0,30826,0,0,0,0,0,0, -0,0,0,0,27463,0,0,0,0,0,0,0,0,0,0,21640,63303,0,0,3275,31111,0,0,0,0,0,0,0,11556 -,0,14756,0,0,0,15108,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23914,28966,0,0,0,4965,0,0,0,0, -0,0,0,0,0,0,10216,5223,0,0,0,0,0,0,0,0,0,27142,0,0,1173,20198,0,0,0,0,0,56614,0, -0,0,0,0,4612,0,0,0,0,0,0,0,0,0,0,11822,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17769,7910, -0,0,31880,0,0,6055,0,0,0,0,0,0,0,0,0,0,8970,0,0,0,0,0,0,0,0,0,0,0,16840,23879,0, -0,11051,0,0,0,32552,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20842,13701,0,0,0,37191,7373, -10471,17482,25348,0,0,0,38502,0,0,0,0,0,0,0,0,0,21509,6058,0,0,0,0,0,0,3173,0,0, -0,9543,0,0,0,0,0,0,17768,12708,0,0,0,0,0,37030,0,0,0,0,0,0,0,0,0,0,12748,48743,0 -,11718,0,0,25194,0,0,0,9033,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5028,0,30118,0,0,0,0,0, -42759,0,0,3720,0,0,0,0,0,0,25190,0,0,0,0,0,0,0,0,0,0,5450,5125,0,58086,0,0,0,0,0 -,27716,0,0,0,0,0,0,0,0,0,22052,0,0,0,0,26249,0,15947,3460,0,0,0,35814,0,0,0,7813 -,19500,32167,0,18597,0,0,0,0,0,28644,0,0,0,60743,0,0,0,0,0,29636,0,0,0,0,0,0,0,0 -,0,0,0,0,0,17220,15885,9414,9642,0,0,0,593,0,0,24228,0,0,0,0,0,40422,0,26244,0, -23109,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64902,0,0,0,0,3979,60007,0,0,0,28199 -,0,0,0,43142,0,0,0,0,0,0,0,29158,0,30532,0,0,0,0,13256,0,0,0,0,16549,0,0,0,0,0, -26116,0,0,0,0,0,0,0,0,22825,0,0,0,0,0,0,0,1065,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,18985,4805,0,0,0,0,0,17702,0,0,0,0,0,0,0,0,0,0,3468,0,0,0,0,13447,0,0,0 -,0,0,0,0,0,0,0,0,56871,0,0,1776,15780,0,0,2603,0,10280,31366,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,11592,3591,0,2372,0,0,0,0,0,0,0,20004,0,0,0,0,0,0,12072,518,0,0,1960, -8999,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7178,32999,0,0,0,0,0,0,1641,0,0,0,0,0,0,0,6764, -9893,490,4005,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25258,5541,0,14053,306,20743,0,0, -9422,0,0,0,0,0,0,0,11977,260,0,35175,0,0,0,0,0,0,0,18405,0,0,0,16582,0,0,0,22470 -,0,0,0,0,0,0,2792,0,0,0,14026,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14858,3909,0,0,0 -,57671,0,0,0,0,0,0,15979,0,0,0,2794,15239,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26884, -9070,0,0,0,0,51846,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19499,37127,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,0,19205,10350,11910,0,0,0,0,15083,23108,0,0,0,0,0,0,0,0,0 -,0,0,0,0,0,0,0,169,0,0,0,0,0,0,0,0,0,0,0,15274,41735,0,56774,0,0,2825,0,14025, -389,0,0,0,0,0,0,0,0,21482,31910,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20456,710,0,0,25032, -21797,0,0,0,0,0,0,0,0,0,0,32427,21252,0,30150,0,43174,0,0,0,0,0,0,0,0,0,0,0,0, -11403,0,0,1029,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6892,9252,0,63206, -3496,14406,0,0,0,0,0,0,0,0,0,0,22568,0,0,21253,0,0,0,0,0,0,0,39623,0,0,10189,0,0 -,0,0,0,0,0,0,0,0,0,0,0,30729,59910,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3305,0,0,0,0,0,0, -0,0,0,7660,24871,0,838,0,0,0,0,0,0,0,0,0,0,0,0,12013,13252,0,551,0,0,0,43207,0, -30567,0,0,0,0,0,0,0,0,28394,30724,0,0,0,0,0,0,0,0,0,0,22665,22725,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,29414,0,0,0,0,16074,8966,245,1445,0,0,0,0,24872,0,0,0,0, -13124,0,35527,0,0,0,0,0,0,13259,10917,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -25191,0,0,0,13956,0,0,0,0,0,0,0,54631,19625,12070,3083,0,0,0,0,14436,0,0,0,0,0,0 -,0,0,0,0,0,0,0,21766,0,15463,29322,0,0,0,0,0,0,29990,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,23653,0,0,0,0,0,0,0,0,2643,0,0,21223,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,4114,0,0,0,0,0,0,0,0,34790,0,0,0,0,0,0,0,16103,0,0,0,0,0,0,297,3620,3338, -10372,0,14727,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29924,22473,13895, -15529,32455,30378,13540,0,28807,0,0,0,0,0,0,0,64582,18380,0,0,0,0,0,0,0,0,0,0,0, -0,38598,0,0,0,0,0,0,0,0,1236,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32710,0,0,0,0,4590,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64935,0,0,0,0,0,0,0,0,0,0,0,0,16744,0,0, -0,0,0,0,20005,0,0,13608,1191,0,0,0,62183,0,0,0,0,0,24484,0,0,0,0,0,0,0,0,0,0, -17643,0,0,0,0,0,0,0,0,0,0,0,0,5380,0,0,32328,0,0,63814,0,0,0,2919,0,0,0,0,17034, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,60295,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,7690,486,0,0,0,39270,0,49094,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12555,0,0,0,0,0,0,0,0 -,0,0,0,0,20967,17993,12647,0,0,0,16036,32616,0,0,0,0,16294,8555,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,35174,0,0,0,0,0,0,30346,0,0,0,0,0,0,0, -14797,3652,0,0,8268,12934,0,54950,0,0,0,0,2632,33959,0,23175,0,0,0,0,0,36262,0,0 -,0,0,0,0,32684,26918,0,32676,0,0,0,0,0,0,0,0,0,0,15625,11943,1206,0,0,0,0,18052, -0,0,0,0,0,16422,0,0,0,26404,0,0,28777,0,0,24902,0,0,408,45351,0,35719,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,3658,17446,0,165,0,0,0,0,0,0,0,6151,0,0,24424,0,0,0,0,0,0,0, -24170,24293,0,0,0,0,0,0,0,0,0,11847,0,39591,0,0,0,0,0,0,9549,2788,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,1010,0,0,0,0,0,0,26055,31724,0,24233, -1828,0,0,0,0,0,0,0,0,0,17284,0,0,0,0,19464,0,0,0,0,0,0,0,0,32452,0,0,0,28871,0,0 -,0,0,17704,53383,0,0,0,0,0,0,0,0,0,17892,1938,0,0,0,0,0,16362,0,0,21605,0,0,5003 -,0,0,0,0,0,0,22693,0,22342,0,0,0,55846,0,0,0,0,0,0,0,0,0,22853,0,0,0,0,0,0,0,0, -6600,263,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24836,0,0,0,0,0,0,0,0,0, -40711,0,0,0,0,0,33894,0,0,0,0,0,0,13000,0,0,0,0,0,0,0,0,0,0,30308,0,0,0,0,0,0, -5386,0,0,0,0,0,0,27844,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17740,0,0,0,0 -,25093,29064,0,0,0,0,0,0,0,12680,11462,0,0,0,0,0,0,0,0,84,7303,0,0,0,0,0,0,0,0,0 -,0,0,27044,457,0,22924,58246,19016,0,2606,45703,0,5157,0,25028,0,0,0,0,0,0,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,2065,0,0,0,0,0,31946,0,0,0,0,0,0,0,0,0,0,0,0,33382,0, -47878,0,0,0,0,0,0,0,0,25004,0,0,0,0,0,0,0,26153,35654,0,58055,30668,0,0,0,0, -25988,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4456,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,7560,20583,0,0,0,0,0,0,0,0,0,37510,0,0,0,0,0,0,0,0,0,42822,0,0,0,0,0,0,0,0, -0,0,0,1733,0,0,0,8196,0,0,11241,0,30572,60326,0,15013,0,0,0,40646,0,23812,0, -10022,0,0,0,0,0,0,0,0,12874,31015,0,0,0,0,0,0,1608,0,0,0,0,18308,0,0,0,0,27114,0 -,0,0,0,0,0,0,7944,1382,0,11813,0,0,0,0,0,0,0,0,0,0,0,0,0,24517,0,11621,0,0,0,0,0 -,0,0,0,0,0,0,21702,0,0,13100,8262,2644,7973,0,0,0,0,0,0,0,0,0,0,0,0,1033,12581,0 -,25221,0,0,0,40998,16301,62983,0,0,0,0,1263,9318,0,0,0,18854,0,0,1741,33895,0,0, -0,0,0,0,26377,0,0,0,0,0,0,0,0,0,0,32165,0,51143,0,0,0,0,0,29412,0,0,0,0,0,0,0,0, -1674,4230,0,0,0,0,0,10502,0,0,0,0,5545,0,0,0,0,0,2099,45158,0,0,0,0,0,0,0,0,0,0, -14157,0,26955,0,0,0,0,0,0,0,0,0,17096,0,0,0,0,0,0,0,0,0,0,0,0,0,27050,6726,0,0,0 -,0,0,0,0,0,28554,0,0,7142,0,0,0,0,16936,0,0,0,25833,0,4399,6980,0,46214,0,0,0,0, -0,10630,21164,0,0,0,0,0,0,0,2446,48551,0,0,0,0,0,0,0,0,0,0,0,13381,0,0,0,0,0,0,0 -,0,15400,12135,0,0,0,0,0,4774,586,0,0,0,0,0,0,0,0,23751,9736,4548,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,25577,29607,6250,1637,0,0,0,0, -22024,0,0,0,0,22308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37414,24044,0,0,0,14474,29735, -0,7077,0,45990,0,0,0,0,30568,40039,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -6150,0,4228,0,0,0,0,0,27687,0,0,0,0,0,0,0,24548,21513,1350,0,0,0,33607,0,0,0,0,0 -,0,0,0,11784,1414,0,0,0,0,0,0,0,18244,940,0,0,0,0,0,0,7270,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,16709,0,0,0,0,0,0,0,48935,0,0,0,0,0,0,23660,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,53350,0,0,0,0,0,0,4236,16358,0,4422,6665,32644,0,0,744,18084,0,11014,0,0,0,0,0, -29508,0,0,0,0,0,0,0,7686,0,0,13289,5478,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,12872,0,0,24134,1005,22916,0,31429,23400,0,0,0,0,0,0,0,28424,0,0,0, -25706,27109,0,0,26345,0,0,0,0,0,0,25126,0,0,88,0,0,0,0,0,0,0,17032,0,0,21799,0,0 -,10060,0,12296,21892,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20777,14311,0,58182, -32232,0,10282,0,2121,11527,0,0,0,12325,0,0,0,0,0,0,0,28804,2344,8133,0,0,0,0, -21864,62695,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,2771,0,0, -23204,0,0,0,0,0,6278,0,0,0,0,0,26597,0,0,0,0,23144,0,0,0,0,0,31816,20070,0,0,0,0 -,0,0,0,0,0,0,24456,2118,0,0,0,0,6570,1156,0,0,0,0,0,0,0,30406,0,0,0,28388,3572,0 -,0,26599,12426,5286,0,0,0,0,0,4967,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24970,24167,0,0,0 -,0,28745,4678,0,0,0,0,0,0,0,1444,236,0,0,0,0,0,0,0,0,19428,0,0,0,0,0,0,2092,0,0, -0,0,0,0,0,0,0,2827,0,0,0,0,0,19881,19204,0,11749,0,0,0,0,0,0,0,17958,0,17894,0, -18726,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9190,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,21510,5033,0,0,0,0,22855,0,0,0,0,0,14598,0,29605,0,0,0,0,0,0,0,0, -617,0,0,0,0,47142,0,0,0,0,0,0,0,0,0,0,3627,0,0,0,0,0,0,0,0,0,0,0,0,0,2225,14823, -0,0,2637,6182,78,15078,0,0,0,0,20264,0,0,0,0,0,0,36743,4140,44551,17352,25703,0, -0,0,0,0,0,0,0,0,0,0,0,14024,0,0,0,0,0,0,28004,0,0,0,0,0,7588,0,0,0,0,0,0,0,2087, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18028,0,0,0,300,14212,0,0,1386,40327,0,0,0,0 -,0,0,31082,0,0,22374,0,0,0,0,0,35718,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -26532,7756,0,0,18982,0,0,0,0,0,0,0,0,6440,1159,7180,0,0,0,0,0,0,45766,0,57798,0, -16740,0,0,6802,60454,0,0,0,26470,0,0,0,0,0,65382,4362,7750,0,0,0,0,0,0,9096,4743 -,334,0,0,0,0,0,0,39974,0,0,0,25828,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3027,0,0, -0,15816,0,0,0,0,0,0,0,0,48327,0,0,0,0,0,0,0,0,0,0,16168,41799,0,0,24458,8581,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,12292,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,0,0,0,54503,0,0,0,0,5097,30852,18664,0,0,0,0,0,0,16484,0,0,27337,0,0,0, -0,0,0,0,0,0,0,0,0,35942,0,0,0,0,0,0,0,4356,0,0,0,0,0,57030,0,0,1417,41191,0,0,0, -0,0,23429,0,0,0,0,10024,21735,0,0,10126,0,0,0,0,19046,0,0,0,0,0,0,24105,4710,0,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4394,0,0,0,0,13253,0,56391,0,0,0,0,0,0,0,0,0,0, -0,19174,0,0,0,0,0,0,0,0,0,55974,0,0,0,52070,0,15620,0,0,0,0,0,2660,0,0,0,0,21644 -,0,0,52455,0,0,0,0,0,0,0,0,0,8902,0,0,0,0,0,0,3116,0,464,34726,0,0,0,0,0,0,25003 -,12423,0,27172,1896,7335,0,0,0,0,0,35686,0,0,0,0,3472,0,0,0,0,22406,0,0,0,0,0,0, -0,0,0,45254,0,0,0,0,0,0,0,0,0,0,0,0,0,21124,23594,33127,0,0,0,0,0,0,16684,22087, -0,0,0,0,0,0,0,0,0,0,0,0,8714,0,0,0,0,0,0,0,0,0,0,55814,0,0,0,0,0,0,4109,23460,0, -0,8874,0,0,0,0,0,0,0,0,0,147,0,0,0,0,0,0,0,0,0,0,0,0,0,29960,63398,1302,0,0,0,0, -0,0,0,0,24806,0,0,0,0,0,0,0,0,0,9799,0,0,0,0,0,0,0,31333,0,0,0,0,0,19557,0,0,0,0 -,0,5701,0,0,0,63014,0,0,0,0,0,0,0,21254,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12484,0,0, -0,48326,0,0,0,0,0,0,0,0,0,0,0,15783,0,0,1202,0,0,0,0,23174,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,3086,49191,0,0,5387,15141,0,0,0,3365,0,0,0,0,20076,14021, -0,0,0,0,0,0,0,0,0,0,376,40198,0,0,0,52039,0,24932,0,0,0,0,808,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,9860,0,0,0,0,0,23719,0,21476,0,0,0,0,20776,4807,0,0,3177,16678,0,0,110 -,10853,0,0,0,17382,0,0,0,0,0,0,0,0,0,43462,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,7500,4966,0,0,0,0,0,0,0,52102,0,24516,0,0,0,0,0,0,0,0,0,0,0,0,0,26535,0,0 -,0,46247,0,0,0,15557,0,0,0,0,76,52327,0,0,0,0,17866,0,0,0,0,0,0,0,0,0,0,46758,0, -0,0,0,0,19173,0,0,0,0,0,0,0,0,0,44038,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2985,0 -,0,0,0,0,0,14310,0,0,2125,45831,0,0,0,0,0,0,9838,0,13227,19492,0,0,0,29764,0,0,0 -,0,686,30053,0,0,0,0,0,30789,139,20837,0,0,0,0,502,18533,0,0,0,0,0,19111,0,0,0,0 -,0,31396,0,0,0,17444,0,0,0,0,0,0,0,49862,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25610,550,0 -,0,561,0,29034,0,0,0,3528,0,0,0,1715,14661,18,63463,0,0,0,0,0,0,0,0,0,0,14186,0, -0,0,0,0,0,0,0,0,0,0,29578,59014,0,39430,0,0,0,0,2250,16612,0,31780,0,0,0,0,0,0, -462,16967,0,29029,0,0,0,0,0,23462,0,0,0,0,0,0,0,0,1768,0,6025,16998,1804,0,0, -54182,0,0,0,0,0,0,0,0,14124,0,6154,29702,0,0,0,0,0,7716,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,48807,0,8292,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16389,5933,0, -14857,51303,0,0,0,0,0,0,0,0,0,0,0,35623,9097,23047,0,0,23112,0,0,0,0,0,438,0,0,0 -,0,0,0,0,151,9254,1390,0,0,0,0,0,0,54215,0,0,0,0,6187,0,0,0,0,13095,0,0,0,0,0,0, -0,0,0,0,0,0,9866,0,0,59622,0,0,0,0,0,0,0,0,0,25286,0,0,23848,32069,0,0,0,0,0,0,0 -,0,0,9255,2187,15270,437,0,0,0,0,0,0,0,0,0,0,19493,0,0,0,0,0,0,0,0,0,0,0,11748,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16902,0,0,0,0,0,0,0,0,0,22212,1865,17543,0, -0,0,0,0,0,21996,0,0,0,0,55975,0,0,0,0,0,0,0,0,32138,21156,0,0,0,0,0,0,14249,0,0, -0,2388,0,0,0,0,6823,0,0,0,0,0,0,0,0,0,0,0,0,0,26694,0,0,6059,53511,0,0,0,0,0,0,0 -,49542,6159,0,0,0,0,0,0,0,0,0,0,0,0,0,1036,24036,0,2501,0,0,0,0,0,0,17419,51271, -3377,15142,0,0,0,0,0,0,5007,62374,0,56935,0,0,0,0,0,0,0,0,0,0,0,24422,0,0,0,0,0, -0,0,0,942,0,0,0,0,0,0,0,0,0,0,28263,0,0,0,0,0,0,0,15622,0,19749,0,0,1611,0,22219 -,48583,25129,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17476,0,0,0,0,0,0,0,0,0,0, -721,0,0,0,0,32518,0,0,0,18469,0,0,0,0,0,0,5896,29927,3657,23046,0,0,3214,0,0,0,0 -,0,0,0,0,0,112,0,0,0,0,0,3048,455,0,31012,0,0,0,0,0,0,0,23270,0,32677,0,0,0,0,0, -38086,0,0,0,0,0,0,0,0,0,0,0,0,0,4900,0,0,0,0,0,0,0,0,0,25541,0,18788,0,0,22248, -1351,0,61734,4524,30629,0,14887,242,29063,0,0,14408,4741,0,0,0,37318,0,0,0,0,0,0 -,0,0,0,0,0,0,8106,0,32107,0,0,0,0,0,0,0,0,0,0,0,1481,0,0,28132,0,25798,0,59783,0 -,0,0,0,0,59078,0,0,0,23366,0,0,0,0,0,0,0,30887,0,0,0,0,16200,0,0,0,335,0,0,0,714 -,0,0,0,0,0,0,0,0,0,0,0,0,0,30730,9478,0,0,0,0,0,0,0,0,0,0,0,18790,0,0,0,0,663,0, -0,0,1034,31431,0,0,0,0,0,0,0,0,0,0,30120,0,0,0,0,13925,0,0,0,0,0,0,2280,13414,0, -0,0,0,0,0,22028,23687,3017,11047,0,0,21738,18630,0,0,0,0,0,0,0,30246,0,0,0,0,0,0 -,0,0,0,0,0,0,17257,0,21896,63783,0,0,0,21094,0,18662,0,25700,0,22533,0,0,0,0,0, -6341,5800,11111,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,15399, -12970,6501,0,0,3179,26438,0,0,0,0,0,0,0,15750,0,13062,0,0,0,0,0,0,0,0,0,0,142,0, -0,0,0,21284,11177,4391,0,0,0,0,19595,40647,0,0,0,0,0,11877,0,0,0,26439,0,0,0,0, -695,49126,27467,11972,0,0,0,0,0,0,9961,0,0,0,31722,62982,0,0,0,0,15817,52710,0,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24614,0,0,0,0,0,20550,0,0,5034,3942,0,0,0, -45927,0,0,0,0,0,0,0,0,0,0,2548,0,0,0,0,0,0,45606,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,0,0,3405,12582,15563,54087,0,0,0,0,0,0,0,0,0,0,0,0,24202,5893,0,0,0, -44230,0,0,0,5605,0,47782,0,32230,0,0,0,0,0,0,0,0,0,0,0,7014,0,0,0,0,16488,3175,0 -,27237,0,0,0,0,0,40902,0,0,0,0,0,0,0,32004,31434,0,24392,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,0,29130,58214,0,0,0,0,0,0,29002,0,0,0,0,0,0,0,0,0,0,55366,0,0,0,0,0,0,0 -,0,0,0,0,37926,0,0,0,0,0,0,0,0,1290,0,0,0,4713,0,0,0,0,0,0,0,0,0,0,0,0,0,20812,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1803,966,0,17700,0,0,654,19109,0,51655,0,0,0,0,0, -10470,1584,0,0,0,0,0,0,0,2506,0,0,25159,4303,0,0,0,395,15879,0,0,0,0,0,0,0,0,0,0 -,1352,6535,0,19652,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4722,7909,0,0,0,0 -,30152,0,0,64742,0,0,0,0,0,0,2153,9125,0,0,279,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,41894,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,0,0 -,0,0,0,0,1328,17030,0,0,0,0,0,0,0,54151,0,0,0,0,1775,54535,0,0,0,0,31624,0,0,0, -7150,0,0,0,0,0,0,0,1840,35943,0,0,0,0,0,56455,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -64486,0,0,0,51174,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,4134 -,0,0,0,0,0,0,0,0,0,0,0,17092,0,0,0,0,0,0,0,0,0,0,0,0,12,16134,19883,39943,10281, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,44711,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -14125,2407,0,0,0,0,0,0,0,0,0,0,26921,0,0,0,0,0,22188,0,20810,10053,0,0,0,0,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28170,0,15208,0,0 -,32517,5736,19271,3562,10534,0,0,0,59655,0,0,0,0,27084,60422,0,0,24969,0,0,0, -2636,0,0,0,0,26277,0,0,0,0,0,0,0,0,0,0,0,30596,3594,0,0,0,8362,14565,0,0,0,0,0,0 -,10793,12326,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5906,59686,0,0,23081,517,0,15556,0,0,0, -8486,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,0,0,0,19877 -,0,0,0,0,0,0,0,0,7497,0,0,26085,0,0,23784,63591,6568,6310,0,0,0,0,0,0,0,0,0, -10054,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7018,14470,18858,0,5641,10660,0,0,0,0,0,0,0, -35526,1515,0,0,0,0,0,0,0,0,0,0,0,27656,0,0,9606,0,39590,0,0,0,0,0,0,0,0,0,0,0, -53926,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,232,4327,12649,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,20199,0,0,0,0,0,0,26730,0,0,0,19400,14695,0,31334,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19589,0,0,0,0,0,0,0,0,5064,11908,0,27333,0, -0,0,0,0,0,0,47751,0,0,0,26662,0,0,0,0,0,0,0,55655,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,6245,0,0,0,0,0,0,0,0,23368,63911,0,0,0,0,0,0,0,0,1974,0,0,0,0,0,0,0, -8520,24037,0,0,0,0,0,0,0,26279,0,0,0,22886,0,0,0,27782,0,30694,0,0,0,0,0,0,0,0,0 -,0,0,33703,0,0,0,30405,0,34598,0,51047,0,0,0,0,1908,0,0,0,0,0,0,0,0,0,0,1511, -21897,0,0,0,0,0,0,51398,0,24870,0,32647,0,0,0,35015,0,0,0,0,0,0,0,11204,0,0,0,0, -0,0,7758,57991,0,0,0,30949,0,0,22,15140,9162,0,0,0,0,0,0,25540,20136,7108,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16427,10789,9805,0,0,0,0,0,0,0,0,0,4680,0,0,52679, -0,0,0,0,0,14884,0,0,0,16804,0,0,0,0,0,0,9578,5287,0,0,0,0,0,0,0,34054,0,0,0,0,0, -19076,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7627,55719,0,39463,14446,58374,0,0,0,0,23465, -15845,0,0,0,0,0,38534,0,0,0,17893,10922,0,7176,678,0,0,0,0,0,0,0,0,3113,46279,0, -0,0,0,0,0,0,23334,0,0,18088,23268,0,62342,0,0,0,16613,0,0,0,0,0,0,0,0,0,38182,0, -0,0,0,0,0,25292,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10344,71,6446,0,0,1893,0,0, -1106,0,28680,30756,0,41126,0,0,1492,0,15341,0,0,0,0,17575,0,21220,0,0,0,0,0, -25060,2088,21828,0,0,0,0,0,358,0,0,0,0,0,16708,0,0,0,1668,0,0,0,0,0,12260,0,0,0, -0,0,0,0,0,4078,0,0,0,0,0,12713,6215,0,0,20329,0,0,0,0,0,0,0,0,0,0,31204,0,0,0,0, -0,0,0,0,0,0,3732,0,1646,0,0,27460,0,34406,17128,14341,0,0,0,0,0,19527,0,0,0,0,0, -0,0,0,0,0,6120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8551,21546,10212,3020, -2951,0,17638,0,0,6985,44999,2218,8197,0,0,30472,63366,0,26660,0,0,0,0,0,0,0,0,0, -0,0,0,1265,0,0,0,0,0,0,0,2610,0,0,0,11278,20295,0,0,0,0,0,19780,0,0,0,0,0,0,2353 -,10852,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5421,24292,0,0,0,0,0,0,0,0,0,0,0,0,0,34407,0, -0,0,0,0,0,15432,20774,0,0,0,0,0,0,0,0,12360,10757,0,0,0,33126,0,0,0,0,0,0,0,0,0, -0,0,29573,0,2343,0,0,0,0,0,63079,0,0,0,0,0,0,0,0,0,43015,0,16038,0,0,0,0,0,0,0,0 -,1480,25573,0,0,0,0,0,0,0,8839,0,0,0,0,0,0,0,24645,0,0,0,0,0,0,0,0,0,0,0,0,0, -5063,0,0,0,0,0,45830,0,0,0,0,0,0,0,0,0,0,823,0,0,64039,0,0,0,0,0,0,0,0,0,0,0,0,0 -,15300,0,0,0,0,0,0,2924,46759,6760,19268,0,0,0,0,0,0,0,0,0,34182,0,0,3977,18149, -0,0,0,32199,0,0,0,0,0,0,0,0,0,23524,25994,0,0,10343,0,0,0,9733,0,0,0,0,0,0,0,0,0 -,4740,0,0,0,0,0,0,0,0,0,16741,0,0,4626,23367,0,0,31400,0,0,3557,0,0,4234,0,0,0,0 -,0,0,28486,0,0,0,0,0,14213,0,57191,0,0,0,0,0,0,0,0,0,0,240,0,0,0,0,65318,29832,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29989,0,31846,0,0,8170,0,0,4421,27626,30884,0 -,0,20204,0,0,0,0,44614,534,20868,0,0,0,0,0,0,0,0,0,0,0,0,0,28710,0,10277,0,0,0,0 -,0,29511,0,19813,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27020,0,0,0,0,0,0,53094 -,0,35207,0,0,0,37542,0,61766,8584,8037,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12488 -,22757,0,0,0,0,0,0,0,0,0,0,0,0,0,23814,0,0,0,0,0,0,0,0,0,19973,0,0,0,63943,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36006,0,0,0,19012,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,8580,0,0,0,0,0,0,0,18021,0,0,0,0,0,0,0,0,80,1254,0,0,0,42630,0,0,0,0,0, -0,0,16262,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2124,25479,0,0,0,0,16873,0,0,0,0,3142, -0,0,18443,0,0,0,0,0,3917,0,8841,1190,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,20645,0,0,0,0,0,0,0,0,0,0,0,9284,0,0,24394,41351,0,0,0,42087,0,62566,0,0,0,0, -0,0,0,0,0,0,6728,4199,0,0,0,0,25515,0,1231,0,374,15623,0,29956,0,14118,0,0,0,0,0 -,19047,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31718,0,0,0,0,0,0,0,0,0,0,0,20900,0,16743,0 -,0,0,28902,0,0,0,0,0,0,0,0,0,0,0,0,2578,0,0,0,0,0,0,0,0,0,13838,0,0,10052,0,0,0, -0,7432,43783,17097,0,0,0,0,0,873,0,0,0,398,0,0,0,0,0,0,0,0,0,8459,23559,0,53030, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35750,0,4071,0,0,0,38662,0,41414,0,0,0,0,11656,0,0 -,0,0,0,4011,42695,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25353,0,0,0,0,0,0,0,27177,22372,0, -0,0,0,0,30980,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,46278,3976,12711 -,0,0,0,0,0,0,0,0,0,0,0,20517,0,0,0,0,0,0,0,0,0,0,0,0,4072,11078,0,0,16553,2405,0 -,0,0,0,0,0,0,0,2670,0,0,0,0,0,0,32998,0,0,0,0,0,0,0,47046,0,30533,0,0,11050,9734 -,13129,0,0,0,0,23494,0,0,0,0,0,58310,0,0,0,57543,0,0,0,0,0,0,0,0,0,0,0,0,0,454,0 -,0,0,0,0,0,5163,59687,2220,0,0,0,0,0,0,29510,0,0,0,0,0,0,0,0,0,0,0,17316,0,20069 -,0,0,0,0,0,0,0,0,0,5319,0,0,0,0,0,0,0,0,0,27174,0,0,0,0,0,0,0,22949,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,19208,0,0,0,0,0,0,20933,0,0,6026,8742,0,0,0,17380,0,13127,2797,0 -,0,30116,0,0,5963,8004,0,57126,0,0,0,0,0,42854,14792,30759,0,24964,0,0,0,0,0,0,0 -,0,0,0,0,0,0,0,0,0,0,16933,0,0,0,0,0,0,15176,40839,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -788,30341,0,0,0,0,21036,24102,0,0,0,0,30123,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -22597,31531,26789,0,59559,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9352,29863,0,0,0,0,0,0,0,0 -,0,24551,0,0,0,0,0,0,0,20516,0,0,0,39462,3665,0,28265,0,8778,64262,0,57414,9132, -0,0,18276,0,0,0,0,0,0,0,0,0,0,26344,30725,524,19751,0,13796,0,0,0,0,0,0,0,0,0,0, -18155,0,12841,0,74,24998,13579,1061,0,64199,0,0,8776,0,0,60231,0,25412,0,0,0, -59143,0,0,0,0,0,0,14344,1510,0,0,0,38374,0,0,0,0,0,0,0,0,13353,0,0,0,0,0,0,0,0,0 -,0,9446,0,0,0,0,0,0,0,32613,0,0,0,0,0,0,0,0,0,0,0,0,0,19844,0,0,0,0,14859,0,0,0, -0,6662,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14154,0,29770,0,0,0,0,0, -16520,2182,0,0,0,0,0,36102,3340,0,0,0,0,0,0,0,0,25189,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,15720,0,0,0,0,0,0,22758,0,0,304,0,3243,14117,0,0,0,0,0,0,0,0,0,0,5130, -12679,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21733,10441,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,36103,0,0,0,0,0,23590,0,57479,0,0,0,0,0,0,0,0,0,0,0,0,10824, -18372,0,0,0,0,0,35078,15722,12967,0,0,0,0,0,34599,0,0,0,0,0,0,0,0,0,0,0,0,0, -53639,0,38630,0,0,0,0,0,0,31017,11333,0,0,0,0,19144,0,9513,0,0,0,0,0,0,0,0,56711 -,24042,0,1197,0,0,58502,0,0,0,0,0,0,0,0,0,8230,6121,18628,0,0,0,0,0,0,25290,0,0, -0,0,0,1514,0,0,0,0,0,0,0,14378,9798,32363,0,0,0,0,0,9577,0,0,0,0,0,0,26788,0,0,0 -,0,0,0,330,10533,0,0,0,0,0,42246,0,0,0,0,0,0,5074,21028,0,38119,0,0,0,0,0,0,248, -0,31176,62054,0,53287,0,0,0,0,271,0,0,0,0,0,0,0,0,0,0,0,0,0,9224,2117,0,0,0,0, -15818,5607,0,52582,0,0,0,0,0,0,0,0,18248,24005,23018,0,0,0,0,0,0,0,0,0,0,0,0,0, -427,0,0,39910,0,0,7080,11399,0,0,0,0,0,0,0,0,0,0,22220,57894,0,0,0,0,0,0,0,13156 -,0,1413,1007,0,0,0,0,21415,0,21543,0,0,0,0,0,0,0,0,0,41702,22538,9573,0,0,0,8806 -,0,0,6920,56359,0,0,0,0,0,0,0,0,0,0,0,42215,0,0,13708,0,0,0,0,0,0,0,0,0,0,16453, -0,0,0,0,0,0,1582,1764,3282,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11653,0,0,0,0,12139,0, -29482,31076,1673,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,40262,0,0,0,33862,0 -,0,0,0,0,20996,0,0,0,0,0,4615,0,0,0,0,0,0,0,0,0,0,0,43943,333,19367,0,0,0,0,0,0, -0,26821,0,32389,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4936,11687,0,0,0,0,0,0,0,0,0,10885,0 -,0,0,0,0,25926,0,0,0,0,0,0,15851,0,0,0,0,0,0,0,0,0,8360,0,17130,7942,0,11460,0,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,18150,14248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -22310,0,0,0,42758,0,0,0,0,0,0,0,0,29354,5574,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,31109,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11236,0,0,0,0,0,0,0,0 -,0,0,0,0,0,9156,0,0,1801,14023,0,0,0,0,0,62406,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -23620,0,0,0,0,0,0,0,0,0,0,31018,65510,0,0,0,0,0,0,0,26182,0,0,0,0,0,0,0,27717,0, -0,0,0,0,0,0,46950,0,0,0,0,0,0,0,0,0,0,0,0,0,31108,0,11366,0,0,0,3717,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,8552,6054,3339,0,0,0,0,51622,0, -0,0,0,0,0,0,3718,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28358,0,2756,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,1462,0,0,27622,0,0,0,0,0,0,0,62502,14410,56743,0,0,0,0,0,0,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,12206,0,0,0,0,0,0,0,0,0,0,0,0,36550,0,38054,0,0,0, -21221,0,0,0,0,0,0,0,27077,0,0,16906,0,12587,12101,0,0,0,0,0,0,10414,28775,21769, -60167,0,56646,0,0,0,0,0,20740,0,0,0,0,0,0,5931,5351,0,65478,0,0,0,0,0,0,7977, -52647,0,4868,0,0,0,55463,0,0,0,0,0,32197,0,0,0,0,0,13445,0,0,0,26631,0,0,0,0,0, -11237,0,0,0,0,209,1285,0,0,1928,0,0,0,0,43334,23849,23172,0,0,0,0,0,0,0,0,24712, -62439,8811,3463,20457,0,0,0,0,0,0,0,0,0,16008,56263,0,0,0,0,0,0,0,0,0,0,0,60358, -22761,6565,0,0,30888,27686,0,0,0,17093,0,0,0,0,22121,0,0,0,7593,14182,0,28103,0, -0,0,0,0,45126,0,0,0,0,0,0,0,0,0,0,0,0,0,31844,0,0,0,0,0,0,0,0,0,0,0,0,0,18500,0, -0,0,0,28202,0,0,0,0,0,0,0,0,26308,0,29541,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -29572,0,0,0,21285,0,0,0,0,0,60839,0,0,0,0,0,30407,15949,2981,0,0,0,46439,0,0,0,0 -,0,23911,26505,25222,12811,5895,0,6343,0,0,0,0,0,0,0,0,0,0,0,31815,0,0,0,0,0,0,0 -,0,19688,10245,0,0,0,31301,26985,28964,0,0,0,0,0,0,0,0,27208,31172,0,0,0,0,216,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16292,0,0,0,0,0,8743,0,0,0,0,0,0,0,0, -0,0,0,0,0,6438,0,0,0,33319,0,0,0,33286,0,0,0,0,0,0,0,0,0,22181,7499,24774,0, -10756,0,44775,724,0,25768,25669,24873,5349,25257,0,0,54566,0,0,0,0,0,0,0,0,0,0,0 -,327,439,357,0,0,6536,8452,0,0,1802,0,0,61350,0,15045,0,0,0,0,0,0,0,0,0,0,0, -38343,0,0,0,0,0,0,0,0,0,0,32491,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -22885,0,0,32073,0,0,0,9546,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27748,0,0,23176,0,0,0 -,0,0,0,0,0,0,0,0,0,24583,0,0,0,0,0,34118,0,0,0,0,2158,0,5586,30340,0,0,0,0,0,0,0 -,0,0,0,0,0,0,24452,0,0,0,0,2409,4390,0,24196,0,0,0,0,0,0,32264,26948,20587,0,0,0 -,2155,0,0,0,0,0,0,0,0,0,0,0,4328,26276,0,0,0,0,0,0,0,0,23564,0,12458,11367,0,0, -25162,0,0,0,0,0,0,65414,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32966,0,0,0, -34662,0,0,0,0,0,39238,0,0,0,0,11400,10214,266,12452,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,15173,0,0,0,13668,0,13222,0,23364,0,0,0,0,0,11941,0,0,0,0,0,0,0,0,0, -25575,0,0,0,57383,0,0,0,10308,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,2865,9287,75,0,0,0,0,0,0,0,0,0,0,21508,22380,59526,0,0,0,23589,0,0,0,51590 -,0,0,0,0,0,0,0,0,0,0,0,4645,3980,28295,0,0,0,0,0,12388,0,0,0,0,0,0,0,0,0,0,0, -21734,0,17607,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41767,0,0,0,0,0,0,0,18436,0,0,0,0,0, -0,0,21958,0,19430,0,0,1204,0,0,0,0,0,0,0,0,0,3240,55239,0,0,0,0,0,30660,0,0,0, -28901,0,0,0,0,4716,0,0,0,0,0,0,0,0,0,0,0,11754,0,0,0,0,22086,0,22564,8749,0,0, -28391,0,0,0,0,0,0,0,0,0,0,0,2886,0,0,0,0,0,0,0,29062,0,0,0,0,0,0,0,40358,0,0, -15916,39526,0,13735,0,0,0,0,28938,0,407,4006,0,0,0,26916,0,0,0,0,0,27526,30280,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,24586,0,24649,5126, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8684,0,0,0,0,0,0,0,23019,0,22377,18599,0 -,0,0,0,0,0,0,0,0,0,27593,9735,0,20196,0,0,0,0,28168,48423,0,0,0,0,0,31399,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,13892,0,0,0,0,0,17606,0,0,15242,29767,26378,17701,0,0, -14472,0,4840,0,0,0,0,0,0,24708,0,9349,4330,0,0,0,0,0,0,0,16137,0,0,34854,0,0,0,0 -,0,0,0,0,0,0,0,25063,0,0,0,0,0,0,6603,12583,0,0,0,0,0,0,0,0,7433,29188,0,0,0,0,0 -,31270,0,0,22920,3143,0,0,0,0,0,23461,0,0,0,0,0,0,0,0,618,0,0,0,0,21381,0,11524, -0,0,0,0,0,0,21004,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,312,23239,0,0,0,0,0,0,0,0,0,0,0, -0,2313,0,0,40614,0,0,14825,0,0,0,0,0,0,46535,0,41190,7853,0,31656,0,0,0,0,0,0,0, -0,0,3433,5255,0,0,0,0,0,0,0,33958,0,0,0,0,72,15493,0,0,0,0,0,0,0,36070,0,0,0,0,0 -,0,0,14724,0,0,0,0,0,29828,0,0,0,0,0,0,0,18822,20008,0,0,0,0,2438,2952,0,0,0,0,0 -,0,0,0,0,0,0,0,0,3342,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24420,0,19908,0,0,0,8101,0, -17479,0,0,3530,0,8202,29319,0,0,1132,6789,0,0,23881,0,0,0,4810,0,0,46918,0,0,0, -41574,0,0,0,0,0,0,0,0,0,48582,0,0,0,0,0,0,0,0,0,0,0,0,0,39334,0,0,0,26117,0,0,0, -0,0,0,5100,0,0,0,0,0,23496,27813,4045,54918,0,0,0,0,0,0,6473,7428,0,0,0,0,6792,0 -,0,0,0,0,3560,32103,0,0,0,0,0,0,0,0,0,0,0,54790,0,0,6926,0,0,0,0,16518,0,0,0,0,0 -,20806,0,0,0,0,1841,3174,0,0,0,0,9612,18374,0,0,0,0,32744,0,0,9671,0,59879,0, -23300,8073,0,0,14758,0,0,0,10342,0,0,0,0,0,0,24808,14759,0,0,0,0,0,0,5515,0,0, -14852,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2354,23271,0,32740,0,0,0,0,0,0,0,0 -,0,0,18472,0,0,0,0,0,0,0,0,33190,0,0,0,0,0,0,0,0,8972,21669,0,0,0,0,0,0,0,0,0,0, -0,25574,0,0,0,0,5096,0,14283,55367,0,0,0,0,0,0,0,0,0,12644,0,0,0,0,4651,0,0,0,0, -0,0,0,661,0,0,13638,19466,0,0,0,0,0,31273,0,8010,0,0,0,0,0,3211,0,0,0,0,63430,0, -0,0,0,0,15237,0,0,0,0,0,0,19018,2437,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14312,0 -,0,0,0,16836,0,0,471,35975,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 -,6023,0,0,0,0,0,0,0,0,11593,9639,0,0,0,55783,0,5700,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,0,27908,0,26598,0,0,6667,6470,0,0,0,0,0,0,0, -62534,0,0,0,0,16522,27911,0,0,10025,7172,0,0,779,0,360,17477,0,0,0,61991,7752, -7717,1494,0,0,0,26569,40742,0,0,0,0,0,0,0,26406,10474,32196,0,0,0,0,0,50567, -16521,11716,0,0,0,0,0,55558,0,0,0,0,0,0,0,0,0,0,0,61926,0,26436,0,0,0,0,4459, -10598,0,0,0,0,0,0,0,0,0,0,0,9223,0,29318,0,0,0,0,0,60423,0,0,0,0,0,0,0,47078,0, -50246,0,12612,0,0,0,0,0,0,0,61799,0,55015,0,21060,7309,0,0,0,0,0,11976,0,0,0,0, -23527,0,0,0,0,0,0,10347,15942,0,34023,0,0,0,0,4969,0,0,0,0,0,0,0,0,28997,0,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36454,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3466,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,0,0,19716, -28872,0,0,0,0,0,22152,0,0,0,0,0,0,26342,0,0,0,9764,0,0,0,0,0,0,0,21798,0,0,0,0, -13,6853,32136,0,0,0,0,0,0,0,750,0,0,54502,0,0,0,0,0,0,0,0,0,46183,0,0,625,22854, -0,0,0,0,2061,23588,0,0,11049,56262,0,0,18538,1509,0,0,17258,4453,0,0,0,0,12429,0 -,0,0,0,8102,0,0,0,0,0,0,8074,0,23852,0,0,0,0,0,0,0,0,0,0,0,16136,3428,0,27876,0, -0,0,7332,0,0,0,0,0,28900,0,0,2284,0,0,17573,201,1508,0,0,0,0,0,0,0,0,0,31365, -27688,22565,0,0,0,5159,0,0,0,0,4584,42599,0,0,0,44422,1068,23173,0,0,0,613,0,0,0 -,12645,0,0,0,0,0,27076,6732,0,0,0,3913,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,22244,29992,15911,0,0,0,0,0,22982,0,0,0,0,0,0,0,50598,0,0 -,0,0,0,0,5161,1574,0,0,0,0,0,0,0,0,0,19108,0,0,0,35014,0,0,0,25956,29067,0,0,0,0 -,0,0,0,0,0,0,47079,0,0,0,0,0,0,0,0,0,0,1356,61927,0,0,0,64455,2122,64231,0,0, -18763,0,0,0,0,0,0,0,0,0,907,34471,0,0,0,39078,0,0,1995,0,0,0,0,0,0,0,0,0,0,56518 -,0,0,0,0,0,0,0,0,0,0,0,0,822,0,15978,44423,0,0,3112,325,0,0,0,0,0,15397,0,0,0,0, -0,0,0,0,0,0,1193,4294,4968,15559,0,46150,0,0,0,0,0,18917,0,0,0,0,0,0,9928,37543, -0,0,0,0,13097,36999,0,0,0,15430,0,0,8424,29639,0,0,0,0,0,0,0,0,0,0,0,0,0,25734,0 -,0,0,0,0,0,0,0,0,0,0,0,0,40487,0,13284,0,11141,0,0,0,32388,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,5298,57702,0,0,0,0,0,0,0,13060,0,0,0,0,0,0, -8233,42278,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36422,0,0,0,7972,0,0,0, -18437,0,0,0,0,7406,0,0,0,9225,0,0,0,0,0,0,0,0,0,13865,47591,18220,53703,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,2796,0,0,0,0,0,24940,17223,0,0,0 -,13221,0,0,0,0,0,0,0,0,0,0,15848,0,0,0,0,0,6122,1735,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,16968,18151,0,0,0,0,0,47494,0,0,0,0,0,0,26089,19494,0,0,0,0,0,15494,0,0 -,0,0,0,0,0,0,0,0,28809,0,0,0,0,42727,0,55174,0,0,0,0,0,0,0,0,0,0,0,20485,0,0,0,0 -,0,0,0,0,0,0,0,58598,0,0,0,0,0,0,0,0,0,0,0,0,0,15172,0,0,0,0,0,0,0,0,0,35302,0, -48135,20972,33094,0,0,0,0,0,9765,0,0,0,0,0,0,0,0,0,39559,0,0,13736,6950,0,0,0,0, -23658,8903,0,0,0,0,0,0,0,22662,0,0,0,0,0,58886,7468,0,0,0,0,0,0,0,0,64550,0,0,0, -0,0,47622,0,0,0,50886,0,0,0,0,0,57606,912,0,0,0,0,0,0,0,0,0,1449,0,1169,0,718, -46151,12104,0,0,0,0,0,0,48230,0,0,0,0,0,0,0,0,0,0,1259,0,0,33734,23208,62567,0, -65158,0,0,0,0,0,0,0,0,0,0,28684,59878,0,0,0,0,0,0,0,0,0,0,25769,0,0,0,0,65479,0, -0,0,0,555,22789,0,19748,1769,10246,8680,0,0,0,0,0,0,0,0,0,14250,0,5899,3303,0,0, -0,0,0,0,0,0,21097,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21638,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,10795,0,0,0,16204,0,0,0,0,0,26986,2469,0,14660,0,0,0,0,0,45447, -12234,3494,4555,10566,0,0,0,0,0,0,0,0,0,0,0,0,2801,0,0,0,15755,0,0,0,0,0,0,0,0,0 -,0,0,0,0,0,0,0,0,0,39654,0,0,0,0,0,0,6763,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -33574,0,10279,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63527,0,0,3912,0,0,7492,0,0,0,35142, -0,0,0,0,0,0,17576,8103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16713,4198,0,0,4782,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,16228,0,0,0,0,25961,20166,0,0,0,10980,0,0,0,0,0,14340, -18922,14567,0,44199,0,0,0,0,0,0,0,18406,0,0,0,0,0,37606,0,0,0,0,0,0,0,0,0,20902, -0,0,0,56358,0,38342,0,0,0,0,9514,36071,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21700,0,0, -5266,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1134,0,1453,0,0,0,0,0,3882,0,0,0, -0,0,0,0,0,4004,0,0,0,51910,0,0,0,0,0,23076,4648,0,0,0,31051,25351,0,0,0,22884,0, -0,0,0,0,63975,0,0,2376,16997,0,0,2096,0,0,0,3373,7046,0,0,0,0,0,0,0,30726,0,0,0, -0,20,0,13707,614,0,0,12840,3079,0,0,0,0,0,51046,3729,0,32680,0,0,0,0,0,24008, -62759,0,0,4745,0,0,0,0,0,0,0,0,0,0,0,0,0,2414,0,0,44262,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,24937,0,0,0,0,0,0,0,0,19140,0,13575,0,0,0,0,0,0,0,39110,0,0,0,28036,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,4261,0,0,0,0,5992,0,264,0,0,0,0,0,0,0,13739,0,21928,0, -0,0,0,0,0,0,0,0,0,0,4232,15110,0,0,0,0,0,0,0,0,0,30022,0,0,27977,0,0,0,0,0,24776 -,0,0,0,0,0,2962,0,0,0,0,0,0,26564,22441,0,0,0,0,0,13640,11205,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,19305,1894,0,0,0,0,0,0,0,0,0,0,9389,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14119, -5224,135,0,0,0,0,0,0,0,0,0,25796,0,0,0,0,0,0,7470,0,0,0,0,63815,0,55654,0,0, -12584,0,1524,33223,0,0,0,9895,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11624, -0,0,0,5614,0,0,0,0,0,0,0,21320,0,0,53607,0,51206,0,0,0,25863,0,0,0,0,0,0,0,0,0,0 -,0,8964,1740,0,0,0,0,0,0,0,0,13476,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7975,0, -0,3306,8134,0,8389,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25766,0,0,0,0,0,0,0,0,0, -52166,0,0,0,0,0,0,0,0,0,0,0,0,0,21477,31112,31652,0,0,0,0,0,0,0,28452,0,0,0, -44231,0,0,0,0,0,0,0,24805,0,0,0,0,0,0,0,0,0,0,12428,6471,0,0,0,0,525,17926,0,0,0 -,26919,0,0,18120,0,0,0,30024,0,0,0,0,0,0,0,0,0,0,29189,0,0,0,43559,0,0,0,0,0,0, -19787,7557,0,59334,0,0,10184,6085,0,44039,0,0,0,0,0,0,0,11175,0,0,0,0,30440, -63110,0,0,0,0,0,0,11017,0,0,0,0,0,0,0,0,27204,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,29126,0,0,0,0,0,0,0,0,0,0,0,0,0,0,622,0,5226,2727,0,15588,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4650,0,2675,0,0,32420,0,0,0,61511,0,0, -5419,17829,2123,0,0,0,0,0,0,0,0,0,0,0,0,0,0,38183,2640,0,11274,14533,1842,0,0, -42663,12681,3430,0,11845,0,0,0,0,0,0,0,0,0,6533,0,0,0,0,0,54598,0,0,0,0,0,0,0,0, -0,0,0,0,12616,38535,0,0,0,0,0,32229,0,0,0,54279,0,48614,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,31401,0,0,0,0,34310,0,0,0,22788,0,52134,0,0,0,0,0,0,0,23302,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,40678,0,0,0,51463,535,0,0,0,0,15525,0,0,0,0,0,0,4904,869,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63718,0,0,0,0,0,0,0,0,1678,0,692,0,0,0, -0,0,0,0,0,0,26216,0,0,0,0,0,29355,0,0,0,0,25095,0,0,0,0,4335,0,0,0,0,0,14538,0,0 -,0,0,0,0,0,0,0,27273,55014,0,0,0,0,0,27271,0,0,0,0,0,30468,0,0,0,0,18186,0,0,0,0 -,0,14345,0,0,0,2152,0,0,0,0,0,0,0,0,0,0,0,0,0,0,58438,21034,0,23339,21318,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,21412,0,0,0,0,0,0,0,12869,0,0,4875,0,0,0,0,29191,0,0,0,0 -,0,0,1640,10247,0,14244,0,0,0,0,9867,0,0,0,0,0,12363,0,0,7653,0,0,4168,2663,0, -4580,0,11143,0,0,0,0,0,0,0,30662,0,0,0,0,0,6724,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,13764,0,0,0,0,0,0,0,0,0,0,0,0,234,6821,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,0,0,0,0,0,25639,0,0,0,0,0,0,0,0,0,29958,0,3461,0,0,0,0,0,0,0,0,0,28324, -18795,7013,12746,11655,0,37287,0,0,10953,7718,9705,0,0,0,0,0,0,0,0,0,0,46534,0,0 -,0,0,0,0,0,0,0,0,8137,17988,0,25156,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41415,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,15784,6918,0,0,0,0,7019,10919,0,0,0, -0,0,0,0,0,0,0,4171,55495,4940,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22440,19333,0,0, -28136,0,6249,21317,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53414,0,0,0,57318,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,39303,0,0,0,0,0,19940,0,0,0,0,0,0,0,25543,0,0,0 -,0,0,0,0,0,0,0,0,0,2698,3911,0,0,0,26790,0,0,0,0,0,0,32424,0,0,18470,0,0,0,14726 -,29834,0,0,0,0,0,0,0,0,0,0,0,1000,4197,0,0,0,19366,0,0,0,39878,0,0,0,0,2185,8901 -,5288,9829,25000,0,0,0,0,0,0,1062,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35622,0, -0,23048,62503,6506,0,0,0,0,0,0,0,13609,10438,0,0,0,0,0,0,0,0,0,0,7723,42119,0,0, -0,0,0,13317,0,0,0,41606,0,27111,0,0,21194,11461,0,0,0,0,26856,58342,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,20940,48710,0,0,0,0,0,0,5227,0,0,0,0,0,10061,31300,0,0,0,19236,0 -,0,0,0,0,30277,13896,0,0,0,12876,13159,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,428, -46951,13134,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15462,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,21668,0,0,0,0,0,0,0,0,0,0,0,0,2249,0,0,0,0,44967,0,0,0,0 -,0,0,3465,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24868,0,0,0,0,0,23909,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,2190,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,16164,0, -10437,0,0,5263,20102,20938,0,0,0,1192,1030,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,21385,4870,0,0,0,0,0,0,0,0,0,0,0,18596,0,0,0,0,1422,4038,2858,0,0,0,0,0,0,0,0 -,48998,0,0,0,0,0,0,0,0,6508,37350,0,0,0,0,0,0,0,0,17001,39431,0,0,0,0,0,30182,0, -21445,7403,28164,0,51750,0,0,0,62631,0,0,0,0,0,0,0,31206,0,0,0,0,0,0,0,0,0,0,0, -7751,0,0,0,0,0,0,0,0,0,13477,0,0,456,26693,0,0,0,0,0,0,0,0,0,0,0,0,14890,0,0,0,0 -,0,26697,22022,13225,27364,0,0,0,18884,0,0,0,0,0,0,0,0,3659,0,0,0,0,0,0,0,0,0,0, -0,1448,5413,0,0,0,0,0,0,0,0,0,0,0,6340,0,0,18091,18725,0,0,0,0,0,0,0,0,0,0,0,0,0 -,22118,0,0,0,18981,0,0,0,0,0,0,0,0,0,29223,3724,0,0,0,0,43526,0,0,0,25668,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21545,9862,0,22692,32201,60646,0,7300,0,0, -0,58887,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19460,0,0,0,0,0,0,0,0,0,50342,0, -65255,4360,17286,0,0,0,0,0,0,0,28708,0,0,30025,60102,0,0,0,0,0,0,0,0,0,47014,0, -31973,0,9572,0,0,0,0,0,0,0,18501,0,0,0,0,0,14597,0,0,0,53735,5228,22183,0,0,0,0, -0,0,1554,24164,0,0,0,0,0,0,0,0,0,0,0,0,10827,0,0,0,0,34918,0,0,0,0,22252,0,0, -46855,0,0,0,0,0,31207,0,0,10733,0,0,63334,0,0,0,0,8616,50119,20169,12678,0,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,58087,20298,5,0,0,30920,0,0,0,0,0,0,0,296,13190,0 -,30663,0,0,18536,12228,0,6788,0,0,0,0,30890,21796,0,0,526,0,0,0,0,0,0,0,0,0,0,0, -0,20965,0,0,0,0,2161,0,0,0,0,0,0,24038,0,0,0,0,13544,7398,0,0,32522,9605,0,0,0,0 -,3208,7590,0,0,0,43846,0,0,0,38663,0,0,0,0,0,39014,4142,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,6373,0,0,13676,0,0,0,0,30374,21288,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,0,0,0,0,22791,0,0,0,0,0,37958,0,0,0,0,0,0,0,0,0,0,9452, -9990,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4841,0,0,0,0,18820,152,0,0,0,0,0,13260,3334,0,0 -,24234,8422,0,17957,0,0,0,10244,0,0,0,0,0,0,0,0,0,0,0,7204,0,0,0,0,1201,26151,0, -31173,0,0,0,0,0,0,0,0,0,0,0,0,0,64838,4203,7525,521,0,18888,37031,0,0,0,0,0,0,0, -0,7082,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4490,12487,0,0,0,0,0,0,0,36615,0,0, -0,14854,0,0,0,0,0,0,0,0,0,0,0,0,6539,13029,9704,38983,0,0,0,0,168,10405,0,0,0,0, -394,25607,0,57063,0,0,0,0,0,0,0,0,0,0,16141,19878,0,0,0,0,0,0,0,0,0,29446,0, -12036,0,0,0,0,0,6982,18572,0,24584,14535,0,0,0,0,0,0,0,0,0,0,16,0,21642,0,0,0,0, -0,0,5254,0,0,0,0,0,0,0,0,1622,0,0,0,0,0,0,0,0,0,0,0,0,0,3853,9126,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,7241,10982,0,0,0,0,0,0,0,0,0,0,0,0,0,0,950,0,0,57990,0,0,277,0 -,0,0,694,36007,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42470,0,0,0,0,18409, -51142,0,0,0,0,0,0,0,0,0,28646,0,0,0,30693,0,0,0,0,0,56295,5544,0,0,0,0,8518,8366 -,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,0,0,45670,0,0, -9608,33062,0,0,0,0,0,0,0,0,0,0,0,18694,0,0,0,0,1672,23493,0,0,6955,7655,0,36134, -0,0,0,0,0,0,0,0,23432,647,0,0,0,0,0,0,0,0,0,0,0,13382,0,0,0,19621,0,0,0,0,0,0,0, -0,0,20228,0,0,2728,31495,0,0,0,0,29096,22213,235,35495,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,5348,0,0,0,0,8968,1989,0,0,1066,0,0,11492,5965,31367,0,0,0,0,0,0,0,0,0,0,0, -18727,0,0,0,6757,0,0,10765,4646,0,36166,0,27943,0,0,26888,8420,0,0,0,0,0,0,0,0,0 -,29316,0,0,0,0,0,0,0,0,0,0,4975,0,0,0,14762,3111,0,0,0,0,0,43399,0,0,0,0,0,0,0, -18980,0,0,0,0,0,44550,0,0,0,0,4051,0,0,0,0,37734,0,0,0,0,0,5188,0,0,0,0,0,24486, -0,5989,0,41159,0,0,0,0,0,0,0,0,0,20326,0,0,747,6884,0,0,0,41798,0,0,3117,22919,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21032,0,0,0,0,0,0,0,0,9574,0,0,0,0,0,0, -4302,0,0,0,0,0,0,0,0,0,0,0,21068,34630,0,0,0,0,0,64071,0,0,0,0,0,0,26667,7943,0, -0,0,0,0,52934,0,0,17002,0,0,0,0,0,0,20294,0,0,0,0,0,0,0,0,0,27301,18347,7974,0,0 -,0,0,0,0,0,0,16874,0,0,0,0,45414,0,0,0,0,0,0,648,1575,0,0,0,31749,0,0,0,23301,0, -0,0,0,0,0,0,0,0,0,0,0,15912,50535,0,0,0,0,1993,8582,0,0,0,0,0,0,0,38438,0,0,0,0, -0,0,0,0,0,0,0,0,15850,6183,0,0,0,0,3402,0,0,27494,0,0,749,0,0,0,0,0,0,0,26025, -29606,0,0,7144,19622,30504,0,0,0,0,0,0,0,0,21316,0,0,0,0,0,0,0,0,0,21444,0,0, -1289,6919,0,0,0,0,0,0,8299,0,0,0,14090,35655,0,0,0,0,0,0,0,0,2377,15206,0,0,6028 -,4452,0,25508,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,50310,0,0,0,0,1269,0,0,0,0,0,0,0,0,0 -,0,0,0,51014,0,0,0,0,0,0,0,9286,0,7429,0,0,28393,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,16680,452,0,0,0,0,0,23718,0,0,0,31750,0,0,0,0,0,0,0,0,3568,0,0,13604,0,0, -0,0,0,25255,0,0,0,50982,0,56582,0,0,7467,0,0,0,0,30181,0,0,0,0,0,0,0,30564,7208, -7845,0,0,0,0,0,0,7726,0,0,0,0,62182,0,0,0,41094,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,22695,0,0,0,0,0,0,17736,0,0,0,0,0,0,0,0,50054,0,0,0,14180,0,0,0,0, -0,0,8974,0,0,0,0,0,0,0,0,23332,0,0,0,11140,0,0,0,0,0,0,0,24262,27145,9540,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,26537,45510,6062,3879,0,0,20233,25991,0,0,17803,0,0,0,0,0, -13962,5508,16971,27013,7437,31494,0,0,0,0,0,0,0,0,0,0,4714,0,0,0,0,0,0,0,0,17189 -,0,0,0,0,0,27492,0,0,26953,0,0,0,0,0,0,0,0,0,0,41319,0,0,0,0,0,0,0,0,0,0,0,47430 -,19596,12549,0,0,0,8390,1006,0,0,0,0,0,0,0,0,0,0,24100,17577,4,0,0,0,0,0,22277,0 -,0,0,0,0,0,0,26692,0,0,0,0,0,24676,0,0,0,0,0,0,0,0,0,0,0,0,0,29477,0,0,0,21573,0 -,0,0,0,0,0,0,0,0,0,9864,14214,0,0,0,0,0,0,25771,5766,0,0,8909,8679,0,0,6861, -16166,0,38887,0,0,0,0,0,0,12392,8678,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -52646,1354,2950,0,14692,0,0,10572,49830,0,0,0,0,0,0,0,0,3626,582,0,0,0,55750,0,0 -,0,30885,0,0,0,0,0,0,0,0,0,0,0,0,0,5830,0,0,2090,0,0,0,0,0,0,0,0,0,0,0,0,31142,0 -,0,0,0,0,10503,0,0,18825,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, -57158,0,0,30792,63526,0,0,0,9863,16267,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,18824,0,0,0,0,0,0,19653,25388,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,9292,0,0,0,0,0,0,0,0,0,0,36358,0,0,0,0,0,0,0,0, -0,0,25480,23015,0,0,10440,6725,0,0,0,22436,24265,15109,0,0,0,62311,8906,34534,0, -0,0,0,0,0,15913,1319,0,0,20296,1477,30760,0,25928,16772,0,0,1069,0,0,0,0,0,0,0,0 -,0,0,0,0,17029,0,31909,0,0,0,0,0,0,0,0,0,0,0,41638,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,41542,0,21478,0,0,0,9796,0,0,0,0,0,0,0,0,0,0,22187,58343,0,0,0,24295,0, -0,0,0,0,61831,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2833,5829,0,0,0,62855,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,16676,0,0,0,0,0,0,13577,27431,0,0,0,0,21480,10501,0,16932, -0,0,0,0,0,22918,0,48294,2574,2150,0,0,0,0,1897,4518,0,0,0,0,0,0,25064,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,47942,0,0,0,0,10990,13767, -25705,37863,21672,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,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,43430,1712,0,0,0,0, -18886,0,0,0,0,0,0,0,0,0,0,0,0,0,10535,0,0,0,0,0,0,0,15012,0,0,0,0,0,0,0,0,0,0, -14734,0,0,55782,0,0,30824,10886,0,0,0,0,0,51302,0,0,8012,0,0,0,0,0,20680,6981,0, -57415,11,0,0,18277,0,14564,0,0,0,32390,0,0,0,0,0,0,0,0,0,0,0,0,19113,5158,0, -11172,0,16774,0,0,0,0,0,0,0,0,0,0,0,0,10315,13830,0,0,0,0,0,0,10410,7141,0,0,0,0 -,0,18116,0,0,0,44615,15403,13958,0,1540,14632,19525,24201,19781,0,0,0,24165,0, -38951,0,0,0,0,0,6308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17416,15749,3438,13255,0,0,0,0, -0,0,0,0,0,0,0,32228,0,0,0,0,176,0,0,50566,0,0,0,0,0,0,0,0,0,0,0,0,0,21540,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,58982,0,0,0,0,0,0,0,0,0,5284,0,0,0,0,0,0,25897,28326,0,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15945,0,0,0,9804,293,0,0,0,0,0,0,0,13988,23082,4677 -,0,0,0,0,0,0,0,0,0,0,0,5670,0,0,0,0,0,0,0,44070,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,6405,0,30692,0,0,0,61702,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,45926,0,15398,0,0,0,0,0,0,4554,2692,0,0,0,0,0,32485,0,0,0,10084,0,0,0,0,0,0, -24297,0,0,0,0,0,0,0,0,22790,0,0,0,55110,0,0,0,0,0,0,0,0,0,0,0,0,7112,0,31530, -45255,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,40743,17226,22599,0, -0,0,0,0,0,0,0,3695,0,0,0,0,0,0,0,0,0,0,56999,0,0,0,0,0,13799,3114,21287,1353, -7591,0,0,0,8455,0,0,6824,0,0,0,0,0,0,0,14569,0,0,0,29000,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,19979,0,18376,0,0,0,0,0,0,0,0,0,0,0,0,11332,0,0,0,49863,0,0,0,0,0,0,0,0,0 -,0,0,0,0,0,2191,7527,23148,58022,0,0,0,30631,0,26565,0,0,0,0,0,0,0,0,0,0,0,0,754 -,0,0,15877,0,0,0,0,0,0,0,17510,7657,2821,0,0,0,0,0,0,0,0,0,41927,0,0,0,0,0,0,0,0 -,2569,34439,0,0,3790,0,0,0,15339,8775,0,0,0,0,0,0,0,0,0,0,0,15908,0,0,21419,8359 -,0,0,0,0,424,0,0,0,0,0,0,25318,8008,20551,0,0,0,45735,30058,30372,0,0,0,0,0,0,0, -0,0,0,0,0,0,26180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31432,10567,0,0,0,0, -17450,0,0,0,0,0,0,30310,0,38022,0,0,0,0,0,28932,0,0,0,0,0,43910,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,22180,12075,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22247,0,0,22826, -12359,0,0,0,0,4105,50407,0,0,0,0,0,0,13581,28583,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,28936,0,0,0,0,0,17673,10310,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,905,57862, -1580,0,0,0,0,58630,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,13479,0,0, -14153,13286,0,0,9259,0,0,0,0,0,6606,3524,0,0,0,0,0,6567,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,631,49255,0,0,0,0,0,42886,0,38215,0,0,0,0,0,0,0,0,17580, -0,0,0,0,0,0,0,0,55046,0,0,0,0,0,0,0,0,0,10213,0,0,0,0,3604,37767,0,0,0,0,0,0,0,0 -,0,0,0,30950,0,0,0,0,0,0,0,0,0,62087,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23528,0 -,0,0,0,0,0,0,0,0,28715,4229,0,0,0,0,0,0,0,0,0,0,1226,26820,0,0,0,12133,6984,261, -21130,32548,0,0,0,0,0,0,3565,12390,20713,28071,0,0,1706,25287,0,0,0,0,0,0,0,0, -14670,0,0,0,0,0,0,30534,0,0,0,12615,0,43750,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28228, -0,0,0,0,0,0,0,45095,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1224,3975,10954,6375,0,0,0,0 -,0,0,0,0,0,0,23180,20100,0,0,0,0,25736,8519,0,0,0,0,0,6663,0,2534,0,0,0,0,0,0,0, -0,23720,0,0,0,0,0,0,0,0,0,0,19398,0,47814,26281,49702,0,0,4332,12965,0,0,5704, -3206,0,0,0,0,0,0,0,0,0,0,0,0,0,15396,0,0,0,44102,0,0,0,0,0,0,0,0,0,0,0,0,0,25317 -,1064,39271,27433,0,14952,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14308,0,0,0,0,0,0,2763 -,4100,0,0,0,0,0,0,18792,0,0,0,22154,32583,0,6244,0,0,0,0,0,0,0,49478,0,0,0,0,0,0 -,0,0,0,0,0,21894,0,0,11048,0,0,0,0,0,0,11685,0,53862,0,0,15114,0,13870,0,0,0,0,0 -,0,0,919,0,0,0,31916,0,22570,101,0,0,0,0,0,0,0,0,0,7333,0,0,0,0,3272,0,0,0,0, -27718,32712,0,0,0,0,0,0,0,0,0,1782,0,3688,0,0,0,0,29862,0,0,0,0,0,0,0,22469,0,0, -0,0,0,0,0,55302,850,15492,0,0,0,5927,19786,13350,0,25702,0,0,0,0,0,0,0,0,0,0,0, -40390,0,0,0,0,0,0,0,0,0,0,0,0,0,20260,0,0,0,0,0,0,0,0,0,0,0,0,0,15335,8394,0,0,0 -,0,0,0,26566,0,0,0,0,843,2245,0,0,0,0,0,0,0,0,6959,0,20488,1638,0,0,11533,50759, -0,0,0,0,0,20871,0,0,0,0,0,24519,0,0,0,0,9544,23591,0,0,0,0,0,0,0,0,0,0,20969, -7109,29001,0,0,32422,31720,64294,0,0,0,0,16106,0,0,0,6930,4933,0,0,0,22917,0, -27015,0,0,0,0,19880,8070,0,0,0,0,23945,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3310,0,87,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18439,0,0,0,20742,0,0,0,10597,0,0,0,0,0,0, -0,0,0,0,0,0,20236,0,0,0,16584,3429,0,0,0,0,0,0,0,0,27241,0,0,0,0,16132,0,0,0,0,0 -,0,0,0,0,0,0,0,244,28261,0,0,0,0,0,0,0,29509,0,0,0,0,0,0,0,0,2921,31781,0,0,0,0, -0,0,6408,4196,344,0,0,0,0,0,0,0,0,0,0,0,0,0,11689,45863,0,0,0,0,906,3301,0,0, -25544,32421,0,0,0,0,0,0,0,0,1260,61607,0,27302,0,0,8682,16614,0,0,0,0,10830,0,0, -9604,15049,13413,0,0,0,0,0,0,26761,0,0,0,0,0,0,61990,0,0,0,0,0,12580,0,0,11432,0 -,0,0,0,0,22507,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12389,0,0,0,0,0,0, -2408,22661,14507,43239,0,9700,0,0,24714,0,0,0,0,0,0,0,0,23972,0,0,0,0,0,0,0,0,0, -0,0,0,0,34086,0,0,22955,7238,0,0,0,0,0,28485,13806,20038,0,0,0,0,22602,0,0,0, -1645,22340,0,0,0,0,0,0,0,0,0,0,0,26502,0,0,554,0,0,0,0,61735,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,0,0,0,2694,0,0,0,0,0,0,0,0,0,0,0,0,0,0,883,27879,15948,0,3242,57382,0,0 -,0,0,0,0,13930,0,0,0,0,0,30922,0,4137,52615,0,0,0,0,0,0,0,0,0,0,0,0,0,31911, -16072,0,0,0,0,0,0,0,0,0,0,0,0,26340,0,61671,0,0,0,0,3145,56199,0,0,0,0,0,0,0,0,0 -,0,0,0,280,0,5131,33479,0,15751,0,0,0,0,0,0,4136,1446,0,0,0,0,0,0,11304,17863,0, -0,0,0,0,25125,0,0,0,36646,6057,0,0,0,855,11301,0,0,0,0,0,64774,0,0,0,19397,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,1040,27367,0,0,0,0,0,0,0,0,0,0,0,0,0,64358,0,0,178, -132,0,0,14763,24455,0,0,0,46374,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,46246,0,0,0,37382, -0,0,0,7462,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8166,0,0,6921,0,0,0,9163,0,0,0,119, -0,0,0,23146,17156,0,0,0,0,0,9127,0,0,0,17927,0,0,0,0,0,22084,0,0,0,0,0,39879,0,0 -,2035,0,1067,0,0,0,0,0,16652,59591,0,0,0,0,0,0,0,0,0,0,0,0,20171,0,0,0,0,17733,0 -,0,0,0,0,32037,0,0,0,0,0,14277,0,0,0,0,0,0,0,42022,0,0,26793,20358,0,0,0,0,0,0,0 -,0,0,0,0,0,0,0,0,0,8907,0,0,0,0,0,0,0,0,27780,0,0,0,0,32330,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,39399,0,9732,0,16199,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,854,0,2984,45063,25418,26980,22539,0,9133,3653,15528,28743,4649,0,616, -65127,0,0,0,61863,0,0,0,0,0,0,0,55303,0,0,0,0,0,0,0,0,23880,0,0,0,0,0,0,0,31848, -62854,0,0,0,0,0,0,0,0,0,0,0,49606,0,27974,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,32580,0,0,0,26052,4043,0,0,40454,0,0,26056,30565,0,0,0,0,0,0,0,31398,0,0,0,0 -,0,0,0,0,29288,1797,0,0,3220,0,0,0,0,0,0,0,0,0,20427,0,0,0,0,23621,0,0,0,0,0,0,0 -,0,0,24261,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35591,0,0,6862,0,0,0,4265,0,6285, -5383,0,0,0,0,0,36870,0,39847,0,0,17224,5414,27882,58118,0,0,13224,4262,0,0,0, -31302,0,0,1388,2982,11881,0,0,0,0,0,0,16837,809,0,24140,10724,0,0,0,0,5835,0,0,0 -,0,0,0,0,0,0,0,0,1256,19237,0,0,0,0,0,0,0,5796,11848,0,0,52870,11464,0,0,0,0,0,0 -,0,0,0,5645,9158,0,25223,0,0,0,0,0,39142,24968,8135,32104,28678,0,0,0,46311,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23820,0,0,0,0,0,4050,0,1323,25220,0,0,0,20133,0, -0,0,0,0,0,0,0,0,0,0,9381,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,0,0,0,13444,1198,60806,0,0,0,0,17356,50247,30632,0,0,0,0,0,0,0,11944, -999,0,0,0,0,4010,10404,0,0,0,0,0,0,10346,0,0,49510,0,0,0,0,0,0,0,0,0,0,0,0,0, -38919,0,0,0,0,0,0,6351,60966,20137,487,0,0,0,0,0,0,655,2406,17387,43303,0,0,0, -17063,0,0,213,0,0,0,0,0,0,17221,0,0,0,0,0,0,0,0,0,0,0,10820,0,0,0,0,369,6,0,0, -9098,21093,0,31653,0,0,0,0,0,0,0,0,0,27143,0,0,16234,0,0,0,0,0,0,0,0,6020,31723, -28293,0,0,0,0,1936,30695,0,0,0,0,0,52902,0,0,29512,10791,0,20420,0,0,16010,0,0,0 -,0,0,0,0,0,0,0,0,5324,0,0,0,0,0,0,0,0,0,0,0,0,13383,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,24328,0,0,0,0,0,0,40870,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,24648,0,0,0,0,0,0,0,7786,2852,0,0,0,0,0,0,0,0,0,44678,0,17925,0,0,105,53062, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18762,0,0,40679,0,0,0,16165,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,20390,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,62310,1322, -14247,0,0,0,0,0,0,0,0,1832,6052,0,0,11882,0,0,0,0,17668,0,28262,0,29542,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,0,0,0,28007,0,0,0,57223, -1585,0,0,0,0,0,0,0,0,0,0,0,21162,0,0,62247,0,0,0,0,0,25414,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,0,36326,0,0,0,23845,0,0,0,0,0,0,0,2693,0,0,0,0,0,0,0, -13125,0,31236,0,0,0,0,0,22502,0,0,0,0,0,0,5994,10309,0,0,0,7269,0,0,0,0,17929,0, -1011,44647,0,0,0,0,0,14919,0,0,0,0,20586,5350,0,0,0,45702,0,13189,0,0,0,0,0,0,0, -0,0,35782,17992,0,0,0,0,0,8203,0,0,0,0,0,0,56678,0,0,0,0,0,38087,4233,0,2127,0,0 -,0,0,0,0,0,0,0,0,10148,0,0,0,2021,0,0,0,0,0,0,0,47206,0,0,0,0,0,0,0,9220,0,0,0,0 -,19465,0,0,0,0,0,0,0,0,39206,0,38055,0,0,0,0,0,0,0,46982,0,0,0,0,0,22054,3850,0, -0,0,0,0,0,0,55,0,10542,0,0,0,0,7239,0,0,0,0,0,59367,0,0,14761,0,0,0,0,43079,0,0, -0,0,0,2726,0,0,9582,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,37478,0, -0,0,31364,0,0,0,0,0,0,0,0,20393,8933,0,0,0,0,0,9380,0,0,0,0,16905,549,0,0,0,0, -182,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,1558,0,0,0,0,0,0,0,19242,0 -,0,0,0,0,0,24933,0,6276,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42310,23595, -24068,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13191,6158,2567,0,0,268,47047,0,0,0,0,0,0,0, -0,0,27940,0,0,0,0,0,26726,0,0,0,0,8200,1222,31562,0,0,0,0,0,0,0,0,0,2922,8231, -8904,29157,0,0,0,0,0,0,0,0,23976,4836,0,0,0,0,0,0,0,0,0,0,0,0,31658,0,0,31685,0, -0,2889,6213,0,0,0,0,0,13605,0,0,0,0,0,24772,0,0,0,0,0,0,0,0,0,0,20684,26468, -24075,0,0,0,21193,0,715,679,0,0,0,0,0,0,3050,7654,0,0,0,13798,0,0,0,0,15,27973,0 -,0,8491,2086,0,0,0,43206,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60391,0,0,0,0,0,0 -,0,25892,0,22276,0,34374,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20165,0,0,25672,0 -,0,0,1811,24839,0,31044,0,0,25513,0,0,0,0,0,12810,0,0,62438,0,0,1325,0,364,3782, -0,0,0,0,0,0,0,0,8042,19687,0,0,0,33415,0,0,0,0,0,0,0,0,0,0,0,7205,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,11844,0,0,0,0,3341,1543,6698,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,29766,0,0,0,0,0,0,0,0,0,0,0,41158,0,24294,0,3844,12329, -0,0,0,13738,0,0,0,0,0,0,0,0,26245,0,0,0,0,0,0,6378,0,343,4838,0,0,0,24358,11688, -0,0,0,0,0,0,0,0,0,1489,34759,0,0,0,0,363,51974,1878,11013,0,0,32265,59782,0,0,0, -28421,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22756,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14089,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,29257,61222,0,30661,0,28327,0,0,0,0,0,0,0,0,0,0,0,0,0, -27108,8843,0,9673,2084,0,0,0,16327,0,48455,0,0,0,0,0,0,4876,9316,0,0,0,0,0,0,0,0 -,0,0,0,0,9035,18852,0,0,0,0,0,0,0,0,0,0,0,0,0,4164,0,0,14827,1349,0,0,0,0,0, -11909,0,0,0,0,0,0,0,0,0,21765,0,0,0,0,0,0,0,0,31272,63910,0,0,0,25924,0,0,0,0,0, -0,0,0,0,44487,0,0,0,20612,0,0,27754,31428,0,0,0,0,0,0,0,17287,0,3943,0,0,0,63302 -,0,0,0,0,25256,19942,0,55142,0,39046,0,0,0,0,0,0,0,15367,0,0,0,0,0,0,0,0,0,0,0, -28422,0,0,0,0,0,0,0,0,0,0,0,0,9576,63847,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,25226,5734,0,0,0,0,0,0,13801,4997,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,43942,1270,2566,6284,0,0,16230,0,0,0,20678,0,0,0,0,0,38855,0,0,0,0, -29643,0,0,0,41,3655,0,0,0,0,0,14276,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,0,0,0,15686,0,0,0,15718,0,50694,0,0,16232,8007,0,0,0,5060, -329,11591,51,0,0,0,0,0,0,0,0,0,13065,7302,27530,15366,0,24934,0,0,0,17828,0,0, -4552,6311,0,0,0,0,0,0,0,0,0,0,0,47686,368,12103,10122,33830,0,0,599,18534,9579, -49479,0,5668,0,0,0,0,0,0,0,0,0,13157,0,0,0,0,23274,14055,0,0,0,0,0,48903,0,0,0,0 -,0,0,1871,0,15434,0,0,0,16174,62470,0,0,0,0,0,0,0,0,0,0,0,7749,0,0,0,0,0,0,0, -30501,0,0,0,0,25675,0,0,0,0,0,0,0,0,0,0,9285,0,0,25323,1669,0,0,0,0,0,0,0,0,0,0, -0,3588,0,0,0,0,0,32902,0,0,4426,0,0,0,0,57959,0,0,0,0,0,0,29898,58278,0,0,0,0, -11880,1220,0,0,0,41479,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23141,0,0,0,0,0,0,0,0,0,0,0 -,0,0,42566,0,0,0,0,0,0,0,40167,9484,3493,0,0,0,0,0,21126,0,0,0,0,8649,18918,0,0, -0,0,0,0,0,34886,2601,0,0,0,0,12518,0,0,0,0,7976,10311,0,0,0,0,0,0,0,45190,0,0,0, -0,0,0,0,0,0,0,16842,20229,0,0,0,0,0,0,7528,4614,0,0,0,0,0,30086,0,0,0,1671,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,9896,6277,0,0,0,0,0,61191,0,41287,0,21956,0,0,20010,0,0,0 -,0,0,0,0,0,0,0,0,13195,0,0,0,0,1381,0,0,0,0,365,30951,24268,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,7044,0,0,0,0,0,0,0,0,0,0,27944,359,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,28487,0,0,77,0,0,0,0,0,0,0,0,56775,12586,8421,0,0,0,0,0,0,26185,14599,0,0, -8040,5702,12585,3109,0,0,0,0,0,21574,5388,0,0,0,0,0,0,0,5106,52454,0,0,0,0,0,0,0 -,0,1907,29895,0,6116,0,0,0,0,11081,5285,0,28069,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4104 -,0,0,0,0,0,0,41511,0,0,0,0,0,0,5262,0,0,0,503,4231,7720,34343,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7304,10374,1718,0,0,29127,0,0,0,0,0,0,0,0,23497, -22567,6952,2340,0,0,0,0,0,0,0,0,20360,12453,0,45094,0,0,0,0,0,28582,0,0,0,0,680, -0,0,0,0,0,0,0,0,0,0,0,0,0,23084,0,0,0,30696,0,0,0,0,45862,0,0,0,0,0,0,0,0,0,0,0, -0,5580,6053,0,0,0,0,0,0,0,0,0,0,712,70,0,0,26091,11335,0,0,0,0,13612,0,13160, -1926,435,51559,0,0,0,0,0,0,0,0,0,0,0,0,0,47302,19083,0,0,12742,0,1607,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,6155,37095,0,0,0,0,0,18948,7146,0,0,0,0,0,0,0,7848, -2055,0,0,0,0,8910,0,19336,0,0,48070,8490,0,0,0,0,0,0,0,9932,56423,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,4133,0,0,0,0,0,0,0,0,0,43398,0,0,0,0,0,0,0,0,16173,0,0,0,0,0 -,0,0,32011,0,0,30918,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26854,0,0,0,0,0,0,0,0,0,0,0,0 -,0,20389,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18889,0,0,0,0,8965,0,0,0,44358,0,0,0,8997,0 -,34055,0,0,0,0,0,29350,0,0,501,17767,0,0,32457,60262,0,0,0,30886,0,0,3757,1063,0 -,0,0,25637,0,0,0,0,0,28068,0,26374,0,0,0,0,0,0,0,0,0,0,0,11684,0,0,0,0,0,0,24779 -,229,0,13766,0,0,7402,11525,0,0,0,0,0,0,0,0,26313,23686,0,0,29736,47527,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27268,0,0,0,0,553,0,0,0,0,0,0,32038,0,0,0,0,1135, -26596,0,0,12300,14631,0,0,0,43238,0,871,0,0,31496,0,8457,17669,0,12836,0,0,0, -22726,0,38758,0,0,375,6564,0,0,0,0,0,0,0,0,0,0,0,0,170,18535,0,22948,0,0,32360,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,25764,0,0,0,0,0,0,0,0,0,0,0,15652,0,0,0,32774,0,0,0,0 -,0,0,0,0,0,28551,0,0,0,0,0,0,0,0,0,0,0,0,15145,0,0,0,21100,27654,0,0,0,0,0,0, -4874,26215,0,1639,0,0,0,0,0,0,0,0,0,0,4169,0,0,0,0,0,7336,0,0,0,0,21572,0,0,0,0, -0,0,0,0,0,24644,1675,2533,0,0,0,53318,0,13094,0,0,0,0,0,0,0,6246,0,22020,0,0,0,0 -,0,0,0,0,0,0,0,28453,5576,5124,0,0,0,0,0,0,0,0,0,0,0,0,0,27910,0,29382,18216, -8583,0,0,0,39174,0,43558,0,0,0,0,0,0,0,0,0,11973,0,0,0,0,0,23397,0,0,0,0,6091,0, -0,0,0,0,0,0,6474,16197,14217,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,26728,0,567,48839,0,0,0,0,0,15271,0,0,31818,43974,2450,0,0,0,0,0,0,0, -11368,9191,0,44454,0,0,0,0,0,0,14568,12293,0,0,0,8453,0,0,0,0,0,0,0,0,0,0,0,0, -32040,0,0,0,0,0,0,0,0,0,0,0,0,902,0,0,0,27236,5612,11495,0,0,0,0,0,0,0,0,9194, -23684,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27430,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -26217,44870,0,0,0,0,0,0,5581,7173,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -52775,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20968,18340,0,0,0,0,0,0,0,0,4107,11239 -,0,0,0,0,0,0,0,0,0,0,0,29381,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21990,0,0,0,0 -,0,0,0,0,0,48806,0,0,0,32292,0,0,0,0,0,0,0,10884,0,0,0,0,0,0,0,0,0,0,27562,0, -5643,0,0,0,0,0,0,0,0,0,3089,31525,0,19684,0,0,0,0,0,0,0,61415,0,0,0,0,0,36198,0, -0,0,0,0,0,0,7908,0,0,0,0,872,743,0,0,0,0,0,0,0,0,1229,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,32484,0,0,0,0,0,34822,0,0,0,0,0,50726,0,0,0,0,7274,0,0,0,15304, -11526,0,0,0,3047,0,0,0,0,0,0,22376,0,0,0,846,0,0,0,0,35815,0,0,0,23652,0,0,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,23721,2148,0,0,0,0,0,0,14856,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,1358,0,3082,0,0,0,848,10949,0,0,0,0,0,0,6504,0,0,14372,0,0,0,0,0,0 -,0,0,0,0,8201,9958,0,0,0,0,0,0,24266,0,0,0,0,0,0,0,0,26469,0,0,0,0,18604,2053,0, -33511,0,0,0,0,0,9222,0,0,0,0,0,44006,0,0,0,0,0,0,0,0,0,0,0,41895,0,0,0,0,0,0,0,0 -,12044,390,0,0,0,0,0,4935,0,48646,0,56102,3052,16070,0,0,0,0,0,0,0,8612,9320, -38311,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,500,0,0,0,0,42918,0, -32550,0,0,0,0,0,0,0,0,27434,57926,17064,0,0,46502,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,26760,6756,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,624,0,5000,0,0,0,0,32293,0, -0,0,0,0,0,0,0,0,0,0,0,0,26246,0,0,0,0,0,0,0,0,23,7301,0,0,0,36199,0,40838,0,0,0, -0,0,0,0,0,0,0,0,0,27178,57350,0,0,12457,9317,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,0,0,16810,0,0,0,14510,0,0,0,0,21319,0,0,0,13508,17, -11365,0,0,0,0,5291,0,8329,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27685,0,0,0,0,0,0,0, -52006,0,0,0,7493,0,44263,0,0,0,0,0,0,0,0,9800,0,0,0,25676,61478,0,0,0,0,0,0,5773 -,0,0,0,0,41991,26057,0,0,0,0,0,0,0,0,0,0,22629,0,0,0,47783,362,1959,23468,0,0,0, -10921,0,0,0,3150,0,0,0,0,0,0,0,0,0,0,0,32456,0,0,0,0,0,0,0,4559,3270,0,0,983,0,0 -,26343,0,33446,0,0,0,61767,0,48390,0,0,0,0,0,0,0,2790,0,39782,7849,0,0,0,0,0,0,0 -,1544,2183,0,0,0,0,0,0,0,0,4040,2471,20009,30020,0,0,11242,0,0,0,5578,53382,0, -22631,0,0,0,0,0,0,0,0,0,0,0,12901,0,0,0,0,0,0,0,0,0,0,0,0,215,0,0,9030,0,0,0,0,0 -,0,265,1412,0,0,11626,3687,0,0,0,0,0,0,0,0,0,0,0,0,17449,24359,0,0,26729,40134,0 -,0,0,0,29768,61958,0,0,0,0,0,0,0,0,20908,0,0,0,0,0,11016,0,0,47462,21547,5926,0, -0,14728,2983,24104,15301,0,0,0,0,0,32645,0,0,0,0,0,0,0,3300,0,0,0,15972,0,0,0,0, -0,0,6634,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3076,0,30983,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,106,0,0,0,0,12775,0,0,0,0,7177,18022,0,0,0,0,0,22534,0,0,0,0,0,0,0,0,0,0,0, -49894,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27560,0,0,0,0,30278,10668,23877,0, -0,0,0,0,0,0,29124,0,0,0,0,0,0,0,0,0,0,0,0,0,20870,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,44582,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48454,0,0,0,0,6442,0,16330,22951,0,0 -,16904,0,0,0,0,644,0,0,0,40038,0,0,0,37222,0,0,0,9830,0,0,0,0,0,34919,0,0,0,0,0, -0,0,0,0,0,0,13733,0,0,0,28196,0,0,0,0,0,19876,0,0,0,0,0,0,0,23558,0,11142,0, -27781,0,0,0,0,13864,0,0,0,24682,47847,0,0,0,0,6890,0,0,0,0,0,3981,0,0,0,0,0,0,0, -0,0,0,0,1772,0,0,0,0,0,0,0,3603,1991,0,27396,8652,0,18312,0,0,0,0,30054,0,0,0,0, -0,0,0,11270,0,0,0,0,0,0,0,0,0,20708,0,0,0,0,338,0,0,0,0,0,0,0,7050,0,0,0,0,0,0,0 -,0,0,0,0,0,0,14862,0,0,3492,0,0,0,55878,0,0,0,16486,0,0,0,18119,0,0,0,0,0,0,2154 -,1284,0,0,23113,31751,0,0,29547,0,0,0,0,0,0,36647,0,0,0,0,0,0,0,0,0,0,0,18183,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,7913,0,0,0,0,20644,0,0,10508,0,0,0,0,0,0,0,0,0,0,0,0, -43622,0,0,0,0,0,40966,0,0,0,0,0,0,0,0,0,0,246,901,11529,5191,0,0,0,0,0,0,0,0,0,0 -,0,24454,0,0,26665,27590,0,27397,0,0,0,0,0,0,23562,2949,0,0,30344,62214,0,47334, -2026,18885,0,0,0,48678,0,0,0,22694,0,0,1972,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,15465,0,0,0,0,38822,0,0,0,0,945,32708,0,54791,0,14918,0,0,0,0,0,0, -0,0,0,0,0,0,0,23396,0,0,0,0,0,0,5486,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7722,0,0, -0,0,0,0,0,0,0,0,0,30856,64166,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35206,0,0,0,30535,0, -0,0,0,0,0,0,0,0,62663,0,0,1096,17574,31820,0,0,14375,4402,27207,0,0,21448,4676,0 -,0,0,0,16585,5094,0,0,0,0,0,0,0,0,4845,0,0,32870,0,0,0,0,0,0,0,0,0,0,31466,0,0,0 -,0,31783,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4522,16039,0,0,0,0,0,0,0,0, -0,14469,0,0,0,0,0,0,0,0,0,0,7464,4773,0,0,0,0,0,0,0,0,18636,0,0,0,25640,0,0,0,0, -0,0,2244,0,0,11818,0,1168,0,0,0,0,0,0,0,6540,23079,13770,7719,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,0,0,0,0,0,0,0,0,0,0,0,58150,528, -34502,32682,0,0,12997,0,0,0,0,0,2214,0,0,0,0,0,58567,0,0,0,26375,0,0,0,0,0,0,0,0 -,0,26437,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26121,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,32005,22952,59047,0,13543,0,0,0,0,0,0,0,0,16328,0,0,33542,0,0,0,19782,0,0,0, -16644,0,0,0,0,31688,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10276,0,0,0, -0,0,0,0,36327,0,0,29480,0,0,0,777,12709,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27398,0,0, -0,4455,9037,31397,0,9221,0,0,0,60487,20840,1796,0,0,0,0,0,0,0,0,8364,0,0,0,0,0,0 -,0,0,0,0,0,19752,44902,0,38566,0,0,18027,0,0,0,0,0,0,0,0,10662,0,0,0,0,0,11812,0 -,0,0,0,0,0,0,0,0,19910,0,0,0,45030,0,0,0,0,0,0,0,0,0,0,0,0,19978,5127,0,11620,0, +BROTLI_INTERNAL const uint16_t kStaticDictionaryHashWords[32768] = { +1002,0,0,0,0,0,0,0,0,683,0,0,0,0,0,0,0,1265,0,0,0,0,0,1431,0,0,0,0,0,0,40,0,0,0, +0,155,8,741,0,624,0,0,0,0,0,0,0,0,0,0,0,0,66,503,0,0,0,451,0,0,0,0,0,0,0,835,70, +0,0,539,0,0,0,0,0,0,0,0,0,113,0,0,0,0,718,0,0,0,0,0,0,520,0,1070,0,0,0,0,0,1515, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,78,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,0,610,0,0,750,0,0,0,307,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,964,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,0,999,0,0,0,0,0,0,0,0, +645,75,0,649,52,282,0,200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1621,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,211,225,0,0,687,718,0,0,110,0,58,0,0,0,0,0,0,345,0,0,301,0,0, +0,203,0,0,1154,674,1949,0,0,0,0,0,0,0,0,0,259,0,0,0,0,0,0,0,1275,0,0,0,1231,254, +0,0,0,0,0,0,0,277,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,0,0,800,0,0,0,29, +116,100,490,0,0,0,0,0,1641,0,543,0,0,0,0,41,181,0,657,0,0,202,25,0,0,0,0,0,0,0, +0,0,0,423,0,0,0,113,0,0,0,927,963,0,976,0,206,0,0,0,0,0,0,0,0,0,2002,0,0,0,0,0, +0,0,0,0,0,0,696,0,1170,0,0,0,0,226,13,0,769,678,551,0,0,0,0,0,0,57,0,0,0,10,188, +0,0,0,624,0,0,0,0,0,0,0,0,0,1941,130,0,0,0,0,378,269,0,0,528,0,1146,0,0,0,1105, +0,1616,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,656,0,1940,0,0,0,0,0,173,0,0,0,0,0,0,0,0,0, +0,0,457,342,810,0,0,0,0,620,0,0,0,0,0,0,0,967,95,447,406,0,0,0,477,0,1268,944, +1941,0,0,0,629,0,0,0,0,0,375,0,0,0,1636,0,0,0,0,774,0,1,1034,0,0,0,0,0,824,0,0, +0,0,0,118,0,0,560,296,0,0,0,0,0,0,0,0,1009,894,0,0,0,0,0,0,0,0,0,0,0,0,0,1474, +366,0,0,0,0,0,0,0,0,0,79,1723,0,0,200,0,0,0,0,0,0,0,0,1759,372,0,16,0,943,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,258,0,0,900,1839,707,30,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,2004,0,0,10,115,0,50,0,0,0,0,0,0,0,0,0,0,520,1,0,738,98,482,0,0,0,0, +0,0,0,0,0,0,701,2,0,0,0,0,0,0,0,0,557,0,0,0,0,0,0,0,0,0,347,0,0,0,0,572,0,0,0,0, +0,0,0,0,0,832,0,0,797,809,0,0,0,0,0,0,0,0,0,0,0,528,0,0,0,861,0,0,294,0,0,0,109, +0,0,0,0,0,0,0,0,1187,290,266,0,0,0,0,49,50,748,0,0,466,399,0,0,0,0,0,0,0,378,0, +519,0,0,0,0,0,0,0,0,0,0,0,0,667,351,902,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,180, +0,0,869,0,0,0,0,0,0,0,260,0,0,0,0,0,0,0,0,0,0,523,36,0,0,587,510,809,29,260,0,0, +0,0,0,0,0,0,570,0,565,0,1464,0,0,0,0,0,0,10,0,0,787,399,380,200,0,0,0,0,516,0, +844,887,0,0,0,0,0,0,0,44,0,0,0,305,1655,0,0,0,0,0,0,0,0,0,0,0,0,0,0,786,10,0,0, +0,0,0,0,0,0,0,2031,0,0,0,0,0,684,0,0,0,0,0,1480,0,0,0,27,0,0,0,395,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,813,511,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,0,0,0,206, +496,0,0,0,0,0,909,0,891,0,0,0,0,0,0,0,0,0,687,0,0,0,1342,0,0,0,0,0,0,0,0,0,0, +160,41,0,0,0,0,0,0,0,0,0,0,0,1718,778,0,0,0,0,0,0,0,0,0,0,1610,0,0,0,0,0,115,0, +0,0,0,314,294,0,0,0,983,178,193,0,0,0,0,0,0,0,0,0,174,0,0,0,0,0,0,0,0,0,0,848, +1796,0,0,0,0,0,0,221,0,687,1660,0,0,0,0,262,0,0,179,0,0,0,0,0,66,0,773,0,352,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35,0,152,0,0,1197,0,0,0,0,0,0,0,0,0,0,0,0,560,0,0, +564,0,0,0,797,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,556,0,819,0,0,0,0,0,0,0,0,719,544, +637,5,0,0,0,0,0,0,0,0,0,0,0,101,0,1441,0,0,0,893,0,0,0,0,0,0,0,0,0,238,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,1296,0,0,969,1729,314,60,0,0,0,0,0,1144,0,1147,0,0,0,0,0, +0,0,0,0,0,437,1853,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,828,0,176,0,0,0,0,0,0,434,39,0, +0,0,0,0,159,0,0,0,902,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,270,0,0,0,0,801,556,0,0, +0,0,0,0,0,416,19,197,369,0,0,0,0,0,0,0,0,0,28,34,0,757,0,0,898,1553,0,721,0,0,0, +0,1012,0,0,0,0,1102,0,898,183,0,0,0,0,0,0,0,136,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,0,0,0,247,277,0,0,0,435,0,0,0,0,0,1311,0,0,0,0, +0,0,211,437,0,0,0,28,0,0,750,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2012,0,702, +0,808,0,0,0,0,739,166,0,0,0,0,0,0,719,170,500,0,0,0,0,0,0,0,0,1500,327,0,0,450, +0,0,0,1318,0,0,0,1602,0,0,331,754,0,0,0,0,0,1368,0,0,557,0,0,0,799,850,0,0,0,0, +0,0,0,0,908,0,0,0,0,0,19,62,459,0,0,0,0,0,0,0,0,0,0,0,0,1802,0,0,0,0,0,0,0,0,0, +1397,0,0,0,0,120,238,0,0,0,0,0,0,0,0,0,0,0,1324,0,0,0,0,0,0,0,0,602,201,0,0,164, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,615,0,0,0,0,0,0,0,0,0,0,0,0,0,1243,0,0,0,0,968,0,0, +0,0,0,0,882,0,0,0,907,329,100,0,0,0,0,0,0,0,0,0,0,0,176,26,9,0,0,265,256,0,0,0, +0,0,0,0,0,0,643,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,610,0,0,0,0,973,2001,0, +0,0,0,0,0,522,0,0,0,0,0,0,0,0,0,0,0,553,0,0,0,0,0,0,1582,0,1578,0,0,0,0,0,0,0,0, +0,0,0,795,0,0,0,432,0,0,0,0,0,0,84,126,0,0,0,0,790,0,377,64,0,1529,0,0,0,0,530, +1857,539,1104,0,0,0,0,0,0,0,0,0,0,0,0,977,0,0,0,34,0,0,0,0,0,0,0,0,0,0,0,24,26, +0,0,918,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,183,379,0,0,0,0,0,0,0,792, +0,0,0,0,0,0,0,0,0,1920,0,0,0,0,0,0,0,0,0,771,0,0,0,1979,0,901,254,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,0,0,0,140,0,0,0,0,0,440,37,0, +508,0,0,0,513,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,8,0,0,533,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,752,920,0,1048,0,153,0, +0,391,0,0,1952,0,0,0,0,0,0,0,0,0,0,126,0,0,0,0,640,0,483,69,1616,0,0,0,0,0,734, +0,0,0,0,0,0,480,0,495,0,472,0,0,0,0,0,0,0,0,874,229,0,0,0,0,948,0,0,0,0,0,0,0,0, +1009,748,0,555,0,0,0,0,0,0,193,0,653,0,0,0,0,0,0,0,0,0,0,984,0,0,0,172,0,0,0,0, +0,0,0,0,83,1568,0,0,384,0,0,0,0,0,0,0,164,880,0,0,0,0,0,0,0,0,0,0,0,367,121,0,0, +828,0,0,0,0,0,0,0,1541,0,0,0,0,0,0,0,343,0,0,0,0,0,0,0,0,561,57,0,0,0,0,0,0,0, +926,0,0,0,0,827,0,194,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22,0,0,0,0,0,0,0, +0,0,0,896,1249,0,0,0,0,0,1614,0,0,0,860,0,0,0,0,0,0,0,0,964,102,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,899,0,569,0,0,0,0,795,2045,0,0,0, +0,0,0,104,52,0,0,0,0,0,604,0,0,0,0,779,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0, +494,0,677,0,0,0,0,0,0,0,508,0,0,0,0,0,0,0,0,0,1014,0,957,0,0,630,310,0,0,0,570, +0,0,449,0,64,537,0,0,0,0,0,0,0,244,0,0,0,0,0,0,0,0,0,0,0,0,0,0,702,1650,49,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,338,0,0,0,0,1279,0,0,0,0,0,0,0,896,0,0, +178,0,0,0,0,0,0,0,0,0,0,0,0,0,808,695,0,0,0,0,539,1117,0,0,0,0,0,0,0,0,257,0, +1003,0,0,0,1,448,0,516,0,0,960,0,125,4,0,1268,30,748,0,0,852,0,0,0,6,0,0,848, +236,1385,862,1811,0,0,0,0,698,803,0,0,0,0,0,0,0,610,992,0,0,878,0,1847,0,0,0,0, +0,0,0,383,0,1404,0,0,0,0,986,0,347,0,0,0,0,0,0,0,0,0,0,0,592,572,0,1411,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,606,0,0,0,0,0,0, +0,0,0,0,0,0,0,1829,0,0,0,0,0,0,0,0,0,0,0,0,700,748,0,0,0,0,0,0,365,0,0,127,0,0, +83,198,0,0,0,0,0,0,864,55,0,0,0,0,726,1752,0,0,0,0,0,0,0,0,0,0,0,0,0,1066,0,764, +0,0,0,0,683,0,550,309,0,0,874,1212,0,0,0,1364,0,986,381,723,0,0,0,1573,0,0,0,0, +0,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1559,0,0,0,0,493,133,0,0,0,0,148, +119,0,0,0,0,0,0,537,14,541,0,635,126,0,0,0,495,0,0,0,0,861,998,1009,0,0,0,0,0,0, +0,359,368,0,0,0,0,304,1577,0,0,0,0,0,1107,0,0,0,0,0,929,0,0,0,1142,0,0,0,0,289, +175,0,432,0,219,0,0,0,0,0,785,0,0,595,0,0,0,0,0,0,0,0,0,0,0,0,0,80,0,0,0,0,0,0, +931,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1323,0,0,0,0,290,0,559,1751,127,0,0,0, +934,1167,0,963,0,260,0,0,0,573,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +580,1689,0,0,0,0,0,0,0,0,0,1164,0,0,982,1922,0,63,0,0,0,0,0,793,0,0,0,0,0,0,0,0, +0,0,0,0,0,67,790,0,0,0,0,0,0,0,0,0,0,391,443,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,271,0,0,0,0,0,0,0,0,0,0,0,1140,0,0,0,0,340,300,0,897,0,0,0,0,0,0, +0,0,0,0,890,0,0,0,0,818,321,53,0,0,0,0,0,0,0,0,0,468,0,243,0,870,0,0,0,1765,121, +0,0,0,180,518,0,822,419,634,0,0,0,0,0,0,0,0,0,898,0,0,0,0,454,36,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,806,0,0,0,0,0,0,0,0,0,0,0,0,1326,0,104,0,0,0,0,0,0,0, +0,0,260,0,0,0,0,0,0,0,0,0,0,0,0,542,45,0,0,263,1516,42,0,0,0,0,0,468,0,1005,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,288,87,0,0,0,0,0,0,0,0,502,988,133,0,0,0,0,0,0, +141,0,0,872,1842,0,0,0,0,0,0,0,0,261,619,0,0,0,0,189,246,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,678,0,0,0,0,0,0,0,0,0,0,0,0,285,35,0,517,0,0,0,0,0,0,0,0,0,0, +540,214,667,0,74,0,0,125,0,0,0,0,0,761,131,0,0,0,0,0,0,0,0,0,0,0,0,0,333,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1338,94,0,0,0,0,0,0,0,0,0,0,0,0,449,0,646,103, +86,641,2028,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,869,87,277,117,39,0,0,0,0,0,0,0,0,938, +297,0,0,0,0,558,464,0,0,0,0,0,0,0,0,0,0,731,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1608,0, +0,0,0,0,0,0,1429,0,0,733,1010,0,0,338,1656,0,0,0,1038,979,2010,0,0,0,0,0,0,0, +1005,0,0,121,0,0,0,219,20,0,0,0,0,0,0,872,1440,0,0,0,683,0,1070,0,0,522,0,0,0,0, +439,669,0,0,0,0,0,0,0,0,1245,0,0,0,0,0,1218,0,0,547,233,0,0,0,0,0,0,0,0,0,482,0, +0,0,0,0,0,0,886,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,795,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,371,0,0,0,0,0,0,0,0,0,0,0,0,0,622,0,625,0,0,0,339,29,0,0,338,0,0,0, +0,130,0,0,0,0,0,0,0,0,0,307,0,0,0,0,0,0,0,0,0,0,2044,0,0,0,0,0,0,0,0,308,770,0, +0,0,0,0,1266,0,0,0,0,0,0,0,0,0,400,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,690,739,0,0, +0,0,0,0,0,990,0,0,0,1831,0,0,0,0,0,0,0,0,0,0,0,0,0,613,0,0,0,0,0,0,0,0,0,0,0,0, +0,763,0,878,0,0,0,977,0,100,0,0,0,0,0,0,0,0,0,463,0,0,0,0,623,318,0,0,296,463, +137,0,0,454,0,0,0,1527,58,0,0,0,0,0,0,0,18,48,0,0,0,0,0,729,0,0,0,442,0,0,0,0, +40,449,0,853,0,0,0,0,0,0,227,0,0,0,0,0,0,1491,0,0,0,0,0,0,0,0,0,0,161,55,0,450, +0,1174,62,0,207,0,0,0,0,0,0,0,0,869,0,0,0,0,80,213,0,0,0,0,0,0,0,0,0,0,354,820, +0,0,747,0,0,0,954,0,0,1073,0,556,0,0,0,692,0,191,0,804,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,831,162,0,0,35,0,0,0,0,0,0,0,0,1235,0,0,0,0,0,1234,0,0, +0,0,0,0,0,0,0,0,96,0,0,0,0,0,0,0,149,0,0,0,902,204,0,0,833,0,287,366,0,0,0,0,0, +0,992,2020,0,0,0,0,0,0,0,0,0,0,0,356,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,784,0,0,567, +630,0,0,0,539,0,0,27,0,0,0,0,0,0,0,0,0,0,755,0,0,0,0,0,0,0,0,0,0,0,0,814,0,0,0, +0,0,0,0,0,0,0,0,0,0,987,0,0,255,761,194,0,1086,0,0,0,0,0,0,1016,0,0,1396,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,562,271,913,0,0,0,0,0,0,0,0,320,153,45,475,0,0, +0,0,0,0,0,713,0,327,0,0,0,0,0,0,604,552,3,359,0,0,0,0,853,80,0,0,0,0,0,0,0,2016, +6,887,0,0,0,0,975,0,961,0,0,0,0,0,916,1891,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,100,101,390,708,0,0,0,587,983,512,0,0,0,0,0,0,0,0,0,0,0,645,0,0,0,851,0,0,0, +0,0,498,140,217,0,0,0,1448,0,0,0,0,0,0,0,0,0,905,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +643,105,0,792,0,0,0,0,0,0,0,0,0,0,0,0,56,0,0,0,0,0,0,0,0,0,0,535,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1748,0,0,0,0,0,754,0,0,0,0,0,0,0,0,0,0,0,0,91,0,0,1565,0,91,792, +939,3,370,0,0,0,0,95,0,0,0,0,551,7,619,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1150,0, +0,0,0,0,0,0,0,0,0,0,0,0,671,0,0,0,0,0,888,368,149,0,0,105,1134,0,983,0,0,458,31, +0,643,0,0,0,312,0,740,0,0,0,1642,0,0,0,0,0,0,0,236,0,0,0,0,0,0,0,59,68,0,0,0,0, +0,867,795,0,0,0,0,970,1977,0,0,0,0,0,0,0,1148,0,775,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,970,0,0,0,0,0,0,0,0,0,665,71,0,0,0,0,827,0,0,0,0,0,0,0,0,0, +0,479,0,0,0,0,0,0,0,0,99,607,0,0,0,0,0,0,0,1960,0,0,0,793,0,0,871,41,0,0,241,94, +0,0,0,0,209,0,0,1497,0,0,0,0,0,0,0,0,0,98,0,0,0,463,0,0,0,0,291,0,0,0,0,0,0,0,0, +0,0,984,0,0,0,0,0,205,0,0,0,0,0,0,205,42,0,801,0,0,0,0,0,635,0,0,533,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,371,0,1282,0,0,0,825,0,0,0,0,0,0,0,0,0,357,879,467,0,317,0,0, +0,0,0,0,0,924,0,0,0,0,849,1795,0,0,0,0,895,1799,43,0,0,0,0,0,0,0,0,0,0,1820,0,0, +0,0,0,0,0,525,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,110,0,493,0,174,417,0,0, +0,0,0,583,733,0,0,0,0,0,0,481,215,0,0,0,0,477,0,0,0,0,0,0,0,0,308,0,0,0,0,0,0,0, +0,297,126,0,0,361,1551,0,0,0,0,0,0,871,1807,0,0,0,0,0,1307,0,685,0,0,0,0,0,0,0, +797,0,858,0,565,0,0,0,0,0,0,0,0,0,0,0,0,434,252,826,0,0,0,0,0,0,791,0,0,0,0,509, +231,178,601,0,0,0,0,0,0,0,0,43,1591,0,0,0,0,0,1683,0,0,0,0,45,0,0,0,0,0,0,0,0,0, +0,1120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,556,494,0,398,0,0,0,1030,0,0,0,0,0,0, +168,0,0,0,0,0,0,0,0,0,0,973,0,642,0,0,0,0,0,0,0,0,0,1615,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,378,594,0,1093,0,679,112,0,0,0,0,1492,540,1374,714, +1486,0,0,0,0,825,1511,0,0,0,0,0,0,0,0,0,0,0,0,0,952,0,0,736,143,0,700,0,1540,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1557,0,0,0,860,990,0,0,0,807,0,0,0,0,0,131, +515,0,646,0,0,0,0,117,728,508,121,0,0,0,0,0,0,357,0,0,0,0,0,0,237,0,0,0,0,0,0,0, +0,0,1784,0,0,0,0,0,0,0,0,0,0,0,713,348,1536,0,738,0,0,0,0,0,0,0,434,0,0,0,0,0,0, +366,1877,39,0,0,0,0,0,0,580,0,0,0,0,0,0,0,0,0,0,0,0,0,0,873,0,0,0,0,171,0,625, +550,107,343,943,0,0,0,0,0,0,0,768,0,0,0,0,0,0,0,799,0,0,0,894,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1673,0,0,0,0,0,0,0,0,0,0,0,1052,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +272,0,441,0,0,3,9,0,0,0,1182,0,1346,0,0,0,0,0,0,0,0,682,0,0,1004,24,0,0,968,0,0, +0,2,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,185,0,0,0,578, +474,0,0,0,0,0,0,0,0,0,0,0,0,0,0,113,530,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,556,0,0,0,0,0,0,16,1317,0,0,97,0,0,0,703,0,0,0,0,0,0,0,0,892,0,0,0,1571,0,0, +426,186,0,1101,0,0,0,0,0,0,0,0,937,585,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,644,291, +0,0,0,0,749,0,162,0,0,381,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,762,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,628,21,0,0,0,0,0,0,0,0,919,0,0,0,0,0,0,0,0,0, +633,0,0,0,0,332,0,0,0,0,0,0,0,0,0,1489,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,832,398,0,645,0,0,0,13,0,0,0,0,0,0,0,0,0,0,20,0,800,0,0,0,0,0,0,0,0,0, +0,0,0,0,1993,0,0,0,0,769,0,0,0,665,0,0,0,0,0,0,0,0,0,0,1426,0,0,0,0,60,0,0,0, +641,1874,0,644,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1757,0,0,0,0,0,937,0,1652,0,654,0, +0,0,0,0,0,0,527,0,0,0,0,0,0,0,0,0,0,0,0,0,226,0,0,0,0,0,1486,0,0,0,0,0,0,0,0,0, +0,0,325,0,0,0,0,0,0,0,1345,0,0,91,0,404,0,0,0,0,0,0,0,0,0,0,0,0,973,0,0,0,0,0,0, +0,1176,0,549,0,0,0,0,0,0,0,0,0,0,976,0,0,0,0,0,21,0,0,0,0,0,51,0,0,0,0,314,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,198,6,0,1093,0,0,0,0,0,0,0,0,0, +0,0,0,0,1776,0,0,0,0,0,1528,0,419,0,0,0,0,0,0,0,0,76,138,0,0,0,0,638,29,0,0,0,0, +0,0,0,1418,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,1710,0,0,0,0,0, +0,0,0,0,0,0,0,532,23,0,0,0,0,0,0,0,862,0,0,946,592,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,70,0,0,0,0,0,0,0,0,0,812,0,0,0,76,0,0,988,0,442,0,0,0,896,0,0,0,0,0,0, +483,0,0,0,0,1709,0,0,0,0,0,0,119,0,0,0,117,0,309,0,0,0,0,0,596,976,0,0,0,0,0,0, +0,0,0,0,0,768,0,0,0,0,0,0,0,0,0,518,0,0,0,0,0,0,0,0,0,0,0,0,0,0,863,0,0,0,24, +145,1020,0,0,1984,0,0,0,0,0,0,0,658,0,0,0,0,0,0,0,0,0,0,106,1827,0,1010,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,582,87,0,0,0,0,0,0,0,267,0,0,0,703,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,496,0,0,0,0,1121,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,249,561,0,0,0,0,0, +0,0,760,0,0,154,0,0,0,255,0,419,323,0,0,0,0,0,368,0,0,0,0,0,0,0,0,0,0,522,0,0,0, +0,0,0,0,551,562,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,92,0,0,0,0, +0,0,0,284,525,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,958,0,0,594,0,0,0,0,0,0,6,479,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,61,0,0,0,0,0,0,0,820,1641,0,1556,0,0,0,0,0,0,0,302,0,0, +0,0,0,148,0,0,676,0,0,0,0,0,0,1674,0,0,0,0,0,0,178,0,0,0,0,0,0,0,94,389,0,0,0,0, +91,8,0,0,0,0,0,0,0,0,0,0,112,0,0,0,0,0,0,0,0,0,0,747,0,0,0,0,0,0,0,1746,0,0,0,0, +0,24,0,1352,158,1530,0,0,718,130,280,1401,0,0,0,0,0,1946,8,0,0,0,0,1607,0,0,0,0, +0,0,882,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,417,0,0,0,1597,633,433,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,234,0,0,0,0,0,0,0,0,680,1950,0,0,0,0,249,5,0,0,0, +0,0,0,0,0,0,1216,0,1773,0,0,0,0,0,0,0,0,0,0,0,0,0,0,509,180,0,0,0,0,0,0,0,1002, +0,0,0,0,0,0,0,0,0,0,0,0,0,931,0,0,0,0,0,0,0,0,747,943,0,1837,0,0,0,0,0,0,0,641, +0,0,0,0,280,0,0,0,5,0,0,0,0,0,72,545,0,0,0,0,0,0,0,0,0,742,0,0,254,151,872,0,0, +0,0,0,0,0,0,0,0,0,0,921,0,0,517,833,0,1680,0,0,436,251,584,0,0,0,0,0,0,0,0,0,0, +0,24,500,0,0,0,0,0,0,0,0,195,1775,514,389,0,0,0,0,0,0,0,743,0,0,0,0,0,0,292,0,0, +0,227,1283,774,1805,0,0,0,0,0,0,0,0,0,0,119,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,913, +1910,0,0,0,1826,490,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1162,700,30, +0,0,0,721,839,0,0,0,617,0,0,0,0,0,0,0,0,0,169,428,0,0,0,0,0,1648,637,1205,0,0,0, +1596,0,0,4,266,0,0,0,0,0,0,0,0,0,0,0,862,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0, +0,279,157,391,604,0,0,713,945,877,973,0,0,0,0,0,0,0,0,0,0,0,0,0,0,859,567,628, +1846,0,0,0,0,0,0,0,0,0,762,0,0,191,0,0,0,0,298,0,0,767,909,0,0,0,0,0,0,0,795,0, +0,301,0,0,1970,0,0,0,0,0,0,0,0,0,1236,0,0,0,0,0,0,644,369,15,0,160,71,0,0,0,0,0, +1447,0,0,0,0,0,0,0,0,735,1255,76,0,0,0,0,0,0,0,0,0,0,474,0,0,0,0,0,0,0,0,0,0, +841,0,0,0,0,0,0,0,0,0,0,836,0,0,0,0,0,1622,0,0,735,0,0,0,0,1601,804,1390,394,0, +0,0,0,0,0,96,0,289,0,0,35,688,0,0,0,667,0,513,0,0,0,0,0,0,0,2034,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,704,0,1524,0,1078,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,306, +0,0,0,0,0,0,0,431,0,1196,0,0,54,0,15,1448,0,1418,0,0,0,0,0,0,0,0,0,907,0,0,0,0, +0,0,194,1767,0,0,0,0,0,840,0,900,0,0,0,0,0,0,0,0,0,0,0,1436,0,0,0,0,642,1560,0, +0,0,0,0,0,94,386,0,0,0,0,0,0,0,0,0,0,830,416,0,0,20,731,0,0,0,0,0,0,0,0,697,0,0, +662,0,0,0,0,0,0,0,0,0,861,0,0,0,0,0,0,0,871,671,864,0,928,7,0,332,0,0,0,0,1055, +0,0,0,0,0,0,986,0,0,0,0,0,44,76,0,0,0,0,0,0,0,0,0,0,300,0,0,0,0,0,0,0,175,518, +831,1108,0,0,0,836,0,1852,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,843,1804,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,246,0,0,0,610,202,0,0,36,0,0,0,240,654,13,0,0,0,0,0,0,0, +0,391,0,403,0,0,0,0,0,0,0,0,0,0,75,0,366,815,0,0,631,0,0,0,0,0,0,0,0,345,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,952,0,0,0,0,0,0,0,0,0,0,0,673,35,662,0,287,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,5,34,0,0,0,0,0,0,0,0,151,0,427,0,0,382,0,0,0,329,0,0,279,0,0,0, +0,0,0,0,0,0,0,906,0,0,366,843,0,1443,0,1372,992,0,36,123,0,649,0,0,0,0,0,767,0, +1018,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,995,0,0,0,0,0,0,0,72,368,0,0,1345,0,0,0, +589,0,0,0,0,0,0,0,0,0,1988,0,0,220,541,0,0,0,686,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,32,196,0,0,0,0,0,0,0,0,0,0,0,0,0,381,0,0,0,0,0,0,0,0,0,1452,0, +0,0,616,0,0,0,0,0,0,0,0,0,1229,0,0,0,0,0,0,0,0,0,0,667,120,0,0,0,0,0,0,0,1146,0, +0,0,0,0,0,0,0,0,0,0,352,0,0,0,0,0,293,0,0,0,0,0,0,0,0,0,0,0,0,0,935,0,1050,0, +147,88,0,0,923,0,0,0,0,0,934,0,0,0,0,0,0,0,0,114,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,341,222,0,0,0,0,0,0,0,0,0,0,293,0,0,0,0,0,0,0,0,0,0,0,0, +637,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1159,0,0,0,847,0,0,0,0,0,0,683,0,867,944,0,0, +0,0,0,1809,0,0,0,0,0,0,0,0,0,0,395,170,0,0,0,0,0,0,0,0,0,0,618,535,0,1625,0,0,0, +0,0,0,0,0,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,778,0,0,0,0,0,46,0,2032,0,0,37, +1458,0,938,363,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,314,0,0,0,0,0,0,889,0,0,0,0,0,0,0, +0,0,0,0,462,0,0,0,0,525,0,0,23,0,0,0,0,0,0,0,0,0,0,0,676,0,0,0,0,0,0,0,0,0,0,0, +0,498,725,0,0,0,0,7,0,0,0,0,773,0,0,0,164,0,0,0,0,0,0,0,0,936,583,659,1462,0, +220,0,0,0,0,803,0,0,544,119,0,0,0,0,0,0,0,0,0,0,0,181,176,0,1192,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,1878,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,0,0,0,0,0,0, +944,0,0,0,0,0,0,0,273,0,0,0,0,0,855,0,0,0,0,5,127,0,0,0,0,0,0,0,0,752,230,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,162,0,654,48,156,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,240,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,197, +0,0,0,0,0,0,0,963,0,0,0,0,0,0,0,0,0,0,858,0,0,0,0,0,0,0,0,0,0,676,1978,0,0,102, +972,0,0,0,0,0,0,0,361,0,461,0,0,0,472,0,0,0,0,0,0,0,0,0,0,0,0,0,0,747,905,0,0,0, +155,0,0,0,0,0,0,0,0,0,0,319,163,0,0,0,0,0,0,0,0,0,848,0,0,36,631,0,0,0,0,0,1769, +0,0,0,0,0,144,0,0,0,0,0,0,0,0,0,0,369,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,555,247,0,0, +996,0,0,189,0,0,0,0,0,0,0,0,0,0,280,0,0,0,0,0,0,0,0,0,0,0,526,746,0,0,345,0,0,0, +1017,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,651,428,0,0,0,1162,230,327,546,792,0,0,0, +1203,0,0,0,0,0,0,0,0,0,672,189,0,0,0,0,0,0,99,0,0,0,298,0,0,0,0,0,0,555,397,0,0, +0,0,0,1157,0,0,0,0,0,0,0,0,0,0,398,1523,0,366,0,0,787,0,0,0,282,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,157,0,941,0,0,0,0,0,1336,0,0,116,0,0,0,0,0,0,787,0,0,0,0,0,0,0,0,0, +0,170,160,0,1815,0,0,0,0,0,866,0,0,0,0,0,0,0,0,0,689,0,0,0,0,820,0,498,108,0,0, +0,1119,0,0,0,244,609,1005,0,581,0,0,0,0,0,895,0,0,0,1898,0,0,0,0,0,926,0,0,0,0, +0,0,0,0,0,0,0,0,0,538,496,294,301,0,0,0,18,0,0,757,0,0,0,0,0,1263,0,820,0,722,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2028,0,0,0,0,124,1875,0,0,0,881,0,0,0,1348, +0,0,0,0,0,0,0,911,0,954,0,0,0,0,414,0,0,0,0,517,0,0,0,0,0,816,0,0,0,0,0,0,0,0, +713,0,0,0,0,0,0,0,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,593,150,0,0,0,0, +0,553,0,0,0,0,0,0,0,0,0,0,108,0,0,0,0,420,0,0,0,0,0,0,0,0,0,0,0,1777,0,0,55,493, +0,0,81,0,321,980,0,0,0,0,0,0,0,0,0,0,0,0,0,0,362,112,0,74,0,0,0,0,0,0,0,625,0,0, +0,0,0,0,377,16,0,0,61,281,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,1031,0,0,0,0,0,0,51,0, +0,0,0,0,0,0,211,309,15,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,789,173,0,439,9,648, +0,0,294,0,0,0,0,0,0,0,374,8,0,1099,0,0,0,0,0,0,0,575,0,0,0,518,0,0,0,702,0,0,0, +0,0,0,87,0,0,0,438,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,464,122,0,0,0,1802,0,0,0,0, +0,0,499,0,0,0,87,476,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,840,283,0,0,0,0,1620,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,609,1160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,600, +323,372,0,0,0,0,471,722,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0, +477,1304,0,1774,0,0,88,0,438,12,0,0,0,0,0,0,0,0,671,997,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,639,22,0,0,782,681,0,0,0,0,0,0,0,0,0,0,1013,664,0,942,0,1349,0,0,0,0,0,0,0, +0,0,0,0,0,356,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,215,289,0,1975, +109,450,0,0,0,0,0,0,0,0,0,0,705,0,0,664,0,0,0,0,0,0,0,1238,0,0,318,0,0,0,0,0,0, +0,0,0,0,0,0,0,960,1872,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,0,0,0,0,0,0,0,0,0,239, +777,0,26,0,0,0,0,0,0,0,0,0,0,0,0,375,414,0,17,0,0,0,1350,0,955,0,0,0,0,0,0,0,0, +887,960,0,0,0,0,0,0,0,0,0,0,708,710,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,919,0,0,0, +0,502,280,7,45,0,0,0,0,777,0,0,0,0,410,0,1110,0,0,0,0,0,0,414,341,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,787,0,0,0,436,0,0,0,0,0,0,0,1707,613,377,96,0,0,0,0,451, +0,0,0,0,0,0,0,0,0,0,0,0,0,680,0,483,916,0,0,0,0,0,0,937,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,739,0,0,0,0,0,0,0,0,82,0,0,663,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,128,0,0,0,0,0,0,0,0,1087,0,0,0,0,0,0,0,503,0,0,0,0,0,0,9,113,104,324,0,460,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,935,702,434,485,1014,949,423,0,900, +0,0,0,0,0,0,0,2018,574,0,0,0,0,0,0,0,0,0,0,0,0,1206,0,0,0,0,0,0,0,0,38,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1022,0,0,0,0,143,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2029,0,0,0,0,0,0,0,0,0,0,0,0,523,0,0,0,0,0,0,625,0,0,425,37,0,0,0,1943,0,0,0, +0,0,765,0,0,0,0,0,0,0,0,0,0,551,0,0,0,0,0,0,0,0,0,0,0,0,168,0,0,1010,0,0,1994,0, +0,0,91,0,0,0,0,532,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1884,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,240,15,0,0,0,1227,0,1534,0,0,0,0,0,0,0,0,0,0,0,0,0,0,392,0, +0,0,0,0,0,0,0,0,0,0,0,655,562,395,0,0,0,501,1019,0,0,0,0,509,267,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,1099,0,0,0,0,0,0,948,0,0,0,0,0,0,0, +462,114,0,0,258,404,0,1717,0,0,0,0,82,1061,0,724,0,0,0,0,0,1133,0,0,0,0,0,0, +1021,841,0,1021,0,0,0,0,0,0,0,0,0,0,488,373,37,0,0,0,0,564,0,0,0,0,0,513,0,0,0, +825,0,0,899,0,0,778,0,0,12,1417,0,1116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,114,545,0,5, +0,0,0,0,0,0,0,192,0,0,763,0,0,0,0,0,0,0,755,759,0,0,0,0,0,0,0,0,0,370,0,1237,0, +0,0,0,0,0,298,87,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,31,0,0, +0,0,0,0,814,991,0,757,57,0,0,0,0,0,0,0,0,0,540,0,0,0,0,608,0,0,0,0,0,0,0,0,1014, +0,0,0,902,0,0,0,0,553,1668,0,0,0,0,0,0,0,0,0,559,60,0,0,0,0,0,511,0,0,675,0,0, +156,0,0,0,0,0,0,709,0,698,0,0,0,1745,0,0,0,0,0,0,0,0,0,714,0,0,0,0,0,0,0,0,206, +8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,776,0,0,0,0,0,0,0,0,0,1272,0,0, +0,0,0,1059,0,0,0,0,0,0,406,0,0,0,0,0,0,0,0,0,0,947,0,0,0,0,0,0,168,0,0,0,0,0,0, +870,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,554,0,0,0,0,784,908,0,0,0,0,0,0, +0,396,358,0,0,0,0,0,0,0,0,2,228,0,0,0,0,0,0,0,0,0,0,0,845,14,0,716,1820,594,0, +81,1428,0,161,0,782,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,998,0, +0,0,0,0,0,0,0,0,0,0,0,1043,0,1496,0,0,0,0,0,0,0,0,781,0,0,0,0,0,0,0,817,1114,0, +1814,958,0,0,0,0,812,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,139,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,236,643,0,0,0,0,0,0,0,0,0,1172,0,0,0,0,0,0,0,0,0,1338,0,0,0, +0,0,0,0,0,0,0,0,54,0,0,0,256,0,0,351,0,955,1885,0,469,0,0,0,1270,0,744,0,313,0, +0,0,0,0,0,0,0,402,969,0,0,0,0,0,0,50,0,0,0,0,572,0,0,0,0,847,0,0,0,0,0,0,0,248, +43,0,369,0,0,0,0,0,0,0,0,0,0,0,0,0,766,0,363,0,0,0,0,0,0,0,0,0,0,0,678,0,0,409, +258,82,249,0,0,0,0,0,0,0,0,0,0,0,0,32,393,0,788,0,0,0,1281,509,1968,0,0,0,0,39, +291,0,0,0,589,0,0,54,1059,0,0,0,0,0,0,824,0,0,0,0,0,0,0,0,0,0,1005,0,1598,0,0,0, +0,0,919,0,0,0,0,0,0,0,0,52,132,0,0,0,0,0,328,0,0,0,0,173,0,0,0,0,0,65,1411,0,0, +0,0,0,0,0,0,0,0,442,0,842,0,0,0,0,0,0,0,0,0,534,0,0,0,0,0,0,0,0,0,0,0,0,0,845, +210,0,0,0,0,0,0,0,0,892,0,0,223,0,0,0,0,529,0,0,0,807,0,137,218,0,1444,0,0,0,0, +0,332,661,0,0,0,0,0,0,0,76,1517,0,0,0,0,0,0,0,0,0,0,0,418,0,0,0,0,0,0,0,0,481, +379,0,0,0,0,0,149,18,0,0,0,0,0,0,0,0,742,304,142,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,799,925,195,51,0,0,0,0,688,0,0,0,0,697,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1169,751,0,0,0,452,929,0,221,0,1437,0,0,0,0,955,1251,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,0,132,0,0,0,0,0,865,0,0,0,0,0,0,0,767, +672,42,0,0,0,1050,0,0,0,0,0,0,0,0,368,44,0,0,0,0,0,0,0,570,29,0,0,0,0,0,0,227,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,522,0,0,0,0,0,0,0,1529,0,0,0,0,0,0,739,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1667,0,0,0,0,0,0,132,511,0,138,208,1020,0,0,23,565,0,344,0,0,0, +0,0,922,0,0,0,0,0,0,0,240,0,0,415,171,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,402,0,0,754,31,716,0,982,731,0,0,0,0,0,0,0,888,0,0,0,803,847,0,0,823, +0,0,0,0,0,0,785,0,0,2,0,0,0,0,0,0,0,532,0,0,681,0,0,314,0,384,684,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,649,447,0,1818,1007,0,321,0,66,360,0,0,0,385,0,0,0,0,0,0, +0,900,73,254,0,0,0,0,683,1959,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,86,0,0,725,0,0,0,0,0,196,0,0,0,0,0,831,0,0,0,0,723,0,0,0,0,0,994,627,0,0, +0,0,0,0,0,0,0,0,764,66,0,0,0,0,205,36,0,0,0,0,0,0,0,950,0,0,0,887,111,0,0,831, +388,165,0,0,0,0,0,155,0,0,0,0,0,0,0,0,0,0,0,0,0,0,780,755,0,0,0,0,898,146,0,0,0, +0,0,0,0,45,7,0,0,0,0,0,0,0,0,607,0,0,0,0,0,0,65,0,0,0,0,0,0,0,0,0,88,0,0,0,0,0, +621,600,0,367,0,0,0,0,0,0,0,561,0,559,0,585,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +287,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,672,157,0,0,0,0,714,0,0,0, +0,0,456,0,925,0,0,0,0,0,0,0,0,19,0,0,0,0,1473,0,0,0,0,0,0,0,0,0,0,113,0,0,0,0,0, +0,0,0,0,0,0,0,0,69,463,0,0,82,193,2,471,0,0,0,0,633,0,0,0,0,0,0,1148,129,1392, +542,803,0,0,0,0,0,0,0,0,0,0,0,0,438,0,0,0,0,0,0,875,0,0,0,0,0,237,0,0,0,0,0,0,0, +65,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,563,0,0,0,9,444,0,0,43,1260,0,0,0,0,0,0, +971,0,0,699,0,0,0,0,0,1116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,829,242,0, +0,593,0,0,0,0,0,0,0,0,201,36,224,0,0,0,0,0,0,1430,0,1806,0,523,0,0,212,1889,0,0, +0,827,0,0,0,0,0,2043,136,242,0,0,0,0,0,0,284,148,10,0,0,0,0,0,0,1249,0,0,0,807, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,94,0,0,0,494,0,0,0,0,0,0,0,0,1510,0,0,0,0,0, +0,0,0,0,0,505,1306,0,0,764,268,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,384,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1703,0,0,0,0,159,964,583,0,0,0, +0,0,0,515,0,0,854,0,0,0,0,0,0,0,0,0,0,0,0,1123,0,0,0,0,0,0,0,136,0,0,0,0,0,1782, +0,0,44,1287,0,0,0,0,0,732,0,0,0,0,313,679,0,0,316,0,0,0,0,595,0,0,0,0,0,0,753, +147,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,137,0,0,0,0,414,0,1762,0,0,0,0,0,0,0,0, +0,0,0,599,0,0,0,0,0,0,0,0,0,1749,0,0,0,1627,0,488,0,0,0,0,0,83,0,0,0,0,676,0,0, +1639,0,0,0,0,0,0,0,0,0,278,0,0,0,0,0,0,97,0,14,1085,0,0,0,0,0,0,781,388,0,849, +59,229,0,0,0,0,0,1115,0,0,0,0,108,0,0,0,0,700,0,0,0,0,0,0,0,0,0,1414,0,0,0,0,0, +0,0,0,0,0,0,0,0,660,737,1035,0,0,0,0,0,0,521,690,0,0,0,0,0,0,0,0,0,0,0,0,272,0, +0,0,0,0,0,0,0,0,0,1744,0,0,0,0,0,0,128,733,0,0,277,0,0,0,0,0,0,0,0,0,4,0,0,0,0, +0,0,0,0,0,0,0,0,0,936,1981,40,0,0,0,0,0,0,0,0,775,0,0,0,0,0,0,0,0,0,306,0,0,0,0, +0,0,0,979,0,0,0,0,0,611,0,0,0,0,0,178,0,0,0,1969,0,0,0,0,0,0,0,664,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,390,0,0,0,1510,0,0,0,0,0,0,0,0,0,0,0,493,0,0,37,0,0,0,0,724,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,1537,0,0,168,473,0,0,0,105,0,0,0,0, +627,438,0,0,0,0,0,0,0,0,0,0,11,1256,0,0,0,1626,0,779,0,0,0,0,25,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,308,0,0,0,0,0,741,0,671,0,0,0,0,649,150,0,0,99,521,0,0,3,339,0,0,0, +543,0,0,0,0,0,0,0,0,0,1358,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,234,155, +0,0,0,0,0,0,0,1628,0,766,0,0,0,0,0,0,0,0,0,0,0,0,0,829,0,0,0,1445,0,0,0,486,0,0, +0,0,2,1635,0,0,0,0,558,0,0,0,0,0,0,0,0,0,0,1461,0,0,0,0,0,599,0,0,0,0,0,0,0,0,0, +1376,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,93,0,0,0,0,0,0,447,0,0,66,1432,0,0,0,0, +0,0,307,0,413,609,0,0,0,930,0,0,0,0,21,939,0,0,0,0,0,962,4,651,0,0,0,0,15,579,0, +0,0,0,0,597,0,0,0,0,0,981,0,0,0,545,0,0,0,0,0,0,0,1558,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,800,17,0,0,17,0,907,0,0,0,110,0,0,0,53,458,0,1983,0,0,0,0,0,0,0,0,0,0,443,0, +0,0,0,0,0,0,0,0,0,0,924,1844,0,1232,0,0,0,0,70,519,0,993,0,0,0,0,0,0,14,530,0, +907,0,0,0,0,0,733,0,0,0,0,0,0,0,0,55,0,188,531,56,0,0,1693,0,0,0,0,0,0,0,0,441, +0,192,928,0,0,0,0,0,241,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1525,0,259,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,512,185,0,464,1603,0,0,0,0,0,0,0,0,0,0,0,1113, +284,720,0,0,722,0,0,0,0,0,13,0,0,0,0,0,0,0,4,289,43,0,0,0,0,0,0,1694,0,0,0,0, +193,0,0,0,0,409,0,0,0,0,0,0,0,0,0,0,0,0,308,0,0,1863,0,0,0,0,0,0,0,0,0,790,0,0, +745,1002,0,0,0,0,0,0,0,0,0,289,68,477,13,0,0,0,0,0,0,0,0,0,0,609,0,0,0,0,0,0,0, +0,0,0,0,367,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,528,0,0,0,0,0,0,0,0,0,694,58, +548,0,0,0,0,0,0,687,0,0,0,0,1749,0,0,0,0,0,0,0,0,1004,661,0,0,0,0,0,0,445,0,0,0, +74,0,0,0,0,213,0,0,0,0,0,0,0,0,0,0,0,0,0,834,0,0,189,1672,0,0,0,0,0,0,0,1548, +192,0,0,0,0,0,0,0,0,0,0,0,0,0,32,751,0,78,0,0,0,0,0,0,544,1602,105,473,0,0,0,0, +0,0,156,1949,0,1779,0,0,0,0,0,0,0,0,0,0,0,763,0,0,0,0,0,0,0,0,29,0,0,0,0,0,0,0, +0,0,0,883,0,0,0,0,0,0,0,488,0,617,0,0,50,0,694,1518,785,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,546,0,0,0,0,0,0,0,0,0,0,22,0,0,0,0,1016,0,0,0,577,0,0,0,0,0,0, +184,935,114,720,0,0,100,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,95,14,0,969,0,0,0,0,0,0,0, +727,0,1021,0,0,0,0,0,1190,0,0,0,0,0,0,0,0,0,0,0,0,0,153,0,0,0,0,0,0,0,0,0,798,0, +587,0,0,695,42,0,1929,141,957,0,465,7,908,0,0,450,148,0,0,0,1166,0,0,0,0,0,0,0, +0,0,0,0,0,253,0,1003,0,0,0,0,0,0,0,0,0,0,0,46,0,0,879,0,806,0,1868,0,0,0,0,0, +1846,0,0,0,730,0,0,0,0,0,0,0,965,0,0,0,0,506,0,0,0,10,0,0,0,22,0,0,0,0,0,0,0,0, +0,0,0,0,0,960,296,0,0,0,0,0,0,0,0,0,0,0,587,0,0,0,0,20,0,0,0,32,982,0,0,0,0,0,0, +0,0,0,0,941,0,0,0,0,435,0,0,0,0,0,0,71,419,0,0,0,0,0,0,688,740,94,345,0,0,679, +582,0,0,0,0,0,0,0,945,0,0,0,0,0,0,0,0,0,0,0,0,539,0,684,1993,0,0,0,659,0,583,0, +803,0,704,0,0,0,0,0,198,181,347,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,481,405,203,0,0,99,826,0,0,0,0,0,0,0,492,0,408,0,0,0,0,0,0,0,0,0,0,4,0,0, +0,0,665,349,137,0,0,0,0,612,1270,0,0,0,0,0,371,0,0,0,826,0,0,0,0,21,1535,858, +374,0,0,0,0,0,0,311,0,0,0,991,1968,0,0,0,0,494,1647,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,769,0,0,0,0,0,642,0,0,157,123,0,0,0,1435,0,0,0,0,0,0,0,0,0,0,79,0,0,0, +0,0,0,1425,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,106,393,486,1690,0,0,0,0, +0,0,0,0,0,0,0,0,756,184,0,0,0,1382,0,0,0,175,0,1493,0,1007,0,0,0,0,0,0,0,0,0,0, +0,219,0,0,0,0,515,99,0,851,0,0,0,0,0,1278,0,0,0,0,0,0,0,1000,982,0,762,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,910,1819,0,0,0,0,0,0,906,0,0,0,0,0,0,0,0,0,0,1730,0,0, +0,0,0,0,0,0,0,0,0,1185,0,0,0,0,0,0,0,0,40,0,0,0,147,0,0,0,0,0,0,0,0,0,0,0,0,0, +650,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,30,0,553,0,0,20,597,0,1614,0,0,0,0,0,327, +49,0,0,0,0,0,0,0,78,0,0,786,134,0,0,0,12,496,0,0,0,0,0,0,0,0,0,0,42,204,0,614,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,147,247,0,0,0,0,942,0,0,2023,0,0,0,0, +0,0,67,285,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1309,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,0,0,0,0,0,0,41,532,0,0,0,0,0,0,0, +1692,0,0,0,0,55,1704,0,0,0,0,988,0,0,0,223,0,0,0,0,0,0,0,57,1123,0,0,0,0,0,1764, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2015,0,0,0,1599,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,129,0,0,0,0,0,0,0,0,0,0,0,534,0,0,0,0,0,0,0,0,0,0,0, +0,0,504,621,1248,321,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1397,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,441,75,0,0,0,0,0,0,0,0,0,0,841,0,0,0,0,0,693,0,650,314,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,913,0,0,0,0,0,0,0,0,0,0,0,0,0,0,880,0,475,0, +0,1016,179,602,111,329,0,0,0,1864,0,0,0,0,846,1888,0,0,780,0,0,0,82,0,0,0,0,821, +0,0,0,0,0,0,0,0,0,0,0,956,112,0,0,0,261,455,0,0,0,0,0,0,337,385,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,184,1865,0,0,721,16,0,486,0,0,0,265,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,0,0,0,621,0,0,0,0,0,0,0,0,234,0,0,815,0,0,743, +1987,205,197,0,0,0,0,0,0,0,0,0,314,0,0,0,0,0,0,0,0,0,0,0,0,0,0,219,452,589,0, +176,333,0,0,0,0,0,0,0,1110,47,0,0,0,0,0,0,0,0,0,0,0,864,0,0,300,0,1237,0,0,0,0, +0,0,0,0,0,0,0,1685,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,135,395,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,631,0,0,0,0,0,0,835,0,0,0,606,459,0,979,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,612,0,0,0,0,0,0,0,0,158,372,0,854,0,0,0,0,0, +0,0,1492,0,0,0,833,0,0,0,0,0,0,0,1739,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +195,0,0,0,0,0,0,0,0,730,1997,0,0,0,0,0,0,0,0,61,0,0,0,0,0,0,0,266,751,0,0,0,0,0, +0,0,821,0,0,0,715,0,0,0,868,0,959,0,0,0,0,0,0,0,0,0,0,0,1053,0,0,0,950,0,1081,0, +1595,0,0,0,0,59,0,0,0,0,0,0,0,0,0,0,47,684,0,0,0,0,0,0,1606,0,777,0,1020,0,0,0, +1094,0,0,0,0,0,0,0,350,0,0,0,0,0,0,242,1812,0,0,0,967,0,0,0,473,286,0,0,0,0,0,0, +798,629,222,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,513,337,306,0,0,0,0,0,0,0,0,0, +146,0,0,1646,0,0,0,0,0,465,0,0,0,525,0,0,0,0,0,0,299,165,0,0,0,0,0,0,0,1064,0,0, +0,0,0,596,0,0,0,0,0,0,0,0,0,0,0,0,0,0,238,1741,0,1233,451,1824,0,0,0,0,733,495, +0,0,0,0,0,1204,0,0,0,559,341,0,224,21,0,0,0,0,0,0,0,0,97,1446,0,0,0,0,0,0,0,729, +0,0,565,727,0,1948,0,0,0,519,0,0,0,0,0,0,0,0,0,1193,0,0,0,0,0,0,790,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,323,2,201,0,0,59,0,0,34,0,896,961,0,1285,0,0,46,0,479,0,0, +0,0,549,0,663,0,0,0,0,0,783,65,682,0,0,0,0,0,11,0,0,0,0,0,522,0,0,0,52,0,0,0,0, +0,383,0,0,0,0,0,0,0,0,127,0,0,0,0,0,397,194,0,0,635,0,0,0,0,0,0,0,0,0,0,975,0,0, +0,0,0,0,0,0,0,0,116,0,51,0,0,858,0,1075,535,448,0,0,0,0,0,610,0,0,0,0,0,0,0,0,0, +0,191,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,267,673,319,94,92,0,551,0,0,218, +1406,69,256,0,0,952,1980,0,833,0,0,0,0,0,0,0,0,0,0,0,0,39,0,0,0,0,0,0,0,81,0,0, +0,352,634,0,0,0,0,0,618,0,0,0,0,0,0,73,339,0,0,0,0,0,0,0,0,0,0,0,0,0,0,169,759, +0,0,0,0,0,0,0,0,0,0,0,0,0,1075,0,0,0,0,0,0,482,649,0,0,0,0,0,0,0,0,386,336,0,0, +0,1035,0,0,0,0,0,0,0,0,0,0,0,924,0,73,0,0,0,0,0,1971,0,0,0,0,0,0,0,0,0,1344,0, +501,0,0,0,0,0,0,0,0,46,799,0,0,0,0,0,0,0,276,0,0,0,0,0,0,0,770,0,0,0,0,0,0,0,0, +0,0,0,0,0,158,0,0,0,0,0,1432,0,0,0,0,0,0,0,0,0,0,25,0,0,2001,0,0,0,0,0,0,0,0,0, +0,0,0,0,478,0,0,0,0,0,0,91,1461,211,602,0,0,0,0,0,0,0,0,0,1068,0,0,124,567,0,0, +0,1006,0,0,0,0,0,0,0,0,0,735,812,0,0,323,0,0,0,304,0,0,0,0,0,0,0,0,0,148,0,0,0, +0,0,0,0,0,0,523,0,0,144,730,0,0,981,0,0,111,0,0,132,0,0,0,0,0,0,890,0,0,0,0,0, +444,0,1787,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,2041,932,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,937,0,995,0,0,255,0,0,138,863,965,0,0,631,0,0,0,0,1394,16,652,0,0,0,0,0,0, +0,0,0,0,0,0,0,897,0,321,0,0,0,0,0,922,0,619,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,844,0,0,0,0,0,0,1659,0,1100,0,0,0,1173,0,1930,268,251,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,390,711,0,0,0,0,0,0,0,0,0,0,0,0,0,744,0,0,0,0,0,0,0,0,0,624,0,0,0, +1998,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1125,0,0,0,594,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,268,0,0,0,0,0,0,0,563,0,0,0,0,0,0,0,0,2,39,0,0,0,1332,0,0,0,0,0, +0,0,508,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,796,0,0,0,0,527,0,0,0,0,98,0,0,576,0, +0,0,0,0,122,0,276,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,645,0,0,0,0, +0,0,0,0,0,0,0,290,0,0,762,1292,0,0,0,1315,0,1955,0,0,0,0,0,0,0,0,0,0,210,131,0, +0,0,0,797,0,38,0,11,488,0,936,0,441,0,0,0,0,0,595,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +991,0,0,0,0,0,0,0,0,0,0,0,653,0,523,0,0,0,903,0,0,0,0,0,0,0,0,0,0,0,0,80,0,0,0, +0,0,0,0,0,0,432,0,0,314,0,0,0,0,232,1368,534,0,0,0,0,0,27,0,0,0,12,0,0,0,0,0,0, +0,0,0,264,736,0,1657,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1117,0,127,0,0,0,1208,0,1294, +0,0,0,0,364,0,0,0,0,0,125,1334,0,0,0,0,0,0,0,0,0,0,0,0,0,0,792,0,0,0,0,0,0,0, +849,699,0,0,0,0,0,968,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,1446, +124,397,0,0,0,0,0,0,0,0,0,0,0,641,0,0,0,0,0,0,0,0,0,0,0,0,127,346,0,0,517,75,0, +0,0,0,0,0,0,0,83,0,0,0,0,0,0,1031,0,0,0,0,0,0,0,1470,0,954,0,0,345,304,410,0,0, +0,0,734,0,0,0,0,0,1822,0,0,0,1798,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,161, +1865,69,0,0,0,0,0,0,922,0,0,0,0,0,0,0,0,0,0,0,541,0,627,0,0,0,0,0,0,0,0,0,166,0, +0,0,0,0,0,0,0,0,849,0,0,0,0,0,0,0,717,0,0,0,0,0,0,0,0,0,0,0,0,0,0,600,0,0,0,0,0, +0,654,0,0,188,273,0,0,0,543,0,410,87,0,0,941,0,0,186,250,0,1785,0,0,0,0,0,1339, +462,961,0,780,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,0,0,0,0,0,0,474,1276,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,24,948,0,0,0,0,657,753,0,0,0,0,941,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,706,985,837,0,1861,0,0,0,0,0,0,0,0,0,0,0,0,0,0,292,933,0,0,0,0,0, +0,0,0,0,767,0,0,0,0,0,0,0,641,0,0,0,1233,114,0,883,0,274,2008,0,1794,285,0,0, +571,0,0,0,0,0,0,0,0,0,0,823,960,16,617,0,431,0,0,0,0,0,0,0,0,0,0,567,0,401,0,2, +781,424,33,0,2006,0,0,274,0,0,1882,0,794,0,0,0,1848,0,0,0,0,0,0,448,47,0,0,0, +1199,0,0,0,0,0,0,0,0,417,0,0,0,0,0,0,0,0,0,0,295,0,0,0,0,0,0,0,1019,0,0,0,0,0,0, +0,0,0,0,0,0,0,620,0,0,0,0,464,0,0,0,0,208,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,442,0,930,0,0,0,0,0,516,68,0,0,0,0,0,1128,104,0,0,0,0,0,0,0,0,787,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,491,0,0,0,0,0,0,711,0,0,9,0,101,441,0,0,0,0,0,0,0,0, +0,0,160,396,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,679,326,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,1128,0,0,0,0,0,737,0,1796,0,0,0,0,0,0,0,0,0,0,0,0,338,574,0,0, +0,0,0,1096,491,405,0,0,0,0,0,1081,0,0,0,0,0,0,0,0,0,0,0,0,0,1676,0,1207,0,0,0,0, +0,0,969,354,0,0,0,0,598,0,297,0,0,0,0,0,0,0,0,1772,751,0,37,0,0,1828,0,0,0,0,0, +0,0,0,0,257,191,582,0,0,0,0,0,0,790,0,0,0,0,0,47,0,0,0,0,0,0,0,449,306,1011,0,0, +0,0,0,299,0,0,0,0,0,0,837,0,0,0,0,0,0,10,329,0,0,0,0,0,1320,0,0,0,0,0,0,158,657, +0,1191,0,0,0,0,0,0,7,0,974,1939,0,1665,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,288, +66,0,0,0,0,494,175,0,1643,0,0,0,0,0,0,0,0,570,750,719,0,0,0,0,0,0,0,0,0,0,0,0,0, +13,0,0,1247,0,0,221,356,0,0,0,0,0,0,0,0,0,0,694,1809,0,0,0,0,0,0,0,411,0,44,31, +0,0,0,0,669,0,673,0,0,0,0,0,0,0,0,0,1303,704,299,0,0,0,275,0,0,216,1761,0,0,0,0, +0,0,0,0,0,0,0,1319,0,0,428,0,0,0,0,0,0,0,0,0,0,514,0,0,0,0,0,0,49,55,102,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,364,0,0,0,0,379,0,921,971,52,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1258,0,0,0,1058,0,0,0,0,0,656,0,0,0,0,0,144,0,0,0,0,0,0,0,0,0,0, +0,1373,10,605,0,0,0,0,0,0,0,838,0,1012,0,0,0,0,0,0,0,0,0,0,0,0,0,0,154,365,0,0, +0,0,0,0,0,0,0,340,0,0,0,0,0,810,0,0,0,0,0,0,495,0,0,0,0,0,0,0,0,0,261,0,535,248, +0,358,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,567,445,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,697,0,0,0,1336,0,0,0,0,0,0,0,0,917,174,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,972,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,351,0,0,0,0,0,0,0,0,0,0, +0,0,0,286,0,0,56,438,0,0,0,0,0,1950,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,738,0,0,0,0,0, +0,0,0,0,0,969,2047,0,0,0,0,0,0,0,818,0,0,0,0,0,0,0,866,0,0,0,0,0,0,0,1467,0,0,0, +0,0,0,0,0,0,0,0,0,0,972,0,355,0,0,0,116,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,267,189,104,0,0,0,0,1613,0,0,0,0,0,0,0,116,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,886,0,86,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,45,0,0,863,0,0,0,0,0, +0,0,1953,450,1773,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,381,0,0,0,0,0,0,0, +0,0,0,0,0,1142,0,1189,0,0,0,663,0,0,0,0,0,0,0,846,0,0,528,0,393,378,0,0,0,0,0,0, +325,899,680,1880,0,1770,0,0,0,0,0,648,0,0,0,0,0,0,185,167,0,2046,0,0,0,0,0,0, +249,1645,0,152,0,0,0,1733,0,0,0,0,0,1006,0,0,0,0,0,420,0,0,0,832,0,0,0,0,0,351, +0,0,0,0,6,40,0,0,60,0,0,0,0,1354,745,724,0,0,0,0,0,0,0,0,772,1951,275,108,639,0, +0,0,0,0,0,0,0,0,500,1758,0,0,0,0,0,0,0,0,0,0,0,1886,711,205,0,0,965,865,0,0,0, +534,0,0,0,0,691,0,0,0,237,443,0,878,0,0,0,0,0,1410,0,0,0,0,0,0,0,0,0,0,0,0,0, +995,0,0,0,0,0,0,0,0,0,0,0,0,0,578,0,0,0,0,881,0,0,0,0,0,0,0,0,822,0,923,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,924,0,0,0,665,0,0,0,0,0,1901,0,0,0,0,0,950,498,93, +0,0,0,1451,0,0,0,0,0,747,828,788,400,184,0,198,0,0,0,0,0,0,0,0,0,0,0,994,0,0,0, +0,0,0,0,0,615,320,0,0,0,978,843,905,0,0,0,0,0,0,0,0,850,974,0,0,0,0,6,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,509,0,0,0,0,0,273,0,0,0,0,0,0,0,0,0,0,0,0,0, +201,0,0,0,1041,0,0,0,1040,0,0,0,0,0,0,0,0,0,693,234,774,0,336,0,1399,22,0,805, +802,777,167,789,0,0,1705,0,0,0,0,0,0,0,0,0,0,0,10,13,11,0,0,204,264,0,0,56,0,0, +1917,0,470,0,0,0,0,0,0,0,0,0,0,0,1198,0,0,0,0,0,0,0,0,0,0,1015,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,715,0,0,1002,0,0,0,298,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,867,0,0,724,0,0,0,0,0,0,0,0,0,0,0,0,768,0,0,0,0,0,1066,0,0,0,0,67,0,174,948, +0,0,0,0,0,0,0,0,0,0,0,0,0,764,0,0,0,0,75,137,0,756,0,0,0,0,0,0,1008,842,643,0,0, +0,67,0,0,0,0,0,0,0,0,0,0,0,135,821,0,0,0,0,0,0,0,0,736,0,389,355,0,0,786,0,0,0, +0,0,0,2044,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1030,0,0,0,1083,0,0,0,0,0, +1226,0,0,0,0,356,319,8,389,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,474,0,0,0,427, +0,413,0,730,0,0,0,0,0,373,0,0,0,0,0,0,0,0,0,799,0,0,0,1793,0,0,0,322,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,89,290,2,0,0,0,0,0,0,0,0,0,0,672, +699,1860,0,0,0,737,0,0,0,1612,0,0,0,0,0,0,0,0,0,0,0,145,124,884,0,0,0,0,0,387,0, +0,0,0,0,0,0,0,0,0,0,679,0,550,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1305,0,0,0,0,0,0,0, +576,0,0,0,0,0,0,0,686,0,607,0,0,37,0,0,0,0,0,0,0,0,0,101,1726,0,0,0,0,0,958,0,0, +0,903,0,0,0,0,147,0,0,0,0,0,0,0,0,0,0,0,367,0,0,0,0,690,0,705,273,0,0,887,0,0,0, +0,0,0,0,0,0,0,0,90,0,0,0,0,0,0,0,908,0,0,0,0,0,0,0,1261,0,0,497,1235,0,429,0,0, +0,0,904,0,12,125,0,0,0,841,0,0,0,0,0,860,946,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,768,0,770,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,271,0,0,0,0,0,0,0,719,0,699,581,0,0,0,0,0,0,0,0,0,0,862,304,0,631,0,0,0,0,880, +1513,0,0,0,0,0,981,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,434,0,0,0,0,0,550,0,0,476,930, +824,553,0,0,452,0,151,0,0,0,0,0,0,772,0,292,135,0,0,0,0,0,0,0,504,0,0,1089,0,0, +0,0,0,0,0,0,0,0,0,783,0,0,0,0,0,0,206,393,0,0,0,0,0,0,0,0,232,912,0,0,0,0,0,977, +0,0,716,98,0,0,0,0,0,733,0,0,0,0,0,0,0,0,19,0,0,0,0,668,0,360,0,0,0,0,0,0,656,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,726,0,0,0,0,0,0,0,0,0,0,0,0,72,0,0,1269,0,0,463,0, +0,0,0,0,0,1454,0,1287,245,0,989,0,0,0,0,0,0,0,0,0,107,164,0,0,0,0,0,0,0,1061,0, +0,0,0,2,484,0,0,0,0,0,0,0,1127,0,0,0,0,0,0,0,460,0,0,0,0,0,932,0,0,0,0,0,0,0, +588,625,0,0,0,0,76,92,0,0,0,0,0,0,0,0,0,0,0,0,0,104,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +763,0,622,0,0,0,253,0,546,0,0,110,0,256,916,0,0,35,212,0,0,746,0,0,0,150,0,0, +1466,0,0,0,1299,0,0,0,0,0,0,0,0,0,1518,0,0,0,0,0,0,0,0,0,0,0,0,0,1229,0,0,0,816, +0,0,0,0,0,0,159,0,0,0,0,0,734,869,126,1716,0,0,0,0,0,0,202,232,0,0,0,0,212,0,0, +0,0,0,111,1003,0,0,0,0,0,0,0,0,0,0,0,1712,0,0,216,0,0,0,0,516,0,0,0,0,0,650,0,0, +0,0,57,99,0,0,0,0,300,574,0,0,0,0,1023,0,0,302,0,1871,0,728,252,0,0,461,0,0,0, +323,0,0,0,0,0,0,775,461,0,0,0,0,0,0,172,0,0,464,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,73,727,0,1023,0,0,0,0,0,0,0,0,0,0,577,0,0,0,0,0,0,0,0,1037,0,0,0,0,0,0, +0,0,280,677,0,0,0,0,0,0,0,0,0,0,0,799,0,0,0,0,159,0,446,1730,0,0,0,0,0,0,0,0,0, +395,0,0,0,0,145,0,0,0,0,0,0,0,20,0,0,426,608,0,0,0,0,0,977,0,250,0,0,0,0,0,100, +0,0,0,0,1982,0,0,0,0,0,476,0,0,0,0,0,0,594,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,447,0,0,0,0,526,0,0,14,1124,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,188,0,0,0,0,0,0,0,0,362,301,0,0,0,1743,0,178,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,0,872,0,831,0,0,208,202,0,0,0,0,0,0,0,1954,0, +0,0,0,516,872,0,0,313,224,0,0,24,0,11,546,0,0,0,1937,242,241,46,0,0,0,830,1273, +0,0,0,0,0,0,0,825,327,1006,0,0,0,0,0,1580,516,366,0,0,0,0,0,1736,0,0,0,0,0,0,0, +0,0,0,0,1935,0,826,0,0,0,0,139,331,0,0,0,0,0,0,0,0,0,0,0,288,0,916,0,0,0,0,0, +1888,0,0,0,0,0,0,0,1471,0,1570,0,394,0,0,0,0,0,0,0,1931,0,1719,0,658,228,0,0,0, +0,0,374,0,0,0,0,735,0,0,0,0,0,0,323,498,0,1063,0,0,0,0,155,0,0,0,0,0,0,0,0,906, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1139,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,108,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,0,0,616, +902,0,0,0,0,0,692,0,0,0,0,0,0,823,0,0,0,305,0,0,0,0,0,0,0,681,0,0,0,0,0,214, +1004,0,0,0,0,0,0,0,23,0,0,1703,0,0,0,0,0,0,0,0,0,1443,0,0,19,714,0,0,0,0,64,737, +0,0,345,1758,0,0,579,47,0,0,539,139,0,0,0,0,388,0,0,0,0,253,0,0,0,0,0,0,252,0, +745,0,0,0,0,0,0,0,0,0,0,0,504,107,0,871,0,0,0,229,0,0,0,0,0,903,0,0,71,0,0,549, +6,47,0,0,0,0,0,0,0,0,0,980,865,705,0,0,0,161,0,0,0,0,143,1331,0,0,0,1388,33,724, +0,0,0,19,0,0,0,395,0,0,0,0,0,846,210,0,0,0,122,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,695,937,497,0,0,0,0,0,718,0,0,0,0,0,0,0,1581,0, +0,0,0,0,0,161,49,0,0,0,0,0,0,0,0,0,597,0,0,0,1094,0,0,0,811,908,0,0,0,0,0,0,0,0, +0,0,1471,0,0,0,0,0,0,0,0,0,0,42,1935,0,0,0,2014,66,2007,0,0,586,0,0,0,0,0,0,0,0, +0,28,1077,0,0,0,1221,0,0,62,0,0,0,0,0,0,0,0,0,0,1766,0,0,0,0,0,0,0,0,0,0,0,0,25, +0,499,1388,0,0,97,10,0,0,0,0,0,481,0,0,0,0,0,0,0,0,0,0,37,134,155,486,0,1442,0, +0,0,0,0,591,0,0,0,0,0,0,310,1173,0,0,0,0,409,1156,0,0,0,482,0,0,263,926,0,0,0,0, +0,0,0,0,0,0,0,0,0,804,0,0,0,0,0,0,0,0,0,0,0,0,0,1265,0,415,0,348,0,0,0,1012,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,165,1803,0,0,0,0,0,0,0,408, +0,0,0,0,0,0,257,1321,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1138,0,0,0,249,0, +0,0,576,0,0,0,0,231,0,0,0,288,0,0,0,0,0,0,0,0,0,433,1487,569,1678,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,87,0,0,0,0,0,779,538,0,0,0,413,0,0,0, +0,0,0,0,0,0,0,495,0,0,0,0,0,191,54,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,530,567, +0,0,0,0,0,1484,0,0,0,0,0,0,815,609,0,0,0,0,0,484,0,0,0,0,0,0,0,0,0,0,900,0,0,0, +0,1335,0,1724,0,0,0,0,0,0,0,0,0,0,0,640,0,0,0,0,0,0,0,0,0,0,0,1831,0,0,0,0,0,0, +0,0,0,0,0,0,0,474,0,0,0,0,0,0,0,0,0,1103,0,1504,655,1034,0,0,0,0,0,305,0,0,0,0, +0,0,0,0,0,1236,0,0,429,217,0,0,0,0,739,278,0,0,0,0,0,0,0,708,0,0,0,0,0,1840,233, +0,0,0,0,0,0,0,0,2017,0,0,0,0,0,1488,0,0,0,1590,0,0,0,0,0,1800,28,0,0,0,0,0,0,0, +0,0,45,0,36,0,22,1442,378,0,0,0,0,0,0,1507,0,0,0,0,0,0,0,0,0,0,39,0,0,1054,725, +1955,0,2036,0,0,0,0,0,0,0,0,0,0,896,1871,0,0,0,0,0,0,0,0,0,0,805,0,0,0,0,2046,0, +0,0,0,17,712,0,617,55,320,271,0,0,0,0,0,0,0,0,0,445,0,184,103,0,0,0,0,0,0,0,0, +659,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,676,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +337,0,0,0,506,0,0,0,0,0,843,77,0,458,0,0,0,0,0,1420,382,109,142,330,0,0,0,0,0,0, +0,0,0,0,0,0,87,0,0,0,492,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1239,0,0,0,0,0,0, +211,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1049,0,321,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,1985,0,0,122,0,0,234,0,0,0,1098,0,0,0,0,0,0,549,253,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,522,131,0,0,149,0,0,0,0,0,0,0,0,0,0,0,0,0,0,507,0,0,0,0,811,630,0,0,0,343, +0,0,0,0,0,448,591,455,0,1381,0,0,0,0,0,0,0,575,0,0,0,0,0,1175,0,0,0,0,0,0,0,0,0, +653,0,0,0,1761,0,1198,0,0,0,0,297,1127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,678,0,0, +164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35,0,45,0,0,0,0,0,121,0,0,0,0,0,0, +0,0,125,0,0,0,1622,0,0,0,0,0,721,145,0,0,0,970,792,0,0,0,715,0,0,0,0,0,1999,0,0, +74,531,0,0,65,0,0,0,105,220,0,0,0,0,0,0,0,960,0,0,0,0,0,0,428,19,0,0,401,96,0,0, +0,0,0,1595,116,0,1021,0,0,0,0,0,750,1961,0,0,148,0,0,0,0,0,0,0,0,0,0,0,0,0,75,0, +0,1383,0,0,0,0,0,0,0,0,0,0,0,0,0,0,779,0,0,0,0,0,0,0,0,598,0,424,0,0,0,0,0,0,0, +1222,0,0,0,876,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,133,0,0,0,0,187,0,8,0,0,0,0,0, +0,0,429,0,685,0,0,0,0,0,0,0,0,0,0,0,132,472,0,0,0,0,0,0,0,0,0,938,0,0,874,0,0,0, +0,0,774,0,0,0,0,0,92,0,0,0,0,0,0,830,701,0,0,0,0,0,426,350,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,603,59,0,0,0,0,0,0,0,0,0,0,293,0,0,0,0,0,0,0,0,0,0,0,0,0,0,441,163,4,0, +0,0,0,0,0,0,0,0,806,0,0,0,0,0,0,233,0,0,0,0,1994,0,1739,0,0,393,0,47,1038,0,0,0, +309,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,363,0,0,0,175,0,0,0,0,0,0,0,666, +0,0,1675,0,1600,0,0,0,808,0,0,0,0,0,0,0,0,0,0,0,280,54,0,0,0,0,0,0,0,0,421,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,249,0,0,103,254,0,262,1,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,805,0,0,0,0,0,0,0,0,0,1630,0,0,0,0,0,0,0,0,0,0,0,0,0,671,972,989,0,0, +0,0,0,0,0,889,0,0,0,1382,0,0,0,0,0,0,0,775,0,0,0,0,0,0,0,0,0,0,388,202,0,0,0,0, +16,560,0,0,0,841,0,0,566,0,0,0,938,0,0,0,0,0,0,0,0,0,0,912,0,0,0,1361,0,0,0,0,0, +0,618,236,0,1854,0,0,318,190,0,1376,0,0,0,0,0,0,0,349,0,0,0,0,951,1972,0,0,0,0, +0,0,344,0,0,0,0,0,0,0,0,850,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,910,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,163,85,0,487,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,145,0,83,0,0,1013,0,0,0,1922,0,0,169,557,66,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,1193,82,0,352,454,57,0,0,1333,396,107,0,370,0,0,0,0,0,0,0,0,0,204,0,0,0, +0,0,1706,0,0,0,0,0,0,0,0,0,0,0,0,394,1204,0,0,0,0,0,1007,0,0,0,1696,0,1519,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,981,0,0,0,0,1072,0,0,0,712,0,1629,0,0,0,0,0,0,0,728,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1271,0,0,0,1608,16,0,0,0,0,485,0,0,0,0,0,0, +153,27,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1991,0,0,0,0,0,0,0,0,52,0,21,0, +0,0,0,0,0,0,0,0,819,0,0,0,0,0,917,0,0,0,0,784,0,0,0,0,135,0,0,0,0,0,454,0,0,0,0, +0,0,0,0,0,852,1719,0,0,0,0,0,852,0,0,0,0,0,952,0,0,0,0,568,0,0,0,0,0,448,0,0,0, +67,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1826,657,0,729,666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +669,0,0,0,0,0,0,0,402,0,0,152,0,0,0,0,912,0,0,0,0,0,0,51,320,0,445,0,0,0,0,308, +0,0,0,0,0,386,0,0,239,0,0,130,83,0,143,0,348,0,0,0,0,0,0,0,958,0,0,0,0,0,210,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,430,0,0,0,0,0,0,0,0,0,0,0,0,7,213,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,801,0,0,0,0,0,0,0,0,0,936,0,108,0,0, +0,0,0,0,0,0,0,885,587,219,398,364,0,1165,0,0,342,241,303,0,0,0,0,0,0,0,0,0,0, +1454,0,0,0,0,0,0,0,0,0,0,254,562,0,786,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1294,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,493,216,0,0,0,0,219,341,0,0,0,0,0, +0,0,0,0,0,130,1734,154,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,701,604,0,0,879,0,195, +666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1669,0,0,0,1791,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1228,0,0,0,0,0,623,0,0,0,0,0,0,0,798,0,0,0,0,0,0,0,0,0,0,0,0,84, +122,0,0,0,837,0,0,0,0,0,0,1013,0,0,577,0,0,0,460,932,0,0,0,0,0,0,0,0,0,0,0,31, +131,0,0,0,605,0,0,0,1246,0,0,0,0,68,278,165,307,781,0,0,0,0,0,0,33,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,1113,0,0,720,1953,203,0,0,0,0,0,0,0,425,326,0,0,0,0,0, +0,0,0,0,0,241,1316,0,0,0,0,0,416,0,0,0,1300,0,847,0,0,662,358,0,0,0,0,839,1823, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,654,1522,0,0,0,0,0,0,163,0,0,0,0,0,314,978,0,0,0, +601,0,0,0,0,0,946,434,0,0,0,402,411,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,1467, +410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,483,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,677,0,0,0,0,0,0,0,0,0,0,0,0,70,0,0,0,0,1405,0,0,0,0,0,0,108,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,777,0,0,0,0,0,747,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,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,505,0,326,0,0,164,628,654,0,0,0, +37,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,668,152,0,0,0,0,0,0,0,0,0,0,0,581, +0,0,0,0,44,126,89,0,0,0,0,0,0,0,0,1531,0,0,0,0,0,0,0,0,203,1167,0,0,0,0,0,0,0,0, +531,1232,0,0,0,0,0,943,0,670,231,880,0,1617,0,0,0,1957,0,0,0,0,0,0,0,975,0,0,0, +0,0,0,0,0,0,0,0,242,0,0,0,0,0,0,0,0,0,421,0,0,14,834,0,0,0,0,0,0,0,0,0,0,0,0, +465,0,0,0,0,0,834,688,413,855,0,0,0,590,0,0,0,0,0,0,0,0,114,0,0,0,0,0,0,0,0,0,0, +0,45,169,0,0,0,0,0,0,0,0,0,0,0,198,0,0,565,585,0,0,0,0,0,0,0,0,0,0,0,0,0,691,0, +0,0,593,0,0,0,0,0,0,0,0,0,913,116,0,0,0,0,1360,0,0,0,802,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,673,308,0,709,1006,1895,0,228,0,0,0,1840,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,608,0,0,0,0,0,0,0,0,0,1573,0,2039,136,540,0,0,0,0,0,0,0, +897,0,0,938,1878,0,0,0,0,0,0,0,0,0,1469,0,999,0,299,0,0,0,0,0,0,0,578,0,0,0,0,0, +456,0,0,0,1679,163,693,0,0,0,0,0,0,48,755,0,0,0,0,0,0,0,0,0,0,0,0,338,0,0,0,0, +1091,0,0,0,0,695,0,0,1464,0,0,0,0,0,975,0,0,335,0,0,1979,0,0,0,0,269,1566,630, +396,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1815,634,0,0,0,966,0,0,0,0,0,0,0,9, +412,0,958,0,0,579,382,0,212,0,0,0,0,965,681,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,655, +0,0,0,0,67,0,0,0,0,0,0,751,0,0,0,0,423,231,0,0,1016,300,0,0,0,0,100,237,0,0,0, +1370,0,0,0,1208,0,0,0,0,0,1219,129,0,0,0,0,0,0,0,0,0,0,0,0,0,0,199,0,0,427,0,0, +0,0,949,665,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,0,0, +0,0,712,0,0,0,0,0,1186,0,0,0,0,0,0,0,0,0,0,295,312,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +151,0,0,0,0,588,4,0,0,0,0,0,414,104,0,0,757,263,0,561,0,0,0,320,0,0,0,0,0,0,0,0, +0,0,0,225,0,0,0,0,37,817,0,974,0,0,0,0,0,0,0,0,0,0,0,0,0,2026,131,235,16,0,590, +1157,0,0,0,0,0,0,0,0,221,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,140,390,0,0,0,0, +0,0,0,1144,0,0,0,464,0,0,0,0,0,0,0,0,0,0,0,0,204,407,303,1218,0,0,0,0,5,325,0,0, +0,0,12,800,0,1783,0,0,0,0,0,0,0,0,0,0,504,621,0,0,0,0,0,0,0,0,0,920,0,376,0,0,0, +0,0,218,580,0,768,454,0,0,0,0,0,0,0,0,0,0,0,0,676,0,0,0,0,0,0,164,0,0,0,0,0,0,0, +0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,120,285,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,226,343, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,29,0,0,1812,0,0,8,0,0,0,21,1125,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,1327,0,0,0,0,575,1598,0,0,0,0,0,0,0,0,0,895,0,0,0,959,0,0, +0,0,0,1759,173,0,0,0,0,266,261,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,0,0,1427,0,0,300,1033,0,0,0,0,0,0,0,0,0,0,0,584,0,0,0,0,52,734, +0,0,217,239,0,1129,0,0,0,0,0,0,0,0,732,20,0,0,0,0,0,0,0,0,0,0,0,418,0,0,0,613,0, +0,0,0,0,0,0,0,0,632,0,0,85,984,0,0,0,0,909,694,7,1109,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,167,0,0,0,0,280,62,0,0,33,0,0,359,186,980,0,0,0,0,0,0,0,0,0,0,0,585,0,0,0, +211,0,0,336,145,0,1130,0,873,0,0,840,263,0,0,0,0,0,0,0,0,0,916,0,0,0,0,0,0,0,0, +0,0,155,0,0,0,461,97,0,0,0,0,0,1356,0,0,0,0,0,0,0,593,0,0,0,0,0,1392,0,0,0,0, +126,0,0,0,0,1179,0,0,0,0,0,162,0,0,0,0,0,765,0,187,0,1286,0,0,0,0,0,0,0,0,0,635, +0,0,23,215,0,0,0,1306,0,0,97,716,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,657,0, +0,0,0,0,0,0,0,299,0,0,0,0,0,0,134,0,0,0,0,0,0,0,0,0,0,0,658,1082,0,0,0,0,0,2002, +0,0,0,0,0,0,833,248,0,0,0,0,0,1654,0,0,531,0,0,0,0,0,0,634,0,0,0,0,0,0,0,0,0, +853,573,249,0,0,0,0,0,0,0,0,527,0,0,0,0,1419,0,0,0,0,0,0,20,49,0,0,0,992,0,0,0, +728,0,0,0,0,0,0,0,0,0,0,0,0,497,1579,0,0,0,0,62,268,0,0,0,0,0,0,0,1201,0,0,0,0, +0,0,0,0,0,0,0,0,495,193,0,0,0,0,106,0,0,859,0,0,23,0,0,0,0,0,0,0,813,925,0,0, +223,613,953,0,0,0,0,0,0,0,0,666,0,0,0,0,0,0,0,0,0,670,0,0,40,216,0,0,0,0,0,0, +259,0,0,0,440,1114,0,0,0,0,0,0,0,0,74,475,0,0,188,139,0,797,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,1572,0,0,0,0,39,0,0,0,0,0,0,0,0,0,0,0,0,1594,0,0,0,0,0,0,0,290,0,232, +0,0,887,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,521,14,0,0,0,0,0,741,0,0,0,992,0, +0,0,0,0,0,0,0,111,0,0,425,0,0,0,0,0,789,0,0,0,1593,0,1768,0,0,233,0,0,0,0,943,0, +0,0,0,0,0,0,955,225,245,0,0,0,0,0,0,241,0,0,0,0,1943,0,0,0,1284,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,709,0,0,0,0,0,0,554,0,0,0,0,0,0,0,0,1564,0,0,0, +443,0,0,0,0,0,0,280,0,0,0,0,0,0,0,0,729,0,0,0,348,0,0,0,0,0,0,0,758,848,298,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,829,1422,189,121,0,0,632,812,0,0,556,0,0,0,0,0,436,172, +530,844,232,984,0,0,0,0,0,0,0,0,0,0,147,0,0,0,0,0,0,0,0,537,0,0,0,0,0,859,0,0, +842,0,0,0,0,0,0,0,0,0,0,1291,0,0,0,0,0,0,0,0,0,0,0,1482,612,392,0,0,0,262,31,0, +0,0,0,0,0,0,0,0,0,753,549,0,0,0,0,0,0,696,0,0,0,0,0,0,0,834,0,0,0,0,0,771,0,0,0, +0,0,0,0,0,0,0,0,0,0,921,0,0,0,674,0,0,0,0,0,0,0,0,0,0,308,444,0,0,0,0,0,0,805, +180,0,0,278,271,0,0,214,505,0,1215,0,0,0,0,0,0,387,271,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,1645,42,92,0,459,0,0,330,1557,0,0,0,0,0,0,0,0,113,18,0,0,0, +1742,0,0,0,965,0,0,0,0,0,0,0,0,0,0,0,0,0,182,0,0,65,0,0,0,0,0,0,0,0,0,0,0,0,973, +0,0,0,0,0,328,0,0,588,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,1786, +0,0,962,1985,0,0,0,308,508,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,588,0,0,0,0,0,0,614,793,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,290,0,0,0,0,0,0,0,0,0,0,1136,0,0,0,0,0,0,0,0,0,0,796,719,0,0, +326,210,0,0,0,701,758,472,0,0,0,1947,278,1079,0,0,0,0,0,0,497,41,0,0,634,46,961, +0,810,524,0,0,33,0,0,0,0,0,0,0,0,0,0,0,0,532,0,997,0,0,0,0,0,0,0,0,0,0,0,1301,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1298,0,671,0,0,0,306,0,0,0,0,0,0,0,0,0,0, +693,1823,0,0,0,759,0,0,0,0,0,1932,0,0,0,0,0,0,0,0,0,0,0,0,0,0,88,182,0,0,0,1964, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,521,0,0,0,0,0,0,424,857,0,0,0,0,671,328,0, +529,0,0,0,0,0,716,0,1509,80,67,0,0,0,0,59,141,0,0,0,0,0,0,783,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,1498,0,0,0,0,343,430,803,1183,677, 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,0,0,0,0,0,0,0,0, -0,19817,0,5579,9350,0,0,21002,19718,0,0,0,21926,0,0,0,0,0,0,0,0,0,0,0,0,0,20711, -0,0,0,20197,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,40550,0,0,0,57510,0,0,0,53895, -0,0,15017,0,17000,39367,2347,0,0,0,0,0,0,0,0,0,8588,0,0,0,0,0,3273,17862,3498, -2085,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19048,0,0,0,0,0,11978,58631,0,0,0,0 -,0,0,523,0,12969,198,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28197,0,47846,0,0,0,0,0,0 -,0,0,0,4549,0,0,0,0,0,0,0,0,0,0,687,14917,748,8229,0,0,0,0,0,0,2476,12935,0,0,0, -0,0,0,22792,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27528,59142,0,0,20876,20134,0,0,0, -0,440,12068,0,58951,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48038,0,0,0,60999,0,0,0,0, -0,0,0,0,0,0,0,0,0,15716,7498,5476,0,0,0,0,20202,37959,0,0,0,0,0,0,0,0,0,0,0,0, -29801,0,5451,0,0,0,0,0,0,0,0,0,0,50790,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24485,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13573,0,0,22856,0,0,0,0,21927,0,0,0,0,0 -,0,9130,0,0,0,0,0,0,13732,0,0,0,0,0,0,0,0,0,0,2282,583,0,0,0,0,0,0,0,0,0,0,3726, -26503,0,0,0,0,0,0,9258,0,0,0,0,0,0,0,0,21604,0,0,0,45574,0,0,0,0,0,20710,0,0,0, -42694,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1163,6694,0,0,0,0,0,0,0,10948,0,0,0,29700,0,0, -0,0,0,58823,3796,27399,20939,10180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -19,29287,28649,14534,0,0,16428,45607,0,0,0,0,0,0,25322,0,4908,0,0,0,0,0,0,25476, -29097,14246,11053,0,0,0,0,0,0,0,0,18502,0,0,0,44390,0,0,0,17765,0,0,0,0,0,0, -24520,0,0,0,0,0,0,0,0,0,0,17319,0,0,0,0,0,0,0,0,0,0,0,0,0,28166,0,0,0,0,0,48198, -0,0,31467,0,24585,0,0,0,0,18692,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23596,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,7236,968,13637,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -3763,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14791,0,0,0,12324,0,12741,0,0,0 -,0,0,0,0,0,0,11108,0,0,0,0,4009,40295,20616,4357,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -15015,0,0,0,0,0,43751,0,0,0,0,0,0,0,0,0,0,0,23013,0,0,0,0,0,0,0,0,0,0,0,0,0, -45542,0,0,0,0,0,0,0,0,0,23974,0,0,0,0,17480,20647,0,0,0,0,0,0,8876,0,0,40806,0,0 -,0,0,0,0,0,14502,17160,17764,0,0,31594,35431,0,0,2890,0,0,0,0,0,0,0,0,27524,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8228,0,56583,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,34278,0,0,0,0,0,0,0,0,0,0,0,0,0,2662,0,26724,0,0,0,0,0,0,0,64198,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22281,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3049, -54983,0,0,0,0,0,0,0,837,0,17604,0,0,0,0,0,28838,0,0,0,0,0,0,26312,0,0,3910,0,0,0 -,25830,0,0,0,0,0,8391,0,19845,19240,1092,0,0,5449,0,0,0,0,17188,0,0,0,0,0,0,0,0, -0,10629,0,0,6671,61094,5832,8358,0,0,0,55078,0,0,0,0,0,29860,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,0,0,0,51494,0,28647,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25989,0,0,30153,61318 -,0,0,0,0,0,0,0,24903,0,0,0,4388,0,42054,0,0,0,0,0,0,0,53158,0,0,0,0,0,0,0,50918, -0,0,0,0,0,0,26251,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5929,2853,0,37126, -7372,197,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2027,934,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,55686,0,0,5672,5447,0,62758,0,0,0,0,0,0,0,0,0,0,0,0,2923,0,556,1415, -0,0,0,0,0,0,0,0,0,8645,0,9477,0,0,0,0,0,0,0,48742,0,0,0,0,0,0,0,0,0,0,24235,228, -0,0,0,0,0,0,0,0,0,0,16970,18823,0,0,0,0,0,0,0,0,0,25158,0,0,0,0,0,18567,20072, -2823,14313,1830,0,0,0,0,0,0,0,0,27048,23526,0,0,0,0,0,997,492,0,14730,16677,396, -13574,0,0,0,41671,0,0,0,0,0,0,0,19045,0,0,0,421,17545,3110,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,47111,14475,56551,0,0,0,0,0,0,0,0,0,0,3697,0,0,0,0,0,0,49382,0,35559,0, -0,0,0,40,0,11496,15621,0,8550,0,0,0,63462,0,0,0,0,0,0,0,36966,0,50406,0,46022, -1001,0,0,12069,3249,0,0,0,0,0,0,0,0,0,0,0,0,0,15241,0,0,0,0,0,0,0,0,64743,0,0,0, -0,0,58759,0,0,0,0,1136,26981,0,0,0,0,0,0,0,17732,0,0,0,17157,20011,6629,0,43879, -0,0,0,13572,25128,10759,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28676,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,875,24007,0,0,0,0,7628,0,0,0,0,0,12268,0,0,0,0,0,0,0,0,19300 -,23210,356,0,0,0,0,0,0,0,0,0,15236,0,0,0,0,0,49670,0,0,0,0,0,0,0,21764,0,0,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,13931,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,45799,0,0,436,3589, -0,0,11402,0,0,0,0,0,0,0,0,0,0,62822,0,0,0,39814,588,0,0,0,0,0,0,27750,0,0,0,0,0, -0,1609,22660,2346,18951,0,16068,0,0,0,0,0,0,5162,11110,0,0,0,0,15048,1060,0,7879 -,18280,326,0,14886,19656,0,7594,0,0,0,0,0,781,581,0,16198,0,0,0,0,0,0,1078,9892, -0,0,0,0,0,0,0,0,0,0,4489,0,0,0,0,33798,0,0,0,54534,0,0,0,0,0,0,0,33158,0,0,0,0,0 -,0,0,0,0,42086,13834,2757,8456,16773,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3434,0,0,0, -0,0,3946,29668,0,0,30634,36775,0,0,0,0,0,24901,0,16069,6280,0,0,0,0,41990,0,0,0, -0,0,0,0,27365,0,0,0,0,0,0,0,0,0,0,1450,44807,0,0,0,32100,0,0,0,0,0,35110,0,0,0,0 -,0,0,0,0,17448,19591,0,0,0,0,0,0,0,0,0,0,0,0,1739,0,0,0,0,5511,0,0,0,32934,0,0,0 -,0,0,0,0,0,0,18180,0,0,0,23428,19754,0,0,31174,3021,31655,23464,0,0,0,0,0,0, -57255,0,0,21292,64487,0,0,0,0,0,0,25802,9189,0,0,0,0,0,49254,0,0,0,0,0,0,0,0,0,0 -,5837,50023,0,0,0,0,0,0,0,0,0,15495,0,0,0,0,0,51942,0,0,0,0,0,0,0,0,28104,58662, -0,50214,0,0,0,0,0,0,0,0,2988,0,22888,31812,0,0,0,0,0,2020,0,18916,0,0,0,0,0,0,0, -23973,0,0,0,0,17516,11717,0,0,0,55911,0,0,0,0,0,0,0,2855,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,0,46822,0,24710,28586,0,0,0,1556,0,0,30117,0,0,22090,57127,3403,14087,0 -,0,0,0,0,0,0,0,0,0,1041,0,10633,6916,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,0,0,0,0,0,0,0,27269,0,0,13322,18055,0,29380,0,56454,0,0,120 -,0,0,8773,0,0,0,0,16040,0,0,0,0,0,0,0,27242,23781,0,1572,0,28134,0,0,1512,0,0,0, -0,0,0,27684,0,38470,0,0,0,0,0,0,1513,8709,0,0,0,0,0,0,0,0,0,0,0,46566,0,0,0,0, -28521,61159,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24356,0,0,0,0,0,0,0,0,0,13028,0, -5863,0,0,15693,0,0,0,0,0,0,0,1131,23398,0,0,0,0,0,0,0,26212,0,0,0,0,0,0,0,0,0,0, -0,0,0,18404,0,0,0,0,1457,26183,0,0,2475,7110,0,0,0,0,27180,60166,0,0,0,20262,0, -41862,0,0,0,0,0,0,0,0,0,0,2762,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26148,0,0,0,0,0,0,0,0 -,0,28229,0,0,0,29254,0,0,0,0,0,0,0,0,0,0,27690,0,0,13636,12776,1862,0,0,0,0,0,0, -17225,3271,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28039,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -,0,0,0,0,0,0,0,0,0,4457,18117,0,2023,402,0,0,0,0,0,0,0,0,0,0,0,0,0,104,3654,0,0, -0,0,0,0,0,0,18440,0,0,0,0,0,0,0,0,29861,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,22150,0,0,0,0,0,0,0,0,0,0,0,0,24074,0,0,0,0,0,0,0,0,12004,0,32358, -0,0,3081,0,0,0,0,0,0,0,0,0,4749,0,0,0,0,0,0,0,0,0,0,0,10792,1799,21322,0,7880, -12613,0,0,0,0,0,0,0,0,13993,0,0,0,16202,0,0,0,0,32102,0,37223,0,10500,0,0,0,0,0, -0,0,0,32008,0,0,0,0,0,23816,3236,0,0,0,0,0,23237,0,0,5642,0,4684,294,0,0,0,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,0,0,26852,0,0,0,0,0,0,7148,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,7890,61798,939,0,0,56679,0,0,0,0,0,27078,202,5029,0,0,0,0,0, -0,0,0,0,28005,0,0,15273,24741,5676,20452,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,55910,0,0 -,0,0,5069,27942,0,21092,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12517,0,0,0,0,0,0, -0,0,0,0,0,0,21384,28260,0,2502,20108,0,0,0,0,0,0,0,0,0,0,0,0,46726,0,30790,0,0,0 -,0,0,14725,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1099,6372,0,0,0,12422,15182,0,8683,0, -10665,19462,0,0,0,0,0,0,1590,0,31628,0,22632,19750,0,0,0,0,0,0,0,24198,0,0,0,0,0 -,50662,0,0,0,0,0,0,0,0,0,0,9131,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11015,0,0,0,0,0,0,0, -0,16490,54695,0,0,0,0,0,0,0,0,12937,0,0,0,0,16004,0,0,0,0,0,0,0,0,0,2181,6923,0, -0,0,0,0,0,0,15624,11302,0,0,5673,7559,0,0,14668,15684,0,0,0,0,0,0,24204,48134,0, -24230,0,55527,0,0,3464,19141,0,0,0,0}; +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1357,53,0,0,0,0,590,0,0,0,0,0,0,0,0,0,0, +0,0,0,329,0,0,0,0,0,0,0,469,0,0,0,0,0,0,0,0,0,0,460,0,0,1743,0,0,963,340,0,0,0, +0,0,1603,0,0,250,0,0,0,0,0,646,218,0,1794,0,0,0,571,0,455,0,0,0,1012,0,0,0,0,0, +0,0,0,0,0,0,0,597,161,0,349,0,524,0,0,0,0,0,0,0,0,0,0,0,0,322,432,0,0,0,0,0,0, +325,223,0,0,0,0,0,566,0,0,0,1394,481,436,0,48,457,610,756,618,0,0,0,755,0,1217, +0,0,0,0,0,197,0,0,0,0,0,0,0,0,0,0,0,0,0,0,544,492,107,414,0,0,0,0,0,0,0,0,0,0,0, +1007,0,0,0,0,5,0,0,1580,0,0,0,0,0,0,0,0,0,0,0,0,0,673,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1843,0,0,0,0,0,0,0,0,0,165,0,0,0,0,0,0,809,885,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,498,0,0,0,306,9,0,0,0,0,0,0,0,437,721,146,0,0,0,0,0,0,0,0,0,0,0,177,0,0,0,0, +0,0,0,1377,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,200,0,959,0,0,0,1928,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1435,0,481,0,0,0,0,0,0,142,84,0,0,0,0,0, +1015,0,0,0,315,0,0,0,0,0,0,759,0,0,0,0,0,0,0,0,712,0,0,0,1722,0,0,0,0,0,0,0,0,0, +0,0,0,222,0,985,1414,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,1273, +538,706,0,0,0,0,0,0,0,0,115,0,0,0,0,0,0,0,0,0,0,1781,0,0,0,0,0,431,97,665,42, +237,0,0,0,264,0,0,213,0,0,0,0,0,0,0,455,0,0,0,906,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +624,0,574,0,0,0,0,0,0,0,0,0,0,0,0,354,0,0,0,1558,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68, +235,723,1813,0,0,0,957,0,830,0,0,0,0,0,0,0,0,0,0,0,0,23,0,0,496,0,0,0,0,0,0,0, +547,239,88,0,0,0,0,0,0,0,0,0,1310,0,0,0,0,0,0,0,0,80,1076,0,0,118,0,0,0,479,274, +0,0,0,0,0,0,0,0,0,0,0,497,0,0,669,261,0,0,0,0,13,0,0,0,0,0,0,791,250,642,0,0,0, +1429,939,949,0,0,0,0,0,0,0,0,0,0,0,0,0,818,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,982,330,0,0,0,0,545,0,0,0,0,0,0,947,0,1188,0,0,0,0,0,904,0,0,0,0,0,1372,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,693,377,0,0,0,0,0,0,0,0,0,0,0,0,0,0,695,0,0, +713,386,0,0,0,0,128,1575,0,0,0,0,0,0,424,893,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,904,0,0,0,0,0,552,322,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,1808,49,0,0,0,0, +1832,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,421,0,0,442,415,0,0,289, +0,0,0,0,0,206,110,0,0,0,0,0,205,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +19,1539,0,0,0,0,0,1340,0,1194,0,0,0,0,0,0,0,0,549,0,0,0,0,0,0,0,0,1720,0,0,0,0, +0,0,0,0,0,319,0,0,0,0,112,1180,0,0,0,0,0,0,0,0,0,0,0,967,0,0,0,0,0,0,0,0,0,1940, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,735,0,0,0,0,0,0,0,0,0,897,132,0,0,0,0,0,0,0, +0,0,0,38,838,0,0,0,379,218,8,660,1017,0,0,0,0,0,0,111,387,647,877,0,0,53,790,0, +0,0,0,0,0,0,0,458,0,0,0,0,0,0,954,0,0,0,394,0,1367,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,882,0,0,0,0,0,0,0,1409,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,38,124,342,199,0,0,0,0, +0,0,0,0,0,0,724,628,0,0,0,0,804,266,0,0,0,0,0,208,0,79,0,0,0,0,0,0,0,0,741,0,0, +0,0,0,0,0,0,0,0,606,0,1494,821,1553,0,0,135,405,0,0,178,100,0,0,0,0,0,0,0,0,0,0, +0,0,0,481,0,0,0,1378,0,0,0,0,0,0,0,0,0,0,0,0,0,791,33,1227,857,0,467,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,447,0,0,0,0,0,0,86,128,0,0,0,0,0,0,587,0,0,0,692,1018,0, +195,0,0,0,0,0,0,0,1546,0,0,0,0,0,0,0,0,0,0,0,684,0,0,345,0,0,0,0,0,0,365,0,1683, +0,0,472,0,433,0,0,0,0,0,0,0,28,0,0,0,997,0,705,3,0,0,0,0,0,0,0,0,0,229,0,0,0,0, +102,0,0,0,0,866,1022,0,0,0,0,0,0,0,0,0,55,0,115,0,0,0,0,933,0,0,0,0,0,0,0,702,0, +0,0,0,0,0,0,1728,26,484,0,0,0,185,618,417,0,803,0,0,0,0,0,0,0,0,0,0,0,1262,0,0, +0,0,0,0,0,0,0,0,0,0,0,633,0,0,0,0,0,0,0,0,0,0,0,0,0,479,262,0,0,0,0,0,0,830,0,0, +0,0,26,70,0,0,0,0,0,0,0,0,217,0,640,51,0,0,360,1586,0,0,0,0,0,652,0,0,0,0,0,766, +0,0,0,0,298,737,0,0,0,0,0,0,0,0,0,0,655,222,906,0,0,1013,991,2009,0,0,0,0,503,0, +0,0,216,154,0,0,0,716,0,844,0,0,0,0,621,252,0,0,0,0,748,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,103,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,576,0,0,0,648,0,0,0,331,0,0,0, +0,0,0,0,0,0,0,0,0,632,0,0,0,518,107,0,0,0,0,0,0,0,0,851,0,0,0,0,504,0,0,0,0,0,0, +0,0,0,0,0,0,7,883,0,0,0,0,0,0,0,922,0,0,0,0,0,0,0,0,91,993,0,0,0,0,0,0,200,131, +10,0,0,0,0,0,0,0,0,0,0,0,0,0,365,1433,0,0,0,0,28,103,0,0,798,1013,0,0,0,0,0,0,0, +0,39,1925,0,853,0,0,271,519,0,0,0,0,338,0,0,300,470,419,0,0,0,0,0,0,836,0,0,0,0, +0,0,1937,0,0,0,0,0,393,0,0,357,0,0,0,0,0,703,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,387,0,0,0,0,0,0,75,708,453,1351,0,303,0,0,772,0,0,0,0,0,0,0,0,749,0,0, +0,0,0,0,0,0,0,0,0,0,0,1065,0,0,717,226,0,0,0,0,0,890,431,626,0,0,0,0,706,0,0,0, +51,698,0,0,0,0,0,0,0,0,0,0,0,828,0,0,17,0,0,0,0,1929,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,84,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,871,498,0,101,1793,0,0,0,0,0,0,435,0, +0,0,0,0,966,0,129,1644,0,0,0,0,0,0,0,0,0,0,0,0,0,997,502,0,0,0,0,0,0,0,0,0,0,0, +0,823,0,1927,0,0,0,0,98,1756,0,0,0,0,0,0,0,0,0,0,0,0,8,0,160,1046,0,492,0,0,0,0, +0,0,129,45,0,0,0,0,0,0,353,558,0,0,0,0,0,785,0,0,0,1145,189,0,0,0,26,353,0,0,0, +0,0,2024,0,0,0,606,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,855,0,0,0,0,0,0,0,0,0,0,0, +0,0,2011,0,0,5,4,0,0,461,764,0,0,0,1449,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1445,0,0, +0,1168,0,0,0,233,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,216,0,0,0,286,0,0,0, +3,0,0,0,723,536,0,0,0,0,0,285,0,0,0,560,0,0,0,0,0,690,0,0,0,0,0,1246,0,0,63,0, +33,0,0,0,0,0,520,1862,0,0,0,0,0,0,0,0,0,0,0,0,630,0,0,0,0,554,0,0,0,0,0,1001,0, +0,0,0,0,446,0,0,0,0,0,0,0,1313,0,0,837,636,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,278, +0,0,0,0,0,0,0,0,868,0,0,0,0,1010,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1231,0,304,0,506,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,0,93,1408,794, +843,704,0,285,114,485,898,145,0,19,2035,0,0,0,1933,0,0,0,0,0,0,0,1728,0,0,0,0,0, +0,0,0,746,0,0,0,0,0,0,0,995,1964,0,0,0,0,0,0,0,0,0,0,0,1550,0,874,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,1018,0,0,0,814,126,0,0,1264,0,0,814,955,0,0,0,0,0,0, +0,981,0,0,0,0,0,0,0,0,915,56,0,0,100,0,0,0,0,0,0,0,0,0,638,0,0,0,0,738,0,0,0,0, +0,0,0,0,0,758,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1112,0,0,214,0,0,0,133,0,196, +168,0,0,0,0,0,1152,0,1245,0,0,538,169,871,1816,0,0,413,133,0,0,0,978,0,0,43,93, +371,0,0,0,0,0,0,526,25,0,754,335,0,0,0,0,182,0,0,0,0,0,0,0,0,0,0,0,39,601,0,0,0, +0,0,0,0,181,370,0,0,1652,358,0,0,0,0,0,0,0,0,0,176,286,0,788,0,0,0,0,0,1223,780, +254,1003,896,0,0,0,1447,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,744,0,0,0,0,0,126,0, +41,788,0,0,0,629,0,0,0,0,0,0,0,0,0,0,0,293,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,0,0,0,420,37,1900,0,0,0,0,542,1570,957,0,0,0,0,0,0, +0,373,31,0,0,0,0,125,325,0,0,0,0,0,0,323,0,0,1547,0,0,0,0,0,0,0,0,0,0,0,0,0, +1216,0,0,0,0,0,0,198,1905,629,15,0,0,0,0,0,0,20,75,543,1353,0,0,0,533,0,0,6,0,0, +0,0,0,0,538,0,0,0,0,0,0,0,0,0,0,0,338,0,0,0,0,11,0,0,0,284,659,0,989,0,0,0,0,0, +0,0,0,0,848,0,0,507,0,0,0,0,0,0,0,0,188,991,884,0,0,0,0,60,959,0,0,0,0,0,1653,0, +0,922,337,0,638,0,0,500,0,0,0,0,0,0,0,0,0,0,0,166,0,0,0,0,0,0,0,0,0,0,0,0,418,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,760,0,0,0,0,0,0,1277,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,770,0,0,0,0,0,0,0,243,89,0,0,0,0,0,0,0,0,0,1396,0, +560,0,0,3,1658,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,586,0,0,1271,0,0,0,505,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,637,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1947, +41,445,0,0,0,0,0,0,0,0,57,189,0,0,371,0,0,0,0,552,0,883,0,923,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,0,0,0,875,0,0,0,1788,49,0,0,0,0,0, +0,0,0,0,0,0,661,0,0,1945,0,0,0,0,0,794,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,1135,0,0,0,745,0,0,0,0,0,0,0,84,0,0,0,0,0,0,0,410,0,976,0,0,0,0,0,703,0,0, +0,0,0,0,187,322,0,0,0,227,0,0,0,0,560,0,31,1395,0,0,0,0,0,466,0,0,0,0,643,167,0, +0,0,1428,0,412,0,0,0,0,0,0,0,0,0,1118,562,0,0,0,0,0,256,0,0,0,0,0,0,1771,0,0,0, +0,0,1190,132,0,66,0,0,0,0,0,0,0,0,0,0,317,0,0,0,63,0,0,0,0,0,0,0,1475,0,0,0,0,0, +0,0,288,0,0,0,0,608,0,0,0,0,0,0,0,0,1225,0,1189,0,0,0,0,0,0,0,1468,0,0,0,0,0, +689,120,0,0,0,0,0,0,0,1,0,329,0,0,0,0,226,0,0,0,0,0,1855,0,0,461,0,0,0,0,1346,0, +0,0,0,0,85,0,0,299,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,1171,0,0, +0,980,0,0,0,0,0,0,0,0,637,279,0,0,0,0,0,293,0,0,0,0,528,17,0,0,0,0,5,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,48,0,0,0,0,0,0,0,601,0,0,0,0,0,0,779,0, +196,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1322,737,752,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,412,192,80,0,0,8,1470,0,0,0,0,0,0,0,0,0,873,0,0,0,0,0,835,0,0,0,0,256, +38,986,0,0,0,0,0,0,0,0,0,91,257,278,911,0,0,0,0,0,0,0,0,749,151,0,0,0,0,0,0,0,0, +0,0,0,0,989,0,0,990,0,0,90,194,0,0,0,0,0,425,0,0,0,0,0,774,0,0,0,0,0,0,0,0,0,0, +646,827,752,0,0,0,662,0,22,21,0,0,0,0,0,0,95,239,0,0,0,431,0,0,0,0,0,874,0,0, +265,65,0,0,0,1350,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1887,0,0,0,0,0,0,0,809, +0,696,0,1074,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,630,0,0,802,0,0,0,56,776,0, +970,0,0,797,0,0,0,0,0,400,0,0,1951,0,0,41,0,11,118,0,0,0,0,0,0,0,0,251,615,0,0, +0,1044,0,0,0,0,0,0,0,0,0,0,0,225,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,370,0,0,0,0, +104,48,209,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,930,0,0,0,0, +0,0,0,0,0,0,0,1286,0,759,0,120,385,0,0,0,429,0,0,0,0,0,0,0,0,820,0,0,0,0,0,0, +199,0,10,151,0,0,0,761,365,0,0,0,0,0,0,0,0,0,46,1086,0,0,0,0,11,1624,58,344,0,0, +1008,1868,0,0,0,888,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,711,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,440,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,914,1913,0,958,0,885,0,0,0,0,0,0,0,0,0,0,0, +0,0,847,276,0,302,65,0,0,0,510,0,1514,0,0,0,0,0,0,152,291,0,0,0,0,0,0,0,0,0,0,0, +0,282,589,0,0,0,0,0,0,0,0,0,0,0,0,0,130,0,0,463,42,0,0,0,0,0,372,0,0,0,0,0,0,0, +0,0,680,0,0,0,0,0,0,0,0,977,1997,0,0,0,810,0,0,0,0,0,0,0,0,0,1390,0,0,0,644,0,0, +867,982,0,0,0,0,0,0,0,540,0,123,0,0,0,1978,0,0,0,0,789,623,0,1723,0,1220,0,0,0, +0,0,0,0,480,0,0,0,0,0,0,0,0,0,0,0,888,0,0,0,0,0,0,0,0,0,0,0,0,299,1995,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,788,179,0,0,0,0,0,0,431,156,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,1373,39,80,196,0,0,507,0,0,0,646,0,0,0,0, +0,1214,0,0,0,0,926,0,0,0,1,114,0,0,0,0,0,446,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,0,0,0,490,0,0,0,491,0,1584,0,0,507,250,0,0,0,158, +10,362,1,0,0,0,0,0,0,0,0,0,408,228,860,480,0,779,0,0,0,557,0,0,142,197,0,0,0,0, +0,0,0,0,0,0,0,1490,11,378,316,1057,0,0,18,579,299,1546,0,177,0,0,0,0,0,0,0,0,0, +411,0,0,0,0,727,439,0,0,0,0,0,1528,0,0,0,0,0,0,58,0,482,0,0,0,505,1952,0,0,0,0, +0,0,0,0,0,0,0,242,0,0,0,0,0,0,0,953,0,0,0,0,802,0,0,0,0,0,0,0,0,0,0,290,0,0,791, +52,0,0,0,0,0,0,0,0,0,0,0,112,0,0,0,0,0,1028,0,0,138,0,0,0,0,1811,0,0,0,0,0,0, +934,1821,0,0,0,0,371,38,0,0,0,1296,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,723,0,0,0,0,0, +0,0,0,0,0,0,0,0,1330,0,0,0,0,0,0,0,1255,296,109,0,0,0,0,0,660,0,0,0,0,270,591,0, +0,0,0,0,0,0,1090,81,0,0,0,0,391,0,0,0,0,249,322,0,0,0,0,0,0,0,1412,0,0,0,0,0,0, +0,0,0,0,526,632,0,0,0,0,0,0,235,144,0,0,0,0,0,940,0,0,0,52,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,309,196,0,0,0,0,0,1912,0,1290,0,686,0,0,625,0,0,0,0,0,0,0,0,0,0,0,412,0, +0,0,0,43,0,0,0,0,11,967,758,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,0,0,0,0,0,0,0,0,0,0, +873,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,890,0,0,2,0,0,0,0,0,0,0,0,1774, +393,263,0,0,0,0,0,0,818,456,0,0,251,178,393,97,0,0,0,0,0,674,168,0,0,0,0,0,0,0, +159,1639,0,0,0,0,0,0,0,0,59,934,0,191,0,0,0,0,346,165,0,877,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,128,0,0,0,0,0,0,1297,0,0,0,0,0,0,164,0,0,0,15,132,241,1073,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,228,324,53,0,0,910,0,0,0,0,0,0,0,0,734,705, +217,73,0,0,0,0,0,0,0,0,636,389,0,1409,0,0,0,0,0,893,0,0,0,0,21,0,0,0,0,0,0,0,0, +0,0,0,0,0,721,0,0,0,959,0,0,0,0,1433,0,0,0,0,0,0,0,0,0,0,0,0,174,189,0,0,0,0,0, +0,0,0,0,0,22,2,0,0,815,354,0,0,0,0,425,0,411,60,13,1611,0,0,0,0,0,0,0,0,0,0,0,0, +0,1478,596,0,0,398,0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,1159,0,0,0,0,0, +592,223,0,0,0,0,0,0,0,245,64,0,0,0,0,278,0,604,0,0,1502,265,0,0,0,0,0,0,0,310, +1763,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,129,0,0,0,0,0,0,0,0,0,1356,0,0,0,0,0,0,0, +0,505,0,0,0,0,0,0,0,1000,0,0,966,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,839,0,0,0,0,0,0, +0,0,0,0,0,0,0,637,0,0,0,0,0,0,0,0,0,0,0,0,0,0,590,0,0,0,0,280,0,0,0,1386,0,0,0, +281,0,1064,0,0,0,0,0,917,0,0,15,555,0,0,1014,1883,0,0,0,965,0,0,117,33,0,0,0, +801,0,0,0,0,0,877,0,824,0,0,0,0,0,0,0,0,0,0,0,365,0,0,0,0,0,0,774,7,0,430,0,0, +231,360,0,0,0,0,0,0,0,0,822,740,0,0,929,1485,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,852,0,0,0,0,17,0,0,0,0,0,0,1001,0,0,0,0,35,831,0,0,384,457,0,0,0,1351,0,27, +0,0,984,0,264,552,0,401,0,0,0,710,0,1211,0,0,11,205,0,0,0,0,0,0,0,0,0,0,0,0,5, +579,0,717,0,0,1011,0,0,0,0,0,0,0,0,0,0,0,0,0,0,805,0,0,0,0,0,0,0,0,0,0,0,489,0, +0,0,1024,0,0,0,0,0,0,0,0,0,892,0,0,0,0,0,0,0,0,0,0,0,0,473,0,0,0,659,864,0,0,0, +0,0,0,152,819,0,51,0,0,0,0,0,0,0,0,0,0,130,0,0,0,0,0,229,0,0,0,0,674,0,0,0,0,0, +0,0,0,0,770,52,79,0,0,0,1666,0,409,0,0,0,0,0,0,0,195,0,688,0,0,0,0,0,0,0,0,0,0, +0,889,174,160,0,0,0,0,0,0,0,0,0,0,0,0,0,872,0,918,569,268,0,0,0,1224,0,1361,0,0, +0,0,0,0,0,0,0,374,0,0,0,0,0,731,0,0,0,0,190,0,0,0,0,0,0,0,202,506,444,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,835,0,17,1526,0,0,0,0,0,477,0,0, +994,1374,76,0,0,0,0,0,0,0,355,287,0,1389,0,0,0,0,0,0,455,384,0,0,0,264,0,0,0,0, +0,0,0,0,0,0,0,0,1001,0,0,0,0,0,0,0,0,0,0,0,0,28,0,0,0,851,175,359,0,0,0,0,0,0,0, +0,287,740,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,857,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +819,1402,0,0,0,0,0,0,174,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1649, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,655,573,0,0,0,0,0,0,0,0,128,351,0,0,0,0,0,0, +0,0,0,0,0,918,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,687,0,0,0,0,0,0,0,0,0,1525, +0,0,0,1009,0,0,0,0,0,0,0,340,0,0,0,0,0,0,0,0,0,0,861,0,176,0,0,0,0,0,0,0,0,0,96, +985,0,615,0,0,0,0,0,0,0,1919,0,0,0,0,0,1131,0,0,0,0,0,0,0,247,0,0,0,0,27,23,0,0, +0,0,0,0,0,0,38,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1015,0,0,0,0,0,1088,0,0, +0,0,0,1585,0,0,0,0,227,0,0,0,478,360,0,0,0,95,0,0,0,0,0,0,699,0,0,0,26,0,0,0,0, +1119,0,0,0,739,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,741,67,0,0,0,0,0,0,464,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42,0,96,0,0,0,26,342,0,0,0,0,0,0,203,0,0,449,0, +0,0,0,0,0,0,0,0,0,256,311,0,0,0,0,0,0,758,0,0,0,0,0,0,0,0,827,0,0,0,0,581,64,0, +1047,0,0,0,0,0,288,0,0,0,0,0,1375,0,0,0,0,0,0,0,0,0,0,0,1309,0,0,0,0,0,0,0,0, +376,12,0,0,0,0,0,154,0,1520,0,1753,95,502,0,0,0,0,0,0,0,269,291,1197,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,15,0,0,0,0,1341,0,1017,0,0,0,0,0,0,0, +0,857,1810,533,0,0,1453,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,836,211,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,19,0,156,0,0,0,0,1009,0,0,0,0,0,0,0,0,0,0,0,0,0,820,0,0, +0,0,0,0,0,0,0,228,0,0,0,1131,0,1276,0,0,0,0,0,0,0,0,0,0,0,0,849,1792,0,0,389, +291,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,0,0,525,0,0, +0,453,0,0,0,0,666,0,0,0,422,0,355,0,0,0,0,165,0,260,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,865,0,0,0,0,0,0,0,1625,0,0,0,234,0,1383,0,0,0,0,0,0,0,0,306,0,0,0,802,1921, +0,0,0,0,0,0,180,0,0,0,0,1312,814,0,0,0,0,0,0,0,0,0,0,707,0,0,0,1493,11,61,733,0, +0,0,341,0,0,0,98,0,0,0,0,0,0,0,0,0,0,0,1014,0,0,0,0,0,0,0,142,102,0,0,30,0,0, +823,0,1045,0,0,0,1930,0,1512,0,0,0,0,0,0,0,87,0,1243,245,0,0,0,0,0,0,0,48,68,0, +0,0,0,0,0,0,0,126,77,625,938,0,0,351,0,0,0,174,1668,0,707,0,0,0,0,0,0,0,0,0,0,0, +403,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,282,0,0,0,0,0,0,8,44,0,0,363,115,0,0,0,0,0,0, +0,0,0,0,0,0,545,761,0,0,835,1254,0,0,0,0,930,1936,0,0,0,0,0,0,0,0,653,0,0,0,0,0, +344,0,0,1483,673,185,0,0,460,93,753,478,0,0,0,0,0,1020,0,0,0,0,0,0,0,103,0,0,0, +499,0,0,0,0,0,0,207,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,0,968,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,3,0,0,0,0,399,0,0,0,0,224,563,0,0,0,0,0,704,0,0,0,0,0,0,0,0,0,0,0, +1559,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,861,0,0,0,0,946,333,746,0,0,0,0,0, +0,0,910,0,0,0,0,0,0,0,0,0,0,0,0,0,652,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1393,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1514,0,0,0,0,201,0,510,717,0,0,528,0,0,0,0, +20,0,0,0,1251,0,0,0,1163,0,0,0,307,0,0,0,0,0,1091,0,0,0,0,0,0,0,0,0,0,0,429,0,0, +0,881,0,0,0,0,0,621,0,0,0,0,0,0,0,736,0,348,0,868,0,0,0,0,433,0,0,0,771,1495,0, +0,0,0,215,0,0,0,0,0,124,0,0,0,0,0,0,0,0,0,0,0,55,0,0,0,0,0,0,0,112,62,0,856,270, +0,572,0,0,0,0,939,0,0,0,0,0,0,0,352,0,0,0,0,0,0,0,0,0,647,0,0,0,0,10,0,0,0,0,0, +0,0,220,0,0,0,0,0,0,0,0,0,0,0,0,0,464,0,0,109,0,0,0,1746,0,0,0,515,0,0,0,566,0, +0,0,0,0,0,67,40,0,0,722,992,0,0,923,0,0,0,0,0,0,1145,0,0,0,0,0,0,0,0,0,0,0,568, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,247,0,0,0,0,645,0,0,328,0,0,0,0,0,0,0,0,0,0,0,0, +1363,0,0,0,0,0,1280,0,0,0,0,0,0,0,0,0,0,7,28,360,162,0,0,0,0,0,0,0,0,0,0,0,764, +0,0,833,862,0,856,0,0,0,0,0,0,736,92,0,0,948,1944,0,1479,63,590,0,0,0,1521,0,0, +0,709,0,0,61,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,483,0,0,0,0,1213, +0,0,0,0,29,1022,0,1712,0,466,0,0,0,0,0,0,0,0,0,0,0,0,0,731,0,0,0,0,0,0,171,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,241,0,0,0,0,0,0,0,0,0,0,0,964,2005,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1100,0,0,0,954,0,0,0,0,0,0,0,0,0,1958,0,0,34,549,994,0,0,449, +137,850,0,0,670,146,0,0,0,0,518,159,0,0,0,0,0,0,0,0,151,0,0,1027,0,0,0,0,0,0,0, +0,0,0,983,0,0,0,0,993,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,141,501,0,0,0, +0,0,0,0,0,0,452,0,0,0,0,0,0,0,0,0,0,233,149,0,0,0,0,0,0,0,0,582,0,0,0,801,0,0,0, +0,0,0,70,0,0,369,0,36,0,0,0,0,0,0,0,204,721,430,241,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,0,0,0,0,0,0,0,0,0,0,0,1817,16,1078,1021,0,0, +406,0,0,0,0,0,69,0,0,0,0,0,1830,0,0,0,824,0,0,0,0,0,0,0,0,0,826,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,816,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,717,1845,0,423,0,0, +0,0,0,0,0,0,510,0,0,1048,0,0,0,618,0,0,0,520,0,0,0,0,990,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,321,0,0,0,0,0,0,0,1135,0,0,921,0,0,0,24,397,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,856,0,0,0,139,282,981,0,288,0,0,0,1890,651,56,0,0,0,0,0,0,0, +0,261,0,0,0,0,0,0,0,0,0,0,0,617,1403,0,1205,0,0,563,0,0,0,0,0,0,0,0,333,0,0,0,0, +0,369,0,0,0,0,0,0,0,0,0,622,0,0,0,1407,0,0,0,0,0,0,0,0,0,0,0,0,624,160,0,363,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,0,0,0,0,0,0,0,0,0, +0,619,0,174,292,0,0,656,616,0,0,0,685,0,0,0,0,0,0,0,0,0,0,0,0,0,647,0,0,0,631,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1267,0,0,0,1797,0,0,0,1684,0,0,469,0,531, +1230,73,0,0,0,0,0,0,0,0,0,268,0,0,0,0,0,102,558,109,65,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,595,0,0,0,0,0,374,1832,0,0,0,0,0,0,16,0,405,6,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,881,0,1495,0,0,0,0,0,0,0,0,0,142,0,0,0,0,0,0,0,0,0,0,21,466,23, +257,0,0,0,0,0,0,77,404,0,0,0,0,0,0,712,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,860, +1848,0,0,652,629,0,0,0,0,13,377,0,1842,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1501,0, +0,0,1906,0,0,0,0,0,0,0,0,0,0,0,0,0,491,234,171,0,0,0,0,631,1186,0,0,0,0,0,0,0,0, +0,0,0,0,931,0,170,0,0,0,0,0,0,0,0,0,0,1587,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +765,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,424,0,0,714,0,0,0,0,685,0,0,0,0,0, +0,285,0,0,0,0,0,0,429,0,0,0,0,0,0,0,0,0,0,71,18,0,0,0,0,0,0,0,0,0,0,116,828,0,0, +0,0,0,0,289,0,0,0,0,0,0,0,0,675,0,0,0,1424,0,0,0,0,0,647,0,0,0,1334,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,36,209,0,0,0,0,0,0,0,342,0,0,0,928,0,0,0,0,0,1838,118,856,654, +318,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,915,895,454,0,0,513,1425,0,0, +0,0,0,0,791,0,153,0,0,0,0,0,0,796,909,445,345,0,0,0,0,0,0,0,0,578,0,0,0,1387,0, +0,0,555,0,0,0,0,0,0,766,0,0,0,0,0,0,0,0,0,0,541,0,0,0,0,0,0,0,0,0,0,0,0,0,880,0, +0,0,0,0,1506,0,0,983,0,768,0,0,0,0,584,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,737, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,226,30,426,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +117,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,462,0,0,0,385,0,398,0,0,0,0,0,0, +0,0,0,347,0,0,0,0,125,1259,644,136,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,469,0,0,0,0,0, +1367,0,0,0,0,0,0,0,0,0,0,0,719,0,0,0,0,0,0,0,0,0,0,0,0,0,1423,0,0,0,0,0,0,0,0,0, +749,0,0,0,0,546,645,0,0,0,0,0,0,277,0,0,1275,0,0,0,0,0,0,0,453,536,555,0,0,987, +1107,0,0,90,0,0,0,0,0,0,0,0,860,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +257,0,1768,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1071,0,0,0,0,0,0,0,0,0,0,0,0,0,83, +0,835,0,0,0,0,0,0,0,2006,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,696,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,95,1718,0,0,0,0,0,0,0,26,0,550,0,0,0,0,0,901,0,0,0,0,0, +0,822,0,0,122,0,0,0,807,0,0,0,0,0,262,0,620,601,34,0,0,170,0,0,0,0,537,0,0,0,0, +0,0,0,0,0,332,0,0,208,1909,182,261,0,0,0,1721,0,0,0,0,0,933,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,1609,0,895,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,812,0,0,942,1916,0,0,0,0, +0,0,0,778,0,0,0,137,0,1314,0,0,0,0,0,0,0,1661,0,0,0,0,0,0,0,1591,0,0,0,0,0,0, +820,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,185,89,0,1160,230,6,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,63,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1740,0,0,177, +170,0,1961,0,0,0,0,0,0,0,0,0,0,0,0,91,0,17,44,0,0,0,0,0,0,0,0,0,270,0,296,0,0,0, +0,0,0,0,1523,0,0,0,0,0,0,0,0,0,0,757,7,0,0,0,0,0,0,0,0,0,0,530,588,0,0,0,0,0,0, +0,0,0,786,0,0,0,0,0,580,627,88,447,57,0,0,0,0,0,0,0,0,845,735,0,0,0,0,0,31,15,0, +460,521,12,424,0,0,0,1302,0,0,0,0,0,0,0,595,0,0,0,13,548,97,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,1472,452,1767,0,0,0,0,0,0,0,0,0,0,115,0,0,0,0,0,0,1543,0,1111,0,0,0,0, +1,0,359,488,0,267,0,0,0,1983,0,0,0,0,0,0,0,1155,0,1575,0,1438,31,0,0,377,101,0, +0,0,0,0,0,0,0,0,0,0,0,0,476,0,0,0,0,0,0,0,0,2023,0,0,0,0,0,1836,0,0,0,0,35,843, +0,0,0,0,0,0,0,554,0,0,0,536,625,207,0,1371,0,0,0,424,785,336,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,896,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,750,0,0,0,0,238,0,0, +0,0,0,383,0,0,0,0,0,0,0,0,603,725,11,0,0,0,0,0,0,0,0,0,476,0,0,0,0,0,1552,0,0,0, +0,0,0,0,680,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,435,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1431,0,0,13,112,0,0,356,0,0,0,0,0,0,0,0,0,0,1963,0,0,0,1244,18,0,0,0,0,0,0,867, +0,0,0,0,0,0,50,708,73,592,0,502,0,0,0,0,0,0,161,347,0,0,0,0,470,33,0,246,571,10, +0,465,614,0,237,0,0,0,0,0,24,18,0,506,0,0,0,0,0,0,33,309,0,0,0,0,0,0,0,0,0,0, +140,0,0,0,0,1056,0,0,0,1704,0,0,0,0,0,0,0,1036,0,0,0,0,0,0,0,0,0,1315,432,86, +264,524,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,107,0,0,0,0,0,123,927,0,0,957,1149,0,0, +0,0,0,778,0,502,196,0,0,0,0,1312,0,0,0,0,0,0,0,855,0,0,0,0,0,0,0,0,0,0,45,1400, +0,0,0,1003,0,0,0,0,0,1097,0,0,0,0,0,0,0,0,545,612,0,0,0,0,0,0,0,0,0,0,0,0,54,0, +0,0,0,172,0,0,0,1029,0,0,0,0,0,0,0,0,0,568,0,0,0,732,617,0,0,974,94,989,733,0,0, +0,0,0,0,1789,0,0,665,2015,0,0,0,0,0,0,806,287,0,0,0,0,0,1539,0,0,0,0,0,0,0,0,0, +0,182,1563,0,0,0,0,0,0,0,0,0,484,0,0,0,0,0,1623,0,0,0,0,0,0,0,0,878,1833,0,1569, +0,0,0,0,0,0,0,0,93,0,715,994,0,0,0,0,0,63,0,591,0,0,0,0,0,0,0,749,0,0,0,0,547, +366,0,0,0,1747,0,0,0,0,0,0,0,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1463,0,772, +893,0,0,0,48,0,0,941,0,0,690,1785,106,440,0,0,0,0,0,0,0,0,0,0,32,0,332,216,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,0,0,0,0,0,0,0,852,0, +0,416,564,0,918,0,1764,0,0,3,0,0,274,0,0,0,0,501,0,0,0,0,0,0,0,851,743,0,49,0, +879,0,0,47,0,0,0,0,0,0,865,0,1202,0,0,0,0,0,0,47,272,0,0,0,0,0,0,0,0,0,0,0,1455, +0,0,0,0,891,1911,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,761,0,0,0,0,0,0,0,0,0,407,0, +183,0,0,490,0,0,0,0,0,0,0,35,731,0,0,0,0,0,0,0,819,0,0,0,0,0,0,0,0,0,0,0,0,0, +575,0,0,0,0,45,818,0,0,77,222,0,0,0,0,849,1880,0,0,0,633,0,1308,0,0,0,0,0,0,0,0, +0,0,86,0,0,0,0,0,0,0,0,0,0,0,0,0,0,817,0,0,0,0,0,0,0,0,0,882,0,0,0,914,0,0,0,0, +0,0,0,0,0,0,865,0,0,426,399,58,0,0,0,0,0,0,538,102,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,876,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,139,566,0,63,12,0,0,0, +0,0,0,0,0,0,0,0,0,0,3,114,0,0,0,0,0,0,0,0,576,0,0,0,0,0,0,0,0,933,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,692,0,0,0,0,0,0,0,0,0,0,0,0,752,0,0,0,0, +0,0,0,0,375,0,1011,0,0,96,0,0,0,0,0,0,0,0,0,148,0,0,0,0,0,0,0,0,0,0,0,337,56, +666,0,246,394,0,0,0,0,0,0,0,0,437,0,0,0,506,0,0,0,0,1003,0,1163,0,328,0,0,0,0,0, +0,0,0,1000,0,0,0,0,0,744,101,0,0,0,0,0,726,0,0,176,0,146,9,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,839,0,0,0,0,0,0,223,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,246,1931,29,0,0,1771,0,0,0,0,0,846,6,157,0,0,0,0,0,0,0,0,0,875,0,0,477, +773,177,639,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1747,0,0,0,0,158,873,0,659,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,391,0,0,0,0,0,0,0,0,0,0,0,0,668,883,0,78,628,0,0,0, +0,0,0,0,0,0,0,0,0,1460,0,962,0,0,0,0,0,460,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,199,0, +0,0,388,474,0,271,0,333,608,0,0,0,0,0,0,49,0,988,0,707,617,0,0,0,0,0,0,0,756,0, +0,0,0,0,1583,0,0,0,0,0,0,0,0,0,0,285,0,0,0,0,0,0,0,0,0,0,0,0,0,0,344,0,0,0,0,0, +0,0,0,515,1709,0,0,0,0,0,0,0,0,404,0,0,0,0,500,0,0,0,0,0,0,0,0,0,68,216,0,0,0,0, +0,0,0,488,353,0,0,177,236,0,0,458,490,0,0,0,0,0,0,756,1504,0,757,0,1735,0,0,108, +598,0,0,0,0}; +BROTLI_INTERNAL const uint8_t kStaticDictionaryHashLengths[32768] = { +8,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,0,12,0,0,0,0,4,22,5,0, +4,0,0,0,0,0,0,0,0,0,0,0,0,14,6,0,0,0,5,0,0,0,0,0,0,0,7,13,0,0,4,0,0,0,0,0,0,0,0, +0,6,0,0,0,0,8,0,0,0,0,0,0,7,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,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,0,12,0,0,4,0,0,0,4, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,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,0,6,0,0,0,0,0,0,0,0,10,4,0,5,13,7,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,8,7,0,0,9,0,8,0,0,0,0,0,0,6,0, +0,9,0,0,0,11,0,0,6,8,7,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,7,0,0,0,6,8,0,0,0,0,0, +0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,9,0,0,0,8,4,13,7,0,0,0,0,0, +7,0,5,0,0,0,0,8,5,0,5,0,0,8,7,0,0,0,0,0,0,0,0,0,0,9,0,0,0,8,0,0,0,10,4,0,5,0,4, +0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,8,7,0,4,9,4,0,0,0,0,0,0, +9,0,0,0,8,5,0,0,0,6,0,0,0,0,0,0,0,0,0,7,18,0,0,0,0,4,9,0,0,4,0,6,0,0,0,6,0,6,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,5,8,7,0,0,0, +0,9,0,0,0,0,0,0,0,8,6,10,6,0,0,0,4,0,6,8,6,0,0,0,4,0,0,0,0,0,5,0,0,0,6,0,0,0,0, +10,0,12,7,0,0,0,0,0,4,0,0,0,0,0,5,0,0,8,7,0,0,0,0,0,0,0,0,9,5,0,0,0,0,0,0,0,0,0, +0,0,0,0,6,11,0,0,0,0,0,0,0,0,0,8,7,0,0,10,0,0,0,0,0,0,0,0,6,10,0,17,0,8,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,8,6,9,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +7,0,0,11,4,0,5,0,0,0,0,0,0,0,0,0,0,10,5,0,6,8,5,0,0,0,0,0,0,0,0,0,0,11,5,0,0,0, +0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,9,0,0,0,0,5,0,0,0,0,0,0,0,0,0,6,0,0,8,7,0,0,0,0,0, +0,0,0,0,0,0,5,0,0,0,6,0,0,10,0,0,0,20,0,0,0,0,0,0,0,0,6,9,5,0,0,0,0,10,4,8,0,0, +4,13,0,0,0,0,0,0,0,9,0,9,0,0,0,0,0,0,0,0,0,0,0,0,4,8,6,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,12,0,0,4,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,12,5,0,0,10,4,10,7,13, +0,0,0,0,0,0,0,0,6,0,6,0,6,0,0,0,0,0,0,19,0,0,4,12,6,9,0,0,0,0,4,0,4,11,0,0,0,0, +0,0,0,12,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,4,0,0,0,0,0,0,0,0,0,6,0,0,0,0, +0,5,0,0,0,0,0,6,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,8,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,9,6,0,0,0,0,0,4,0,4,0,0,0,0,0,0,0,0,0,4,0,0,0, +6,0,0,0,0,0,0,0,0,0,0,13,6,0,0,0,0,0,0,0,0,0,0,0,6,8,0,0,0,0,0,0,0,0,0,0,6,0,0, +0,0,0,5,0,0,0,0,14,4,0,0,0,4,12,5,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,8,6,0, +0,0,0,0,0,12,0,9,6,0,0,0,0,13,0,0,5,0,0,0,0,0,4,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,13,0,9,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,5,0,0,0,6,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,6,0,6,0,0,0,0,0,0,0,0,8,7,8,4,0,0,0,0,0,0,0,0,0,0,0,7,0,7,0,0,0,4,0, +0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,8,6,8,4,0,0,0,0,0,6,0,7,0, +0,0,0,0,0,0,0,0,0,10,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,7,0,0,0,0,0,0,9,5,0,0, +0,0,0,7,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,9,4,0,0,0,0,0,0,0,4, +12,5,11,0,0,0,0,0,0,0,0,0,8,7,0,5,0,0,8,7,0,5,0,0,0,0,8,0,0,0,0,7,0,4,10,0,0,0, +0,0,0,0,9,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,0,0,0, +13,5,0,0,0,4,0,0,0,0,0,6,0,0,0,0,0,0,14,5,0,0,0,7,0,0,10,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,6,0,4,0,5,0,0,0,0,8,5,0,0,0,0,0,0,9,5,9,0,0,0,0,0,0,0,0,6,9,0, +0,4,0,0,0,7,0,0,0,6,0,0,10,4,0,0,0,0,0,6,0,0,10,0,0,0,8,5,0,0,0,0,0,0,0,0,10,0, +0,0,0,0,18,4,12,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,8,7,0,0,0, +0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,8,4,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, +0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,8,0,0,0,0,0,0,6,0,0,0,4,10,5,0,0,0,0,0,0,0,0,0,0, +0,4,8,7,0,0,8,6,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0, +0,0,0,8,6,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,6,0,7,0,0,0,0,0,0, +0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,8,7,0,0,0,0,8,0,12,6,0,6,0,0,0,0,9,7,11,7,0,0,0, +0,0,0,0,0,0,0,0,0,11,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0,10,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0, +0,0,0,6,0,0,0,7,0,4,14,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,0,0,0,14,0,0,0,0,0,8,4,0,4,0,0,0,5,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,20,0,0,4,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,12,5,0,7,0,5,0,0,10,0,0,7,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,6,0,4,9,7,0,0,0, +0,0,7,0,0,0,0,0,0,10,0,9,0,9,0,0,0,0,0,0,0,0,4,9,0,0,0,0,6,0,0,0,0,0,0,0,0,11,4, +0,6,0,0,0,0,0,0,8,0,8,0,0,0,0,0,0,0,0,0,0,4,0,0,0,5,0,0,0,0,0,0,0,0,13,6,0,0,11, +0,0,0,0,0,0,0,9,7,0,0,0,0,0,0,0,0,0,0,0,6,18,0,0,4,0,0,0,0,0,0,0,6,0,0,0,0,0,0, +0,5,0,0,0,0,0,0,0,0,9,7,0,0,0,0,0,0,0,6,0,0,0,0,9,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,11,7,0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,0,0,11, +4,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,4,0,4,0,0,0,0,8, +6,0,0,0,0,0,0,9,6,0,0,0,0,0,4,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0, +0,6,0,6,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,6,0,6,0,0,10,6,0,0,0,7,0,0,8,0,8,7,0, +0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,9,0,0,0,0,6,0,0,0,0,0,0,0,5,0,0,18,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0, +0,0,0,8,7,0,0,0,0,0,0,0,0,12,0,12,0,0,0,11,6,0,5,0,0,12,0,12,5,0,7,11,6,0,0,11, +0,0,0,12,0,0,4,12,7,8,6,0,0,0,0,8,5,0,0,0,0,0,0,0,4,11,0,0,6,0,7,0,0,0,0,0,0,0, +5,0,6,0,0,0,0,8,0,10,0,0,0,0,0,0,0,0,0,0,0,9,7,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0, +0,0,0,0,0,0,0,0,0,11,7,0,0,0,0,0,0,10,0,0,5,0,0,12,6,0,0,0,0,0,0,10,6,0,0,0,0,8, +6,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,5,0,0,0,0,11,0,10,6,0,0,8,6,0,0,0,6,0,7,10,6,0, +0,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,10,7,0,0,0,0, +10,6,0,0,0,0,0,0,8,5,11,0,8,4,0,0,0,4,0,0,0,0,9,4,8,0,0,0,0,0,0,0,11,6,0,0,0,0, +10,7,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,7,0,0,0,0,9,6,0,5,0,7,0,0,0,0,0,7,0,0,11,0,0, +0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6, +0,0,0,0,13,0,8,6,13,0,0,0,11,7,0,7,0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,6,0,0,9,6,0,6,0,0,0,0,0,5,0,0,0,0,0,0,0,0, +0,0,0,0,0,5,9,0,0,0,0,0,0,0,0,0,0,4,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,9,7,0,7,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0, +5,11,5,0,0,0,0,0,0,0,0,0,4,0,7,0,6,0,0,0,6,20,0,0,0,10,7,0,5,14,4,0,0,0,0,0,0,0, +0,0,6,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0, +0,0,6,0,4,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,9,7,0,0,11,6,15,0,0,0,0,0, +10,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,7,0,0,0,0,0,0,0,0,9,7,13,0,0,0,0,0, +0,7,0,0,8,6,0,0,0,0,0,0,0,0,9,4,0,0,0,0,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,5,0,0,0,0,0,0,0,0,0,0,0,0,8,5,0,4,0,0,0,0,0,0,0,0,0,0,12,6,8,0,12,0,0,7,0,0,0, +0,0,5,10,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7, +14,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,8,7,10,7,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6,18,6, +14,7,0,0,0,0,0,0,0,0,11,6,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,0,11,7,0,0,10,7,0,0,0,6,8,6,0,0,0,0,0,0,0,6,0,0, +19,0,0,0,9,5,0,0,0,0,0,0,11,7,0,0,0,7,0,6,0,0,11,0,0,0,0,4,8,0,0,0,0,0,0,0,0,6, +0,0,0,0,0,6,0,0,8,4,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,7, +0,7,0,0,0,7,15,0,0,5,0,0,0,0,10,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,7,0,0, +0,0,0,0,0,0,9,6,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +11,7,0,0,0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0, +0,0,5,0,4,0,0,0,4,0,4,0,0,0,0,0,0,0,0,0,6,0,0,0,0,11,6,0,0,8,5,14,0,0,4,0,0,0,7, +17,0,0,0,0,0,0,0,13,5,0,0,0,0,0,5,0,0,0,5,0,0,0,0,16,6,0,4,0,0,0,0,0,0,12,0,0,0, +0,0,0,6,0,0,0,0,0,0,0,0,0,0,12,5,0,5,0,6,10,0,12,0,0,0,0,0,0,0,0,7,0,0,0,0,8,4, +0,0,0,0,0,0,0,0,0,0,8,7,0,0,8,0,0,0,8,0,0,6,0,7,0,0,0,5,0,6,0,4,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,22,0,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,0,0, +0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,18,0,0,0,9,4,0,0,8,0,9,7,0,0,0,0,0,0,8,6,0,0,0,0, +0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,9,7,0,0,0,6,0,0,14,0,0,0,0, +0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,7,10,4, +0,6,0,0,0,0,0,0,8,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,9,6,0,0,0,0,0,0, +0,0,11,6,12,7,0,0,0,0,0,0,0,6,0,5,0,0,0,0,0,0,9,6,11,6,0,0,0,0,9,5,0,0,0,0,0,0, +0,6,8,5,0,0,0,0,8,0,10,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9, +5,10,7,0,0,0,5,8,7,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,4,8,7,0,0,0,6,0,0, +0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,6,0,0,0,0,0,0,0,0,0,0,0,0,22, +0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,5,0,0,0,0,0,0,0, +0,0,0,0,0,17,0,0,6,0,6,12,4,19,6,0,0,0,0,16,0,0,0,0,7,15,7,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,4,10,4,0,0,8,7,0,7,0,0,9, +4,0,6,0,0,0,4,0,5,0,0,0,7,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,7,10,0,0,0,0,0,11,7,0,0, +0,0,12,6,0,0,0,0,0,0,0,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8, +0,0,0,0,0,0,0,0,0,10,4,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,8,7,0,0, +0,0,0,0,0,6,0,0,0,4,0,0,11,4,0,0,12,7,0,0,0,0,9,0,0,6,0,0,0,0,0,0,0,0,0,5,0,0,0, +4,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,6,0,0,0,0,0,0,9,4,0,6,0,0,0,0,0,4, +0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,6,0,0,0,5,0,0,0,0,0,0,0,0,0,7,9,6,0,7,0, +0,0,0,0,0,0,6,0,0,0,0,8,6,0,0,0,0,10,6,11,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,5, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,5,0,4,8,0,0,0,0,0,9,7,0,0,0,0,0,0, +13,5,0,0,0,0,8,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,8,5,0,0,11,7,0,0,0,0,0,0,8,6,0, +0,0,0,0,7,0,4,0,0,0,0,0,0,0,5,0,6,0,5,0,0,0,0,0,0,0,0,0,0,0,0,10,4,9,0,0,0,0,0, +0,4,0,0,0,0,10,5,10,7,0,0,0,0,0,0,0,0,16,7,0,0,0,0,0,7,0,0,0,0,11,0,0,0,0,0,0,0, +0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,5,0,4,0,0,0,7,0,0,0,0,0,0,13,0,0, +0,0,0,0,0,0,0,0,7,0,4,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,13,7,0,7,0,4,16,0,0,0,0,6,8,7,9,7,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0, +0,6,0,0,8,5,0,4,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,5,11,7,0,0,11, +0,0,0,0,0,9,5,0,4,0,0,0,0,9,7,8,6,0,0,0,0,0,0,10,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0, +0,7,0,0,0,0,0,0,0,0,0,0,0,4,10,6,0,7,0,0,0,0,0,0,0,5,0,0,0,0,0,0,10,7,10,0,0,0, +0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,7,0,6,8,7,12,4,0,0,0,0,0,0,0,5,14, +0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0, +6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,4,0,0,20,4,0,0,0,7,0,6,0,0,0,0,0,0,0,0,8,0, +0,6,15,0,0,6,0,0,0,4,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,12,0,0,0,9,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,5,0,0,0,0,0,0,8,6,0,0,18,0,0,0,10,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,9,6,0, +6,0,0,0,0,0,0,0,0,9,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,7,0,0,0,0,9,0,9,0,0,4, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,9,5,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,10,0,0,0,0,7,0,0,0,0,0,0,0,0,0,7,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,4,8,0,8,0,0,0,16,0,0,0,0,0,0,0, +0,0,0,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,8,0,0,0,11,0,0,0,0,0,0,0,0,0,0, +6,0,0,0,0,11,0,0,0,9,7,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,7,0,7,0,6, +0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6, +0,0,0,0,0,0,0,6,0,0,18,0,8,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,7,0,4,0,0,0, +0,0,0,0,0,0,0,8,0,0,0,0,0,16,0,0,0,0,0,16,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,18,0,0,0,0,0,0,0,0,0,9,7,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,4,0, +0,0,0,0,0,0,0,9,4,0,0,0,0,12,5,0,0,0,0,0,0,0,7,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,6,0,0,0,0,0,0,0,0,0,0,0,0,12,5,0,0,0,0,0,0,0,5,0,0,10,6,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,9,0,0,0,11,0,0,6,0,6,0,0, +0,7,0,0,0,0,0,0,8,0,0,0,0,6,0,0,0,0,0,0,19,0,0,0,12,0,9,0,0,0,0,0,10,7,0,0,0,0, +0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,16,7,12, +0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,12,6,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,10,5,0,0,0,0,0,0,0,4,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,7,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,4,0,0,0,0,0,0,0,4,0,0,9,0,0,0,8,0,12,4,0,0,0,0, +0,4,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,8,7,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,9,0,0,0,0,0,0,0,12,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,5,0, +0,0,0,0,0,13,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,0,0,8,6,0,6,0,0,0,0,0,0, +0,4,0,0,0,0,0,6,0,0,9,0,0,0,0,0,0,6,0,0,0,0,0,0,11,0,0,0,0,0,0,0,10,6,0,0,0,0,8, +6,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,7,0,0,0,0,0,7,0,6, +10,7,0,0,10,5,11,6,0,0,0,0,0,7,16,0,0,0,0,6,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,5,0,0,0,7,9,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,0, +0,0,0,0,0,8,7,0,0,0,0,11,6,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +8,7,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,12,7,0,7,0,0,0, +0,0,0,0,6,0,0,0,0,9,0,0,0,23,0,0,0,0,0,10,5,0,0,0,0,0,0,0,0,0,4,0,0,11,7,10,0,0, +0,0,0,0,0,0,0,0,0,0,6,0,0,8,7,0,7,0,0,8,7,8,0,0,0,0,0,0,0,0,0,0,0,14,5,0,0,0,0, +0,0,0,0,18,6,8,7,0,0,0,0,0,0,0,4,0,0,0,0,0,0,11,0,0,0,9,7,12,6,0,0,0,0,0,0,0,0, +0,0,12,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,0,7,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,6,8,7,0,0,0,6,10,0,0,0,9,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,6, +10,7,0,0,0,7,0,0,8,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0, +0,0,0,8,7,8,6,0,0,11,7,10,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,4,8,7,0,0,0,0,0,0,0,0, +0,5,0,0,13,0,0,0,0,5,0,0,9,7,0,0,0,0,0,0,0,4,0,0,11,0,0,7,0,0,0,0,0,0,0,0,0,6,0, +0,0,0,0,0,12,7,19,0,8,6,0,0,0,0,0,6,0,0,0,0,0,0,0,0,10,6,8,0,0,0,0,0,0,0,0,0,0, +6,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,7,0,0,12,0,0,0,0,6,9,6, +14,0,0,0,0,0,0,6,0,5,0,0,8,7,0,0,0,6,0,4,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,4,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,5,0, +7,0,0,10,0,9,7,0,6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,12,6,0,0,0,0,0,5,0,6,0,0,0,0, +0,0,0,0,0,0,0,6,0,0,0,0,9,7,0,0,0,0,0,0,11,6,0,0,0,0,0,0,0,0,0,0,11,7,0,0,13,7, +0,0,0,0,0,0,0,0,12,0,0,4,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,6,11,5,0,5,13,0,8,0, +0,0,0,6,0,0,0,0,0,0,11,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,11,5, +9,6,0,0,0,4,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,10,0,0,0,8,5,0,0,9,0,0,0,8,7,9,0,0,0,0,0,0,0,0,7,0,6,0,0,0,0,0,0,0,0,0, +0,11,0,13,6,0,0,9,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0, +0,0,0,0,0,5,21,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,5,0,0,0,0,0,0,0,0,10,0,8,0, +0,6,0,0,0,4,0,0,9,0,0,0,0,0,0,0,0,0,0,4,0,0,8,6,0,6,0,7,10,0,8,4,0,4,0,0,0,0,0, +5,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,6,12,0,0,7,0,0,0,5,0,0, +0,0,0,0,0,0,0,6,0,0,8,6,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +15,7,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,6,0,0,24,7,0,0,0,0,0,0,0,0,0, +7,0,0,0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,6,0, +0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,4,12,0,0,7,0,0,0,0,0,5,0,0,0,0,0,0,0,0,15,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,8,7,0,0,0,0,0,0,0,0,0,0,8,0,0,0, +0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,9,0,9,6, +0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,8,4,0,7,0,0,0,0,0,0,0,0, +22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,4,0,7,0,0,21,7,0,7,9,6,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,8,0,0,6, +0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,23,0,0,0,0,7,0,0,0, +4,0,0,0,0,0,0,0,0,9,4,11,7,0,5,0,0,0,0,11,0,0,4,20,0,0,0,0,0,0,0,0,0,0,0,11,5,0, +7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +21,0,0,0,0,0,0,7,0,0,0,0,0,0,0,5,0,0,0,0,0,6,0,0,0,0,11,6,0,0,0,0,0,0,0,0,9,6,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,5,0,4,9,4,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,4,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,9,0,0,0,0, +0,0,0,10,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,8,7,0,0,11,7,0,0,0,0,0,0,0,4, +0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,0,5,0,0,0,0,0,0,0,0,0,0,8,7,0, +0,0,0,0,0,0,0,0,6,0,0,21,6,0,0,0,0,0,6,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,14,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,8,0,0,7,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0, +0,0,0,8,7,0,0,11,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,5,0,0,0,7,13,7,10,4,0, +0,0,6,0,0,0,0,0,0,0,0,0,5,10,0,0,0,0,0,0,5,0,0,0,7,0,0,0,0,0,0,8,4,0,0,0,0,0,6, +0,0,0,0,0,0,0,0,0,0,12,7,0,6,0,0,10,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,6,0, +0,0,0,0,7,0,0,8,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,10,5,0,6,0,0,0,0,0,4,0,0,0,0, +0,0,0,0,0,4,0,0,0,0,9,0,11,4,0,0,0,6,0,0,0,5,12,7,0,5,0,0,0,0,0,4,0,0,0,7,0,0,0, +0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,13,6,10,0,0,0,17,0,0,4,0,0,0,0,0,6,0,4,0,5,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,11,7,0,0,0,7,0,0,0,6,0,0,0,0,0,0, +0,6,0,4,0,0,0,0,8,0,0,0,0,5,0,0,0,0,0,4,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,9,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,5,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,12,0,0, +0,0,7,0,0,0,0,0,0,0,0,0,0,0,7,0,0,16,4,0,0,11,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +8,7,0,4,0,0,0,0,0,0,0,4,0,0,0,0,0,0,8,6,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10, +7,0,0,0,0,0,0,9,0,0,0,0,0,0,0,12,5,10,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,5,0, +5,18,7,0,0,14,0,0,0,0,0,0,0,9,4,0,7,0,0,0,0,0,0,0,5,0,0,0,6,0,0,0,6,0,0,0,0,0,0, +8,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,5,0,0,0,7,0,0,0,0,0,0,11,0,0,0, +10,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,14,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +11,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,14,6,0,0,0,0,11,4,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,10,7,0,6,0,0,9,0,9,5,0,0,0,0,0, +0,0,0,10,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,8,5,0,0,0,0,0,0,0,0,0,0,11,4,0,6, +0,6,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,12,4,0,6,8,6,0,0,0,0,0,0,0,0,0,0,8,0,0,5,0,0,0,0,0,0,0,7,0,0,13,0,0,0,0,0,0,0, +0,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,12,7,0,6,0,0,0, +0,0,0,0,0,0,0,0,0,13,4,0,7,0,0,0,7,0,7,0,0,0,0,0,0,0,0,10,4,0,0,0,0,0,0,0,0,0,0, +9,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,10,6,21,5,0,0,0,0,8,0,0,0,0,4,0, +7,0,0,0,0,0,0,11,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,0,0,0, +0,7,9,6,11,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,7,10,0,0,0,0,0,0,6,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,19,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,18,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,7,0,0,0,0,0,0,9,4,10,4,0,7,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,9,7,9,7,10,4,0,7,0,0,0,0,0,0,0,6,12,0, +0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0, +0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,8,0, +0,0,0,0,0,5,0,0,8,7,0,0,0,7,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0, +0,0,0,0,4,0,0,8,0,0,6,0,0,0,7,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,7,9,7,0,0,0,4,8,0,0,0,0,6,11,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,6,0,0,0,0,0,0,10,0,0,0,0,0,0,0,13,4,0,0, +12,6,0,6,0,0,0,0,8,7,0,7,0,0,0,0,0,6,0,0,0,0,0,0,12,6,0,4,0,0,0,0,0,0,0,0,0,0,9, +7,22,0,0,0,0,4,0,0,0,0,0,6,0,0,0,4,0,0,9,0,0,6,0,0,24,7,0,7,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,10,6,0,5,0,0,0,0,0,0,0,7,0,0,8,0,0,0,0,0,0,0,10,5,0,0,0,0,0,0,0,0,0,7,0, +7,0,0,0,0,0,0,13,4,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,18,0, +0,0,0,0,0,7,12,0,9,4,0,0,0,0,0,0,0,0,0,4,0,0,0,0,8,0,0,0,0,0,0,0,0,4,0,0,0,7,0, +0,0,0,8,7,0,0,0,0,0,0,0,0,0,4,18,0,0,0,0,0,10,0,0,5,0,0,11,0,0,0,0,0,0,5,0,6,0, +0,0,6,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0, +4,0,0,0,0,0,0,10,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0, +0,0,0,5,8,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,20,7,0,0,0,0,0,0,0,0,0,0,0,4,9,0,12, +6,8,0,14,7,0,5,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,10,0,0, +0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,9,6,0,7,12,0,0,0,0,4, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7, +0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0,0,9,0, +12,6,0,5,0,0,0,6,0,4,0,6,0,0,0,0,0,0,0,0,10,7,0,0,0,0,0,0,8,0,0,0,0,4,0,0,0,0, +10,0,0,0,0,0,0,0,8,6,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,0,0,0,0,0,0,0,0,0,0,0, +6,0,0,12,6,20,5,0,0,0,0,0,0,0,0,0,0,0,0,9,5,0,5,0,0,0,6,13,7,0,0,0,0,15,6,0,0,0, +6,0,0,13,7,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,5,0,7,0,0,0,0,0,4,0,0,0,0,0,0,0,0, +10,6,0,0,0,0,0,6,0,0,0,0,9,0,0,0,0,0,19,6,0,0,0,0,0,0,0,0,0,0,13,0,11,0,0,0,0,0, +0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,0,0,0,0,0,0,10,0,0,6,0,0,0,0,8,0,0, +0,9,0,15,4,0,6,0,0,0,0,0,6,12,0,0,0,0,0,0,0,14,7,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, +0,0,0,0,0,8,7,0,0,0,0,0,6,10,0,0,0,0,0,0,0,0,7,8,4,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,9,7,10,5,0,0,0,0,8,0,0,0,0,4,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,6,12,0,0,0,10,7,0,5,0,6,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,6,0,4,0,0,0,0,0,7,0,0,0,0,0,0,0,4,9,6,0,0,0,7,0,0,0,0,0,0,0,0,8,6,0,0, +0,0,0,0,0,4,12,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,7,0, +0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,12,6,0,6,9,4,0,0,8,4,0,6, +0,0,0,0,0,4,0,0,0,0,0,0,0,6,0,0,9,6,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,8,0,0,6,13,4,0,5,8,0,0,0,0,0,0,0,8,0,0,0,10,5,0,0,9,0,0,0,0,0,0,6,0,0, +24,0,0,0,0,0,0,0,8,0,0,7,0,0,12,0,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,7,0, +6,8,0,10,0,9,7,0,0,0,5,0,0,0,0,0,0,0,4,8,5,0,0,0,0,8,7,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,19,0,0,4,0,0,0,0,0,6,0,0,0,0,0,5,0,0,0,0,8,0,0, +0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,10,4,0,0,0,0,0,0,0,6,0,0,0,4,20,0,0,7, +10,6,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,7,0,0,0,0,9,6,0,0,0,0,0,0,0,4, +12,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,9,4,0,5,0,0, +0,0,0,0,0,6,0,6,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,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,6,9,0,0,0,0,7,0,0,0,0,0,6,0,5,0,0,0,0,0,0,0,0,9,0,0,0, +0,6,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,17,7,0,0,13,6,14,6,0,0,0,0, +8,0,0,0,0,0,0,7,12,7,8,7,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,4,0,0,0,0,0,4,0, +0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,12,4,0,0,10,7,0,0,0, +0,0,0,10,0,0,6,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,12,0,0,6, +0,0,0,0,0,0,0,0,8,7,12,0,0,0,0,0,0,6,0,6,0,4,0,0,18,6,0,0,0,6,0,0,0,0,0,6,10,6, +0,0,0,0,0,0,8,7,14,0,0,0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19, +0,0,0,8,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,8,7,0,0,10,5,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,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0, +0,0,9,4,8,0,0,0,0,0,0,4,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,4,0,0,0,0, +0,6,0,0,9,7,0,0,0,0,0,5,0,0,0,0,8,7,0,0,14,0,0,0,0,6,0,0,0,0,0,0,9,6,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,5,0,7,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0, +0,0,0,6,0,0,0,6,0,4,0,0,0,0,0,4,0,0,0,0,12,0,0,7,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0, +0,12,0,16,6,0,0,0,0,0,0,11,7,0,4,8,7,0,0,0,0,0,6,0,0,0,0,16,0,0,0,0,6,0,0,0,0,0, +0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,4,10,7,0,0,0,0,0,0,12,7,0,0,0,0,0,0,0,0,0,0, +0,0,10,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,13,4,0,0,10,0,0,0,0,0,0,0,0,0,19,0,0,0, +0,0,0,0,0,0,0,0,0,0,8,6,22,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0, +5,0,0,0,0,0,5,0,0,0,0,0,5,0,0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +4,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,7,0,0,18,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,14,7,0,0,11,5,0,0,0,5,0,0,0,0,12,5,0,0,0,0,0,0,0,0,0,0,24,6,0,0, +0,7,0,4,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,7,0,4,0,0,0,0,8,7,0,0, +9,6,0,0,14,5,0,0,0,6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,12,6,0,0,0,0,0,0,0,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,5,0,0, +0,0,12,7,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,6,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,6,0,0,13,7,0,0,0,0,0,0,14,0,11,4,0, +0,0,4,0,0,0,0,14,5,0,0,0,0,0,5,11,5,0,0,0,0,22,5,0,0,0,0,0,7,0,0,0,0,0,4,0,0,0, +4,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,17,0,10,0,0,0,8,0,0,0,19, +5,18,7,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,10,6,0,6,0,0,0,0,10,4,0,4,0, +0,0,0,0,0,14,7,0,5,0,0,0,0,0,6,0,0,0,0,0,0,0,0,8,0,9,6,12,0,0,6,0,0,0,0,0,0,0,0, +12,0,10,6,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,4,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,5,13,0,9,7,0,0,0,0,0,0,0,0,0,0,0,7,9,7,0,0,8,0,0,0,0,0, +22,0,0,0,0,0,0,0,23,6,14,0,0,0,0,0,0,7,0,0,0,0,11,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0, +0,0,10,0,0,6,0,0,0,0,0,0,0,0,0,6,0,0,8,5,0,0,0,0,0,0,0,0,0,7,11,6,21,0,0,0,0,0, +0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0, +0,0,0,0,0,0,0,4,9,7,0,0,0,0,0,0,12,0,0,0,0,7,0,0,0,0,0,0,0,0,10,4,0,0,0,0,0,0,9, +0,0,0,20,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,11,7,0,0,0,0,0,0,0,6,15,0,0, +0,0,0,0,0,0,0,0,0,0,0,12,4,0,5,0,0,0,0,0,0,11,7,17,6,0,0,0,0,0,0,15,6,0,7,0,0,0, +0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,6,0,5, +0,0,11,0,11,7,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0, +17,0,0,0,0,6,0,0,0,5,0,0,0,0,0,0,8,7,9,6,0,0,14,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0, +8,7,0,4,0,0,0,0,0,0,0,6,0,5,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0, +0,0,0,5,0,4,0,0,8,7,0,6,12,5,0,7,18,7,0,0,8,5,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0, +10,0,11,0,0,0,0,0,0,0,0,0,0,0,9,0,0,4,0,6,0,7,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0, +7,0,0,0,0,8,0,0,0,15,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,0,0,0,0,0,0,0, +0,0,6,0,0,0,0,23,0,0,0,10,7,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,5,0,0,0,0,0,0,8,6,0,0, +0,0,0,0,12,7,9,7,0,0,10,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,9,0,8,7,0,0,0, +6,0,6,0,4,0,5,0,0,0,0,0,5,8,7,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,7,10,5,0,0,11,6,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,4,9,7,0, +0,0,0,11,7,0,0,0,0,0,5,0,0,0,7,0,0,0,0,23,6,11,4,0,0,0,0,0,0,9,0,0,0,10,6,0,0,0, +0,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,6,0,0,10,6,0,0,0,7,0,0, +0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13, +6,11,7,0,0,0,0,0,0,0,0,0,0,0,0,10,5,0,0,0,6,0,0,0,5,0,6,0,6,0,0,0,0,0,0,0,0,0,0, +0,6,0,0,0,0,8,7,0,5,0,0,0,0,0,6,0,0,0,0,0,0,0,4,10,0,8,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,10,6,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,0, +0,0,0,0,0,0,10,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,11,6,0,4,0,0,14,5,0,7,0,0,0,0,0,6,16,0,0,0,0,0,0,0,10,0,0,7,15,0,0,0,11,7,0,0, +0,0,0,0,0,0,0,0,8,7,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,5,0,0,0, +0,8,0,0,6,0,0,0,0,0,0,9,5,0,0,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,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,0,0,0,0,0,0,16,6,0, +0,0,0,0,0,0,7,0,0,0,0,15,7,0,0,0,0,8,0,0,0,14,0,0,0,0,0,0,0,16,7,0,0,0,0,0,7,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,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,6,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,12,6,11,7, +9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13, +7,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,12,0,10,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,8,0,0,5,8,7,10,6,0,0,0,7,0,0,0,0,12,6, +0,0,9,0,0,0,12,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,4,10,0,0,0,10,5,0,0,0,0,0,0,9,6, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,6,0,0,9,5,0,4,0,0,0,6,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,0,0,0,5,0,0,0,0,0,0,0,0,9,0,0,5,0,0,8,7,8, +6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,10,0,9,4,0,0,0,0,0,0,0,6, +11,0,0,0,0,0,0,0,0,0,0,0,8,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,8,7,9,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,7,0,0,0, +0,0,0,10,0,0,0,8,7,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0, +0,0,8,4,0,5,0,0,0,0,0,0,0,7,0,0,0,6,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,22,0,0,0,0,0,0,0,8,5,0,0,0, +0,0,0,0,7,0,0,0,6,0,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,5,0,6,0,7,0,0,0,0, +20,0,0,0,0,0,0,0,0,0,0,7,9,0,0,0,0,0,0,6,0,6,0,7,0,0,0,7,0,0,0,0,0,0,0,4,0,0,0, +0,0,0,14,7,0,0,0,5,0,0,22,4,10,0,0,0,0,0,0,4,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,11,5,13,0,0,0,0,0,0,0,0,0,8,0,0,7,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,10,7,0, +0,0,0,0,0,0,6,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,7,0,7,14,6,0,0,0,0,9,5, +0,0,0,0,0,6,0,0,0,5,10,0,8,6,0,0,0,0,0,0,0,0,9,7,0,0,0,0,0,0,0,6,0,0,8,4,0,6,0, +0,0,5,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7, +14,0,0,5,0,0,18,0,8,4,0,6,0,0,20,0,13,0,0,0,0,7,0,4,0,0,0,0,0,4,8,4,0,0,0,0,0,6, +0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,4,0,0,0,0,0,0,0,0,14,0,0,0,0,0,9,7,0,0,9,0,0,0,0, +0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,20,0,14,0,0,4,0,6,8,5,0,0,0,0,0,7,0,0,0,0,0,0, +0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,10,4,12,7,0,6,0,0,9,7,10,5, +0,0,8,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,0,0,18,0,0,0,14,7,0,0,0,0,0,4, +0,0,0,0,0,0,17,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,4,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0, +0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,8,5,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,5,0,7,0,0,0,0,0, +7,0,0,0,0,0,0,0,0,0,7,0,6,0,0,0,0,0,0,0,0,8,5,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,5,0, +0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,23,0,0,7,0,0,0,0,0,0, +0,0,0,0,0,0,0,4,0,0,0,0,0,0,12,7,8,4,0,0,0,0,0,0,0,0,0,6,0,0,9,5,0,0,0,7,0,0,0, +0,0,0,0,0,0,4,10,0,0,7,0,0,0,5,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,5,0,0,18,7, +0,0,8,0,0,5,0,0,10,0,0,0,0,0,0,6,0,0,0,0,0,5,0,7,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0, +6,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,6,0,0,10,0,0,5,10,4,0,0,12,0,0,0,0, +6,22,4,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,5,0,0,0,0,0,7,0,5,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,6,0,7,0,0,0,6,0,6,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,5,0,0,0,7,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0, +0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,16,6,0,0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,12,7,0,0,0,0,9,0,0,0,0,6,0,0,11,0,0,0,0,0,13,0,9,6,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,4,0,0,10,7,0,0,0,7,0,6,0, +0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,11,0,15,0,22,7,0,4,0,6,0,0,0,0,0,7,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,4,0,7,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0, +18,0,0,0,0,0,0,0,0,0,14,0,0,4,0,0,0,0,8,7,9,0,0,0,0,0,9,0,0,0,14,0,0,0,0,0,0,0, +0,0,11,7,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,7,0,0,0,6,0,6,0,0,0,0,8,0,0,0,0, +0,11,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,9,4,0,0,0,0,0,4,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,6,8,7,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0, +0,0,0,0,0,0,8,6,0,0,9,5,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,5,0, +0,10,6,9,0,0,0,0,6,0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0, +11,7,12,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,4,0,5,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0, +0,0,0,0,6,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,5,0,0,10,6, +0,0,0,4,0,7,13,0,0,4,0,0,11,4,0,6,0,0,0,0,0,6,8,7,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,5,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,5,0,0,0,0,12,6,0,0,0,0, +11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,11,5,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8, +7,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,4,0,0,0,6,17,0,9,0,10,6,0,6,12,0,0,4,0,0,0, +0,0,0,0,0,0,0,8,5,12,7,0,4,0,0,0,0,0,0,0,0,0,0,11,0,9,0,10,6,11,5,0,7,0,0,8,0,0, +7,0,4,0,0,0,7,0,0,0,0,0,0,8,6,0,0,0,6,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,6,0, +0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,11,0,0,0,0,6,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,10,0,0,0,0,0,8,6,0,0,0,0,0,6,12,0,0,0,0,0, +0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,6,0,0,16,0,11,5,0,0,0,0,0, +0,0,0,0,0,10,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,9,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0,0,8,4,0,0,0,0,0,6,10, +7,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,6,0,0,0,0,0,0,9,5,0,0,0,0,8,0,9,0,0, +0,0,0,0,0,0,7,10,0,13,0,0,6,0,0,0,0,0,0,0,0,0,6,9,4,0,0,0,0,0,0,10,0,0,0,0,0,10, +0,0,0,0,0,0,0,10,6,11,0,0,0,0,0,9,0,0,0,0,0,0,4,0,0,0,0,0,0,10,5,0,0,0,0,0,6,0, +0,0,0,0,0,18,4,0,7,0,0,0,0,0,0,24,0,8,6,0,7,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,0,0, +0,8,5,0,0,0,0,10,7,0,6,0,0,0,0,0,0,0,0,8,5,10,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0, +6,0,0,8,7,0,0,0,0,0,0,0,0,0,0,12,6,0,0,0,0,0,0,0,4,0,5,15,0,0,0,0,7,0,7,0,0,0,0, +0,0,0,0,0,6,10,5,0,0,0,6,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,7,0,0,12,0,0,0,0,0,0,0,0, +0,0,5,0,0,0,0,0,0,14,4,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,11,0,10,4,9,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,4,0,0,0,0,0,7,0,0,0, +0,0,0,0,0,0,0,0,7,13,7,0,0,0,0,0,0,0,5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0, +0,0,0,0,0,0,0,5,0,0,0,0,0,6,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,8,0,10,6,0,4,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,6,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,0, +0,0,0,0,0,0,0,10,6,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,5, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,9,7,0,0,0,0,0,6, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,10,6,0,0,0,0,0,0,0,6,0,0,0, +0,0,0,0,5,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,6,0,0,0,5,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,8,6,11,0,0,0,0,6,0,0,0,0,0,0,0,6, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22,0,0, +6,0,0,0,0,0,0,0,6,10,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0, +0,0,0,0,0,0,0,6,0,6,0,0,0,5,0,0,0,0,0,0,0,5,0,0,10,0,11,5,0,0,0,0,0,0,14,7,9,7, +0,6,0,0,0,0,0,4,0,0,0,0,0,0,11,7,0,6,0,0,0,0,0,0,9,7,0,4,0,0,0,7,0,0,0,0,0,5,0, +0,0,0,0,5,0,0,0,7,0,0,0,0,0,5,0,0,0,0,17,5,0,0,8,0,0,0,0,6,9,4,0,0,0,0,0,0,0,0, +8,7,11,7,9,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,6,9,5,0,0,8,6,0,0,0,5,0, +0,0,0,9,0,0,0,9,6,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0, +0,0,0,0,4,0,0,0,0,10,0,0,0,0,0,0,0,0,4,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,4,0,0,0,5,0,0,0,0,0,7,0,0,0,0,0,7,13,5,0,0,0,7,0,0,0,0,0,7,9,6,11,7,0,7,0,0,0, +0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,8,5,0,0,0,5,9,4,0,0,0,0,0,0,0,0,8,4,0,0,0,0, +24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0, +0,0,0,0,6,0,0,0,7,0,0,0,6,0,0,0,0,0,0,0,0,0,5,11,6,0,4,0,7,20,0,8,5,9,5,9,0,0,6, +0,0,0,0,0,0,0,0,0,0,0,7,23,5,0,0,8,4,0,0,10,0,0,6,0,5,0,0,0,0,0,0,0,0,0,0,0,7,0, +0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,9,0,0,0, +10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0, +6,0,0,0,0,14,0,18,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,9,6,0,4,0,0,0,0,0,0,8,4, +11,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,8,4,0,0,0,0,0,0,0,0,12,0,10,7,0,0,10,0,0,0,0, +0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,6,0,0,0,0,8, +6,10,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0,6,0,4,0,0,0,0,0,5,0,0, +0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,4,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,17,7,11,0,0,0,0,0,0,0,0,0,0,4,12,6,0,0,0,5,0,0,0,6,0,0,0,0,0,0,0,0,0,0, +0,5,12,7,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +7,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,6,0,6,0,0,20,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,4, +0,0,0,5,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,6,0,4,13,0,0,7,0,0,0,0,0,0, +0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,0,12,6,0,7,0,0,0,0,10,0,23,6,0,0, +0,4,0,0,0,0,0,6,8,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, +10,0,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,11,0,9,7,0,0, +0,0,0,0,0,0,0,0,9,7,0,4,0,0,0,0,8,7,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, +0,0,0,0,0,6,0,0,10,7,10,5,0,0,8,0,8,0,0,0,0,0,0,4,0,5,10,0,0,0,0,0,0,0,9,0,0,6, +0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,11,7,0,0,0,0,0,0,0,0,9,4,0,0,0,0,0,6,0,0,8, +7,0,0,0,0,0,5,0,0,0,0,0,0,0,0,10,0,0,0,0,5,0,4,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,24,7,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,6,0,0,9,0,0,0,0,0,0,7,0,6,13,0,8, +0,0,0,0,0,0,0,0,0,9,7,0,0,0,0,0,0,0,6,0,0,0,0,8,5,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0, +4,0,0,0,0,0,4,0,0,0,0,0,0,0,6,8,0,0,0,0,6,8,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,4,0,4,0,0,0,5,0,7,0,0,10,0,10,7,0,0,12,5,0,0,9,0,0,0,10,0, +0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,5,0,0,0,0,0,0, +12,0,0,0,0,0,8,5,13,6,0,0,0,0,0,0,9,4,0,0,0,0,8,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0, +0,0,6,0,0,14,0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,17,6,0,0,0,0,12,6,0,0,0,0,8,0,0,7,0, +7,0,4,9,0,0,6,0,0,0,6,0,0,0,0,0,0,8,7,0,0,0,0,0,0,11,0,0,4,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,18,7,0,4,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,6,0,0,0,0,0, +0,0,0,12,5,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,8,0,11,7,0,0,0,0,0,0,0,0,0,4,0,0,0,0, +11,0,0,0,0,0,0,0,21,0,0,6,10,0,0,0,0,0,9,0,10,0,0,0,0,0,11,0,0,0,0,6,0,0,0,0,0, +5,0,0,0,0,0,0,10,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,4,0,0,23,7,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,7,0,0,0,0,0,0,0,0,9,7,0,0,0,7, +0,4,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,0,4,0,6,0,0, +11,6,0,0,0,0,0,0,0,6,0,0,0,0,10,7,0,0,9,4,0,0,11,0,8,5,0,0,0,7,8,5,22,0,0,0,9,6, +0,0,0,0,0,0,0,6,10,4,0,0,0,0,0,7,9,4,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,4,0, +0,0,0,11,6,0,0,0,0,0,0,0,0,0,0,0,7,0,6,0,0,0,0,0,7,0,0,0,0,0,0,0,6,0,6,0,4,0,0, +0,0,0,0,0,7,0,7,0,4,13,0,0,0,0,0,8,0,0,0,0,7,0,0,0,0,0,0,11,6,0,7,0,0,0,0,9,0,0, +0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,10,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,0,0,4,8,0,0,0,0,0,8,0,0,0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,0,6,0,0,0,0,13,5,8,0,0, +0,0,0,0,0,14,0,0,6,0,0,0,0,0,0,0,0,0,7,0,0,17,6,0,0,0,0,13,4,0,0,9,6,0,0,10,5,0, +0,10,5,0,0,0,0,13,0,0,0,0,6,0,0,0,0,0,0,10,0,12,0,0,0,0,0,0,0,0,0,0,0,8,4,0,4,0, +0,0,4,0,0,0,0,0,4,0,0,12,0,0,5,9,4,0,0,0,0,0,0,0,0,0,5,8,5,0,0,0,7,0,0,0,0,8,7, +0,0,0,6,12,5,0,0,0,5,0,0,0,5,0,0,0,0,0,4,12,0,0,0,9,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,4,8,7,0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0, +0,9,6,0,0,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,11,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0, +0,0,0,0,12,7,0,0,0,7,10,7,0,0,11,0,0,0,0,0,0,0,0,0,11,7,0,0,0,6,0,0,11,0,0,0,0, +0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,22,0,10,7,0,0,8,5,0,0,0,0,0,5,0,0,0,0,0,0, +0,0,0,0,9,6,8,7,0,6,0,0,0,0,0,5,0,0,0,0,0,0,8,7,0,0,0,0,9,7,0,0,0,6,0,0,8,7,0,0, +0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,4,0,5,0,0,0,4,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,18,6,0,0,0,0,0,0,0,4,0,0,0,0,0,0,9, +6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,4,0,0,0,5,0,0,0,0,14,0,0,0, +9,0,0,0,0,0,0,0,0,0,9,7,12,7,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,12,0,0,0,0,0,12,7,0,0,0,5,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,10,7,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,6,0,0,0,0,0,0,9,6,0,0,0,0,0,6,0,0,0,0,0, +0,0,0,0,0,9,0,0,0,0,7,0,6,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0, +0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,6,0,7,12,6,0,0,0,0,0,5,0,0,0,0,0,0,0,0, +0,7,0,0,8,6,0,0,0,0,10,7,0,0,0,0,0,0,0,6,0,0,0,0,0,6,12,0,0,0,0,0,0,0,0,6,0,0,0, +0,0,6,0,0,0,6,0,0,0,0,0,6,16,0,0,0,0,0,0,0,0,0,9,0,17,0,14,7,8,0,0,0,0,0,0,6,0, +0,0,0,0,0,0,0,0,0,11,0,0,6,8,7,0,6,0,0,0,0,0,0,0,0,0,0,12,6,0,0,0,0,0,0,0,0,0,0, +9,0,0,0,0,7,0,0,0,0,11,5,0,4,9,6,8,0,0,0,0,0,0,0,0,0,10,0,11,7,0,0,0,0,0,0,0,0, +9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11, +0,0,0,12,0,0,0,0,0,10,5,0,4,0,0,0,0,0,7,10,6,11,6,0,0,0,0,0,0,0,0,0,0,0,0,17,0, +0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,8,0,0,4,0,0,0,6,0,0,0, +0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,4,0,0,0,0,9,6,0,0,0,4,0,0,0,0,0,4,10,7,0,7,0,0,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0, +0,0,0,0,0,0,6,0,0,0,6,0,6,0,0,0,0,10,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,18,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,13,0,0,0,0,0,10,0,0,0,0,0,0,0,0,4, +0,0,0,6,0,0,0,0,0,4,8,0,0,0,11,7,0,0,0,4,0,0,0,0,0,7,0,0,8,5,0,0,16,0,0,0,13,6, +0,0,0,0,0,0,0,6,0,0,0,0,20,0,11,6,0,0,8,7,0,0,0,0,0,6,17,0,8,0,0,0,0,0,8,7,0,0, +9,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0, +0,0,4,0,7,0,0,0,0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,8, +0,8,0,0,0,0,0,0,0,11,0,8,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,6,0,0,9,0, +0,0,0,0,8,0,0,0,0,0,18,0,0,0,0,0,0,4,9,0,0,0,0,0,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,9,6,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,7,0,0,0,0,0,0,0,0, +0,4,0,0,0,0,0,0,14,0,0,0,0,7,0,6,0,0,8,0,20,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,8,0,0,0,14,0,0,0,0,0,0,0,8,0,0,7,0,6,0,0,0,7,0,0,0,0,0,0,0,0, +0,0,0,4,12,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,10,6,0, +5,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0, +0,0,0,5,8,4,0,0,0,0,0,0,0,4,0,0,0,7,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,12,7,0, +0,0,0,13,6,0,0,0,7,0,0,8,0,0,0,8,0,0,0,0,0,0,0,0,0,0,5,0,0,0,7,0,0,0,0,0,0,11,5, +0,6,0,0,8,5,0,7,0,0,0,0,0,0,0,7,0,0,0,0,8,6,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,4,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,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +14,0,10,7,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,19,0,0,4,0,0,0,7, +0,0,11,5,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,16,0,10,5,18,0,0,7,9,6,0,5,0,0,0,0,0, +0,0,0,0,5,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,5,0,0,0,7,0,6,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,6,0,0,0,4,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,6,0,0,0,7,23,0,0,0,0,5,0,0,0,0,0,0,8,5,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,14,0,20,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0, +11,0,0,0,0,7,0,0,0,0,15,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,7,0,0,0,0, +0,4,0,0,0,0,10,0,0,0,0,0,9,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,10,0,11,6,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,5,0,0,11,0,0,0,0,7,0,0,0,0,0,0,8,7,0, +4,0,0,0,0,11,0,0,0,0,0,11,0,0,5,0,0,8,7,0,4,0,7,0,0,0,0,0,0,0,6,0,0,0,0,0,4,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,10,5,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,6,0,5,0,0,0,0,0,0,0, +0,0,4,11,5,10,7,0,7,0,0,9,6,9,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,9,4,0,4, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,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,8,6,0,0,0,0,11,7,0,0,0,0,0,0,0,0,0,0,11,7,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,8,5,0,0,8,0,9,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0, +10,7,0,0,0,6,0,0,0,0,0,0,8,0,0,6,0,0,0,6,10,0,0,0,0,0,0,0,0,0,0,0,8,5,0,0,0,6,0, +0,0,6,0,0,0,0,9,5,8,5,8,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0, +0,8,7,10,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,0,11,7,0,0,0,0,0,5,0,0,0,6,0,7,0,0, +10,5,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,6,0,0,0,0,0,0,11,0,0,0,0,0,13,4, +0,0,0,4,0,0,0,0,0,5,8,0,0,0,12,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,7,14,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,6,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,4,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,7,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,4,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,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,4,0,5,0,0,15,6,10,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,14,6,10,0,0,0,0,0,0,0,0,6,0, +0,0,0,0,0,0,0,12,6,0,0,0,0,0,0,0,0,9,7,0,0,0,0,0,6,0,5,11,4,0,6,0,0,0,7,0,0,0,0, +0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,5,0,0,8,5,0,0,0,0,0,0,0,0,0,0, +0,0,10,0,0,0,0,0,9,6,9,4,0,0,0,4,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,8,5,0, +0,0,0,0,0,0,0,0,0,0,4,0,0,11,5,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,5,0,0,0,0,0,0, +0,0,0,7,12,0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0, +4,9,6,0,4,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,6,0, +7,8,6,0,0,0,0,0,0,0,4,0,0,9,6,0,0,0,0,0,0,0,0,0,6,0,5,0,4,0,0,0,0,0,0,0,5,0,0,0, +0,0,5,0,0,0,7,12,7,0,0,0,0,0,0,18,4,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,6,0,0,0, +0,12,0,0,7,0,0,0,0,0,7,0,0,13,0,0,6,0,0,0,0,8,7,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,7,10,5,0,0,8,0,0,0,0,0,0,0,8,6,0,7,0,0,8,4,0,4,0,0,0,0,10,4,0,0,14,0, +0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,17,0,0,0,0,0,0,6,0,0,0,0,8,6,0,0,10,5,0,0,0,0,8, +6,0,0,0,6,0,0,0,7,0,0,0,0,0,6,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,12,0,0,0,0,6, +8,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,0,0,0,0,7,0,0, +0,0,0,6,0,0,0,0,0,0,0,0,0,0,12,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,4,24,0,0, +0,0,0,12,6,0,0,10,6,0,5,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,17,7,0,5,0,0,0, +0,0,0,0,0,0,0,0,0,0,6,11,5,9,0,8,7,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,10,7,0,0,0,0,0,0,0,7,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,11,5,8,7,0,0,0, +0,8,5,0,0,0,0,10,7,0,7,0,0,0,0,0,0,0,0,0,0,13,6,0,0,0,0,0,0,0,0,0,6,0,4,0,0,0,0, +0,6,12,0,8,7,0,0,0,0,0,0,0,0,0,0,16,0,10,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,22,0,0,0, +0,0,0,0,0,0,0,0,0,0,13,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,22,0,0,6,0,0,21,0,0,0,22,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +6,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,6,0,0,0,5,0,0,0,0,0,7,8,0,0,0,0,6,14,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,0,0,6,0,0,8,6,0,0,0,0,0,0, +0,0,0,0,0,6,0,0,0,0,8,5,0,0,11,7,0,6,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0, +6,0,0,0,5,0,0,0,0,0,0,0,0,0,4,0,0,8,7,0,0,0,0,8,5,11,7,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,4,0,0,0,0,8,5,0,0,10,0,0,4,13,7,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,5,0,0,13,6, +0,6,0,7,0,0,8,4,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,15,0,0,0,10,7,0,0,0,0,0, +7,0,0,0,0,0,0,0,4,0,0,0,0,0,6,0,0,0,0,19,0,0,0,0,6,0,0,0,0,0,4,0,0,0,0,0,6,0,5, +0,7,0,0,0,0,0,0,0,0,0,6,0,0,11,4,0,0,0,6,0,0,13,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,8,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,12,6,0,0,0,0, +0,7,0,0,0,0,0,0,11,7,0,0,0,0,0,6,0,0,10,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,5,11,6, +0,0,0,0,0,0,0,0,10,0,0,0,0,6,0,0,0,0,0,0,8,7,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,0,0, +0,0,0,8,7,0,0,0,0,9,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,10,7,0,0,0,0,10,0, +0,6,0,0,13,0,0,0,0,0,0,0,9,6,0,0,8,6,8,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,4,0, +0,9,7,0,0,0,0,0,0,11,0,0,0,10,7,0,0,0,0,0,0,0,0,9,6,0,0,12,4,0,4,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,6,0,0,0,0,21,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,5,0,0, +9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,4,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,0, +16,0,0,4,0,0,0,0,0,7,0,0,0,6,0,6,0,0,11,0,0,0,0,5,0,0,0,0,0,0,0,4,8,5,0,0,0,0,0, +0,14,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0, +0,0,8,0,0,0,0,0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0, +0,0,0,0,6,9,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,14,7,0,0,9,7,0,0,11,0,0,0,0,0,10, +4,11,5,13,6,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,5,0,0,0,0,0,4,0,0,9,0,0,0,0, +0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,6,12,5,0,0,0,6,14,0,0,0,0,0,0,0,0,0,0,4,9,4, +0,0,0,0,0,5,0,0,0,0,0,0,0,4,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,5,0,0, +0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,11,6,0,0,13,7,0,0,13,6,0,7,0,0,0,0,0,0,8,6,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,10,6,0,4,0,0,12,6,0,0,0,0,0,0,0,0,10,6, +0,0,0,6,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,6,0, +0,0,0,0,7,0,0,9,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,6,0,0,8,6,0, +0,0,7,11,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,8,0,0,0, +0,0,0,5,12,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,12,0,0, +0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,8,7,0,0,8,5,0,0,0,4,9,5,0,0,0,7,10,6,0,0, +0,0,0,0,9,7,0,0,8,5,8,0,8,4,0,0,13,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,0,0,0,0,0,0,0, +0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,4,0,0,0,0,0,0,0,0,0, +0,11,7,0,0,0,7,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,5,0,0,0,7,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,9,7,0,0,0,0,8,5,0,4,0,0,0,0,0,6,0,6,14, +6,0,0,0,0,9,6,0,0,0,0,0,0,8,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,6,0,0,0,0,14,7,9,7,8,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,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,6,16, +0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,14,0, +0,6,0,0,8,6,0,0,0,0,0,6,0,0,12,0,0,0,0,0,8,5,0,7,11,0,0,5,0,4,0,0,0,6,0,0,0,0,0, +0,0,0,0,0,0,0,9,6,0,4,0,6,0,0,0,0,0,0,0,0,0,0,0,0,11,6,0,0,0,0,0,0,10,5,0,0,0,0, +0,4,0,0,0,7,11,6,0,4,8,5,9,5,0,0,0,5,0,7,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,8,5,14,7,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,16,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,4, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,9,6,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,9,0,0,0,12,5,0,0,0,0,0,0,0,4,10,5,0,0,0,0,0,0,0,0,0,0,0,6,0, +0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,4,0,0,0,6,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,0,10,4,0,0,0,0,0,5,0,0,0,4, +0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,8,0,10,7,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,7,10,7,0,0,0,0,0,0,0,0,15,0,0,0, +0,0,0,0,0,0,0,7,0,0,0,0,0,7,10,7,9,7,0,0,0,7,0,0,8,0,0,0,0,0,0,0,9,0,0,0,8,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,8,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,7,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,15,7,12,6,0,0,0,7,0,5,0,0,0,0,0,0,0,0,0,0,0,0,18,0,0,5,0,0,0,0, +0,0,0,6,9,5,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,9,7,0,0,14,0,0,0,11,7,0,0,0,0,0, +0,0,0,0,0,0,4,0,0,11,7,0,0,0,0,8,0,0,0,0,0,0,6,8,7,0,0,0,7,10,4,0,0,0,0,0,0,0,0, +0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,10,0,0,0,0,0,0, +6,0,6,0,0,0,0,0,4,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,11,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,7,0,0,10,7,0,0,0,0,9,7,0,0,0,0,0,0,13,7,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,12,0, +0,0,0,6,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,7,0,0,9,6,0,0,11,0,0, +0,0,0,14,4,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,7,0,0, +0,0,0,6,0,7,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,5,0,0,0,0,20, +7,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,8,0,0,0,0,0,0,0,0,0,11,5,0,0,0,0,0,0,0,0,0,0,10,4,0,0,0,5,8,5,10,4,0,0,0,0,0, +0,13,6,9,7,0,0,10,7,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,6,0,0,0,7,0,6,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,10,7,0,0, +0,0,0,0,0,0,0,0,12,4,0,0,0,0,8,7,0,0,0,0,0,7,0,6,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0, +0,0,0,0,6,0,6,9,6,0,0,12,5,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,0, +0,0,0,0,0,0,0,0,0,5,8,7,9,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,11, +4,0,0,0,0,0,0,8,0,0,0,10,7,0,4,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,0,8,0, +0,0,0,0,0,5,0,6,0,0,10,0,14,0,0,0,0,0,0,0,23,0,0,0,12,0,10,5,0,0,0,0,0,0,0,0,0, +5,0,0,0,0,8,0,0,0,0,6,8,0,0,0,0,0,0,0,0,0,22,0,8,0,0,0,0,6,0,0,0,0,0,0,0,5,0,0, +0,0,0,0,0,6,18,4,0,0,0,7,10,6,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0, +0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,7,10,0,0,0,0,0,0,6,0,0,0,0,11,5,0,0,0,0,0,0,0,0, +15,0,8,6,0,0,13,7,0,0,0,0,0,7,0,0,0,0,0,7,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,9,5,9, +0,0,6,8,6,0,0,0,0,10,0,0,0,18,5,0,0,0,5,0,7,0,0,0,0,8,6,0,0,0,0,9,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,14,0,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,6,0,0,0,5,0, +0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,8,5,0,0,0,0,0,0,0,0,9,0,0,0,0,4,0,0,0,0,0,0,0,0, +0,0,0,0,20,5,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,9,5,0,0,0,0,0,0,8,4,24,0,0,0,0,0,0, +0,0,0,0,0,0,0,9,7,0,0,0,0,10,5,0,0,8,5,0,0,0,0,0,0,0,0,12,7,0,6,0,0,10,6,0,0,0, +0,14,0,0,4,9,5,0,0,0,0,0,0,9,0,0,0,0,0,0,6,0,0,0,0,0,4,0,0,8,0,0,0,0,0,11,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,8,5,11,7,0,4,0,0,10,0,0,0,0, +0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,11,6,0,0,0,0,0,5,14,6,0,0,0,0,10,0,0, +0,13,4,0,0,0,0,0,0,0,0,0,0,0,6,0,0,10,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,7,12,0,10,6,0,0,0,0,0,0,10,0,0,0,0,0,10,0,9, +7,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,4,0,7,0,0,0,0,9,7,0,0,0, +0,0,0,0,0,0,0,0,0,24,0,11,7,0,7,0,0,0,0,0,0,8,6,0,0,0,0,0,0,8,7,0,0,0,0,0,5,0,0, +0,6,9,0,0,0,23,5,0,0,0,0,0,6,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,7,0,0,0, +0,0,0,0,0,0,0,0,0,0,6,0,0,18,4,0,0,11,7,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6, +0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,9,0,0,0,11,0,0,0,23,0,0, +0,10,4,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,4,0,0,0,0,0,7,0,0,19,0,11,0,0,0,0,0,12,7,0, +0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,5,0,0,0,0,0,5,0,0,0,0,0,5,0,0,0,0,0,0,0,6,0,0, +9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,4,0,0,0,0,10,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,4,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,22,0,8,7,10,4,11,0,13,5,8,7,9,0,8,7,0,0,0,7,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0, +0,8,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,4,0,0,0,4,11,0,0,6,0,0,8,5,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,8,5,0,0, +20,0,0,0,0,0,0,0,0,0,11,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,7,0,0,14,0,0,0,9,0,13,7,0,0,0,0,0,6,0,7,0,0,8,6,10,6,0,0,8,6,0,0,0,6,0, +0,12,6,9,0,0,0,0,0,0,5,9,0,12,4,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,8,5,0,0,0,0,0, +0,0,4,8,0,0,6,8,0,0,0,0,0,0,0,0,0,13,6,0,7,0,0,0,0,0,6,8,7,8,6,0,0,0,7,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,18,0,11,4,0,0,0,5,0,0,0,0,0,0,0,0,0,0, +0,5,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,0,0,0,4,14, +6,0,0,0,0,12,7,8,0,0,0,0,0,0,0,8,7,0,0,0,0,10,4,0,0,0,0,0,0,10,0,0,6,0,0,0,0,0, +0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,15,6,9,7,0,0,0,0,0,0,15,6,11,7,0,0,0,7,0,0,21,0,0, +0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,17,6,0,0,10,5,0,5,0,0,0,0,0,0,0,0,0,7, +0,0,10,0,0,0,0,0,0,0,0,4,11,5,0,0,0,0,16,7,0,0,0,0,0,6,0,0,8,7,0,4,0,0,10,0,0,0, +0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,8,0,0,0,0,0,0,6,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,8,0,0,0,0, +0,0,0,10,4,0,0,0,0,0,0,0,0,0,6,0,5,0,0,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0, +0,7,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,6,10,7,0,0,0,0,0,0,0,0,8,4,0,0,10,0,0,0,0,4,0,6,0,6,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,0,0,0,7,0,0,0,7,17,0,0,0,0,0, +0,0,0,0,0,0,10,0,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +6,0,0,0,5,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,5,0,4,0,0,0,0,0,6,0,0,0,0,0,0,10,5,0,0, +0,5,0,0,0,0,9,0,19,7,0,0,0,0,0,7,0,0,0,0,10,6,0,0,0,6,0,5,0,0,0,0,0,0,0,0,0,6,8, +0,0,0,0,0,11,0,0,0,0,0,0,6,0,0,0,0,0,7,9,0,15,0,0,0,0,0,0,0,0,0,0,4,0,0,0,5,0,0, +0,0,0,0,0,6,0,0,0,0,0,0,0,4,0,0,0,0,9,0,0,0,0,0,0,0,0,6,0,7,0,0,0,0,0,0,0,6,0,0, +0,0,0,6,10,0,0,0,0,0,0,0,23,0,14,0,0,0,0,7,0,0,0,0,0,7,0,0,9,0,0,0,0,7,0,0,0,0, +0,6,0,0,14,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,6,0,0,0,4,0,0,0, +0,0,0,0,0,9,5,0,0,0,0,0,4,0,0,0,0,9,5,0,0,0,0,22,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,22,0,0,0,0,0,0,0,10,0,0,0,0,0,0,5,0,4,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,6,11,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,14,7,0,0,12,7,0,0,0, +0,0,0,0,0,0,4,0,0,0,0,0,6,0,0,0,0,8,6,10,0,0,0,0,0,0,0,0,0,10,7,8,5,0,0,0,0,0,0, +0,0,8,4,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,5,0,0,9,5,0,0,0,0,0,5,0,0,0,0,0,4,0,0,0, +0,0,0,0,0,0,0,12,4,11,0,0,0,9,0,11,7,0,0,0,0,0,0,10,6,0,0,0,6,0,0,0,0,15,5,0,0, +11,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,4,0,4,0,6,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,8,0,0,0,19,7,0,4,0,0,9,0,0,0,0,0,10,0, +0,6,0,0,13,0,12,6,0,0,0,0,0,0,0,0,10,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,13,7,10,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,6,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,4,9,0,0,0,10,0,0,0,0,0,0,0, +0,5,0,0,0,0,0,0,10,0,23,6,0,0,0,6,8,0,0,0,0,0,0,0,0,0,17,7,0,0,0,0,11,6,22,5,0, +0,9,6,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,5,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,4,11,0,9,4,0,0, +0,7,0,7,0,0,0,0,0,0,12,4,0,0,0,0,0,0,0,0,0,0,0,0,11,4,0,0,0,0,0,0,0,0,0,0,0,0,0, +4,0,0,11,5,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,8,6,0,0,0,4,0,0,0,0, +0,0,0,0,0,7,0,0,0,4,0,0,10,4,0,0,0,0,0,0,0,7,0,7,0,0,0,6,0,0,0,0,8,6,0,6,0,6,0, +0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,0,0,0,0,9,5,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,6,22,6,12,0,0,6,0,0,0,6,0,0,0,0,0,7,0,0,0,0,11,0,0,0, +9,7,0,0,0,0,0,4,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, +0,0,0,6,0,0,0,6,0,6,0,0,8,7,0,0,0,4,9,7,19,0,0,0,0,0,0,0,0,0,9,6,10,6,0,6,0,0,0, +4,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,6,16,7,10,6,0,0,23,6,11,7,0,4,0,0,0,0,0,0,0,0,0, +5,0,0,0,0,10,7,0,0,0,0,0,7,0,0,0,0,0,0,15,0,10,0,0,0,14,6,0,0,0,0,0,0,0,0,0,0,0, +5,0,0,0,0,0,0,0,5,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,5,0,0,11,5,0,0,0,0,0,0,0,0,0,0, +0,4,0,0,0,0,0,6,0,0,10,0,0,0,0,7,0,0,0,0,0,0,10,6,0,0,0,0,8,4,0,0,0,7,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,7,12,5,0,0,0,0, +0,6,0,0,0,0,9,6,0,0,0,0,0,0,0,6,9,0,0,0,0,6,0,0,0,0,8,7,0,0,0,0,0,0,0,6,0,0,0,0, +0,0,0,0,0,0,10,5,0,0,0,0,0,0,8,6,0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,8,5,0,0,0,0,0,7,0,7,0,4,0,0,10,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,5,0,0,0,0,13, +7,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,7,0,0,13,0,0,0,0,0,0,0,0,7,10,5,0,0,0,0,0,0,9,7,0,0,8,6,9, +5,0,0,0,0,0,6,12,0,0,0,0,0,0,0,18,6,0,0,0,0,0,0,0,0,19,7,0,4,0,0,0,0,9,5,0,5,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,7,0,0,0,0,0,0,14,0,0,0,23,7,8,7,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,22,0,0,7,0,0,0,0,0,0,0,0,9,7,8,4,0, +0,0,0,0,0,0,0,8,5,0,6,0,0,0,0,0,6,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0, +8,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,12,5,0,0,0,0,0,0,0,0,0,0,8,6,0,0,11,7,0,0,0, +0,12,0,8,6,19,7,0,0,0,0,0,0,0,0,0,0,0,0,0,6,11,0,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,11,7,0,0,0,0,0,4,10,0,0,0,0,0,0,0,8,7,0,0,0,0,14,0,8,0,0,6,10,0,0, +0,0,0,0,0,12,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,6,0,0,0,0, +0,0,0,0,13,0,0,0,0,0,0,0,11,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0, +0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,5,0,0,0,6,0,0,0,5,0,7,0,0,0, +0,0,6,0,0,21,7,0,0,9,6,0,0,0,6,0,0,13,7,0,0,0,5,0,0,0,0,0,4,0,6,0,0,0,0,0,0,0,0, +0,0,0,4,0,0,0,0,0,0,11,5,0,6,0,0,10,5,0,0,0,0,0,0,0,0,9,6,0,0,8,7,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,9,0,0,0,0,0,0,6,0,0,0,0,15,4,0,0,12,7,0,0,0,6, +0,7,0,0,8,0,9,5,0,4,0,0,0,6,0,6,0,0,23,4,0,0,0,0,0,0,0,0,0,0,0,0,10,7,0,4,0,0,8, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,0,0,0,0,0,0, +7,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,12,6,0,0,0,0,0,0,10,7,0,7,0,0,0,0,0,0,0,0,0,0, +9,0,0,0,0,0,8,0,0,0,0,4,0,0,0,0,0,0,0,0,0,4,11,5,0,0,0,6,0,6,0,0,0,0,0,0,0,6,0, +4,0,0,0,0,0,0,0,0,0,0,0,5,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,8,7,0,0,0,6,0,6,0, +0,0,0,0,0,0,0,0,5,0,0,0,0,0,5,0,0,0,0,11,0,0,0,0,0,0,0,10,5,9,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,8,0,23,7,0,0,0,0,0,7,0,0,10,6,18,0,0,0, +0,0,0,0,8,7,0,6,0,0,0,0,0,0,8,5,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0, +0,0,0,0,0,6,0,0,0,4,12,7,0,0,0,0,0,0,0,0,10,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,13,5,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,4,0,0,0,0,0,0,0,0, +11,7,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0, +0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,10,0,11,0,0,0,0,0,0,0,0,0, +17,5,0,4,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,4,0,0,0,0,8,7,0,0,0,0,0,0,0, +0,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,0, +10,0,0,0,8,6,0,0,0,7,0,0,0,0,0,0,8,0,0,0,14,0,0,0,0,7,0,0,0,4,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,9,4,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0, +10,0,0,0,16,5,0,0,0,0,0,0,8,0,0,4,0,0,0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,10,0,0,0, +0,0,0,0,0,5,0,0,0,0,12,5,0,7,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,7,0, +0,0,0,0,0,0,0,12,6,0,0,0,0,0,7,0,6,0,6,12,6,0,0,0,0,0,0,0,4,8,7,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,20,0,0,0,0,6,0,6,0,0,0,0,0,0,0,0,10,6,8,0,0, +6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +16,0,8,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,23,5,0,0,0,7,0,6,0, +0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,9,5,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,0,0,10,0,0,0,14,0,0,0,0,7,0,0,0,4,17,5,0,0,0,0,11,0,9,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,6,0,0,0,5,0,7,0,0,0,0,0,0,0,0,8,0,0,0, +12,6,0,0,0,0,0,0,13,0,0,0,0,7,9,0,0,0,0,0,0,0,0,0,0,5,0,0,0,7,10,7,12,0,0,0,9,0, +0,0,14,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,15,6,0,0,23,0,0,7,0,6,0,0,0,7,0,6, +0,0,0,0,0,0,0,6,0,6,9,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,8,7,9,4,0,0,10,0,0,0,10, +6,0,7,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,23,0,0,6,0,0,0,0,0,0,9,4, +0,0,10,7,0,0,0,0,0,0,0,0,0,0,0,0,9,7,0,0,9,6,0,0,0,0,8,6,0,0,0,0,0,0,0,0,12,0,0, +0,0,0,8,0,0,6,11,6,0,0,8,7,8,5,0,0,0,0,0,5,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0, +10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0, +7,0,0,0,0,9,6,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,8,0,0,0,0,6,12,5,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,10,0,10, +7,0,0,8,0,0,0,0,4,0,0,0,6,0,0,0,6,0,0,0,6,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,5,0, +0,0,4,0,0,0,0,0,4,0,0,0,0,0,0,0,6,0,6,0,5,0,0,0,0,8,0,0,0,10,7,0,0,0,0,10,0,0,0, +0,0,13,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,19,7,0,4,12,0,8,0,0,0,0,6,0,0,0,0, +0,0,0,6,0,0,0,0,0,0,0,0,0,4,0,0,0,0,18,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0, +0,14,0,0,4,0,0,0,6,0,0,0,6,0,0,0,7,0,0,0,0,0,0,10,4,0,0,9,7,0,0,11,0,0,0,0,0,0, +7,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,4,0,0,12,0,0,0, +0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,22,5,9,7,0,0,0,0,0,0,0,0,0, +0,0,6,0,0,9,6,0,5,0,0,0,0,0,0,10,5,0,0,8,6,0,6,10,5,0,0,0,6,0,0,0,6,0,0,20,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,9,0,0,0,0,6,0,0,0,0,17,4,0,7,0,6, +0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10, +0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,0, +0,0,7,0,0,8,6,12,0,0,7,18,7,0,0,8,4,0,0,0,0,9,6,0,0,0,0,0,0,0,0,13,0,0,6,0,0,0, +0,0,0,0,0,0,0,10,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,7,0,0, +0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,8,5,0,0,0,0,0,0,0,0,12,0,0,0,8,0,0,0,0,0,0, +4,0,0,10,0,16,0,0,0,0,0,0,0,12,7,10,7,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,0,0,0,0,0,0,0,0,0,0,0,6,16,6,10,0,0,5,0,0,0,0,0,6,0,0,0,0, +0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,5,8,7,0,7,0,0,0,0,0,0,0,0,8,0,0,6,0,0,0,6,0,0,0,4,0,0,0,0, +8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,7,0,0,8,0,0,0, +9,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,7,13,5,0,5,0,0,0,7,8,4,0,0,0,0,0,0,0, +0,12,0,0,0,0,0,0,0,0,0,0,0,8,6,0,6,0,0,11,0,0,0,0,0,0,0,0,6,0,0,0,0,0,4,0,0,0,0, +0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,10,7,0,4,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,0,0,0,0,0,0,0,0,0,0,9,0,11,6,0,0,10,6,0,0, +0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6, +0,0,0,6,0,0,0,7,0,0,9,0,8,7,11,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,9,6,10,5,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,10,7,0,0,0,0,0,0,11,0,9,6,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,5,0,6,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,15,5,12,5, +0,0,0,0,0,0,12,7,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,12,6,0, +0,0,0,24,4,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,0,0,0,0, +0,0,0,4,10,4,0,0,0,0,10,7,0,0,0,0,0,0,0,0,0,0,0,0,9,0,11,0,0,0,0,0,0,0,0,0,0,6, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5, +0,0,8,0,0,0,0,7,0,0,0,0,0,0,10,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,10,7,0,0,0,0,0, +0,0,0,0,0,14,7,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,0,0,6,0,0,0,6,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,11,6,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,7,20,7,11,4,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,7,9,6,0,0,12,7,0,0,0,0,0,0,10,0,12,0, +0,0,0,0,0,4,9,6,13,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,5,0,0,0,0,0,0,8,0,0,0,0,0,0, +0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,6,0,0,11,0,9,0,0,0,0,4,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,8,5,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0, +0,4,0,5,0,0,0,0,0,0,0,0,0,4,0,0,0,0,9,7,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0, +0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,6, +0,0,0,0,8,7,0,0,0,0,0,0,12,0,0,6,0,0,0,0,0,0,0,6,8,4,0,0,10,7,0,0,10,0,0,0,0,0, +0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,7,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,4,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,7,0,0,0,0,0,0,0,5, +0,4,0,0,0,0,0,6,0,0,0,0,0,0,8,0,0,6,0,0,0,6,0,0,0,0,0,7,0,5,8,4,0,0,9,0,0,0,0,4, +0,0,0,0,0,0,0,0,0,5,0,0,15,6,8,6,0,0,0,6,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,9,6,0,0,0,0,0,0,0,7,0,0,0,4,0, +6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,9,5,0,6,12,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,6,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,8,7,0,6,0,0,0,0,0,0,0,0,0,0,0,0,11,0,12,7,0,0,0,0, +0,0,0,0,0,5,0,5,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,11,4,0,0,0,0,0,0,0,0,0,0,10, +7,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,7,8,7,9,6,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,5,12,0, +10,5,12,6,0,0,0,7,0,0,0,0,0,0,0,5,0,0,0,5,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7, +11,7,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,0,6,0,7,0,0,0,0,8,0,8,5,0,6,0,0,0,6,0,0,0, +0,0,0,0,6,0,6,0,6,9,0,0,5,17,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,7,0,0, +0,0,0,7,0,0,0,0,16,5,0,0,0,0,0,0,0,4,0,0,0,5,11,5,0,7,0,0,0,4,8,7,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,7,0,0,0,0,12,0,0,0, +0,0,12,0,0,0,0,0,0,0,0,4,10,4,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,6,0,0,0,0,0,0,0,4,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,20,5,0,0, +10,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,12,0,0,0,0,0,0,6,0,0,0,0,0,0,9,4,10,7,0,4,0,0, +0,0,0,0,10,6,0,0,0,0,8,4,0,7,8,6,0,6,8,0,10,0,0,0,0,0,13,5,0,6,0,0,0,0,0,0,22,4, +0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,6,10, +5,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,10,4,0,0,10,7,0,0,0,0,0,5,0, +5,8,0,0,0,0,6,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,10,7,0,0,0,4,0,0,0,0,0,6,0,0, +0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,7,0,0,0,6,0,0,0,0,0,0,0,0,0, +4,0,0,0,4,10,0,0,6,13,7,8,0,0,0,0,0,0,7,0,0,12,7,0,0,0,0,0,0,10,5,0,0,0,0,0,6,0, +0,0,0,0,0,0,0,0,0,13,7,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,0,8,6,0,6, +0,0,0,0,0,0,0,0,12,0,8,4,0,0,0,0,0,4,0,4,0,0,0,0,0,0,0,5,0,0,0,0,12,5,0,0,0,7,0, +0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,10,0,0,0,20,0,0,5,0,0,10, +7,11,7,0,0,0,0,0,0,0,0,0,0,17,0,9,4,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,0,0,0,0,0,0,0,5,0,0,10,7,0,4,0,6,0,0,24,0,0,5,0,0,0,0,8,0,0, +0,0,0,0,0,10,5,0,4,0,6,0,0,8,0,0,0,0,0,0,4,0,6,0,0,0,0,0,0,9,5,0,0,0,0,0,0,0,0, +0,0,0,6,0,0,0,0,9,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,4,0,7, +0,0,13,0,0,0,0,0,0,0,11,6,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0, +17,7,0,0,11,6,0,0,0,0,12,6,0,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,5,0,0,0,6,0,0,0,0,0,0,0,0,0,0,10,0,0,4,8,6,0,0,0, +0,0,0,9,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,9,5,0,7,18,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,8,0,0,0, +0,0,0,0,0,5,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,6,0,0,0,0,0,0, +0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,4,0,6,0,0,9,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,0, +0,0,0,8,7,10,0,8,5,0,0,0,0,0,0,0,0,9,0,0,0,10,0,0,0,0,6,0,7,0,4,0,0,0,0,0,0,0,0, +8,0,0,0,0,0,8,4,0,0,0,0,0,5,0,0,10,0,12,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +4,0,0,0,0,0,0,12,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,18,6,11,0,0, +7,0,0,0,0,0,6,10,5,0,0,0,0,0,0,0,0,0,5,0,0,9,5,12,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,6,0,0,0,0,13,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0, +0,0,0,8,4,0,6,12,0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,11,4,0,0,0,6,14,0,11,0,9,6,0,0,0,0,0,0,22,0,12,0,8,6,0,0,0,0,0,0,0,6,0, +0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0, +10,7,0,0,0,0,0,0,0,0,9,0,0,0,0,4,0,0,0,0,0,0,0,0,0,5,11,0,0,0,0,0,0,0,8,6,0,0,9, +7,0,0,12,4,0,0,0,0,0,0,12,6,0,6,0,7,0,0,8,5,0,0,0,0}; #if defined(__cplusplus) || defined(c_plusplus) } /* extern "C" */ diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/dictionary_hash.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/dictionary_hash.h index b3bb9599f43..e553ea5d4ef 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/dictionary_hash.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/dictionary_hash.h @@ -15,7 +15,8 @@ extern "C" { #endif -extern const uint16_t kStaticDictionaryHash[32768]; +extern const uint16_t kStaticDictionaryHashWords[32768]; +extern const uint8_t kStaticDictionaryHashLengths[32768]; #if defined(__cplusplus) || defined(c_plusplus) } /* extern "C" */ diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/encode.c b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/encode.c index 141e70aa2a3..8d90937b436 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/encode.c +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/encode.c @@ -54,12 +54,19 @@ typedef enum BrotliEncoderStreamState { BROTLI_STREAM_METADATA_BODY = 4 } BrotliEncoderStreamState; +typedef enum BrotliEncoderFlintState { + BROTLI_FLINT_NEEDS_2_BYTES = 2, + BROTLI_FLINT_NEEDS_1_BYTE = 1, + BROTLI_FLINT_WAITING_FOR_PROCESSING = 0, + BROTLI_FLINT_WAITING_FOR_FLUSHING = -1, + BROTLI_FLINT_DONE = -2 +} BrotliEncoderFlintState; + typedef struct BrotliEncoderStateStruct { BrotliEncoderParams params; MemoryManager memory_manager_; - HasherHandle hasher_; uint64_t input_pos_; RingBuffer ringbuffer_; size_t cmd_alloc_size_; @@ -73,10 +80,17 @@ typedef struct BrotliEncoderStateStruct { int saved_dist_cache_[4]; uint16_t last_bytes_; uint8_t last_bytes_bits_; + /* "Flint" is a tiny uncompressed block emitted before the continuation + block to unwire literal context from previous data. Despite being int8_t, + field is actually BrotliEncoderFlintState enum. */ + int8_t flint_; uint8_t prev_byte_; uint8_t prev_byte2_; size_t storage_size_; uint8_t* storage_; + + Hasher hasher_; + /* Hash table for FAST_ONE_PASS_COMPRESSION_QUALITY mode. */ int small_table_[1 << 10]; /* 4KiB */ int* large_table_; /* Allocated only when needed */ @@ -114,8 +128,6 @@ typedef struct BrotliEncoderStateStruct { BROTLI_BOOL is_initialized_; } BrotliEncoderStateStruct; -static BROTLI_BOOL EnsureInitialized(BrotliEncoderState* s); - static size_t InputBlockSize(BrotliEncoderState* s) { return (size_t)1 << s->params.lgblock; } @@ -174,6 +186,11 @@ BROTLI_BOOL BrotliEncoderSetParameter( state->params.dist.num_direct_distance_codes = value; return BROTLI_TRUE; + case BROTLI_PARAM_STREAM_OFFSET: + if (value > (1u << 30)) return BROTLI_FALSE; + state->params.stream_offset = value; + return BROTLI_TRUE; + default: return BROTLI_FALSE; } } @@ -195,7 +212,7 @@ static uint8_t* GetBrotliStorage(BrotliEncoderState* s, size_t size) { if (s->storage_size_ < size) { BROTLI_FREE(m, s->storage_); s->storage_ = BROTLI_ALLOC(m, uint8_t, size); - if (BROTLI_IS_OOM(m)) return NULL; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(s->storage_)) return NULL; s->storage_size_ = size; } return s->storage_; @@ -234,7 +251,7 @@ static int* GetHashTable(BrotliEncoderState* s, int quality, s->large_table_size_ = htsize; BROTLI_FREE(m, s->large_table_); s->large_table_ = BROTLI_ALLOC(m, int, htsize); - if (BROTLI_IS_OOM(m)) return 0; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(s->large_table_)) return 0; } table = s->large_table_; } @@ -499,7 +516,7 @@ static BROTLI_BOOL ShouldCompress( /* TODO: find more precise minimal block overhead. */ if (bytes <= 2) return BROTLI_FALSE; if (num_commands < (bytes >> 8) + 2) { - if (num_literals > 0.99 * (double)bytes) { + if ((double)num_literals > 0.99 * (double)bytes) { uint32_t literal_histo[256] = { 0 }; static const uint32_t kSampleRate = 13; static const double kMinEntropy = 7.92; @@ -617,11 +634,7 @@ static void WriteMetaBlockInternal(MemoryManager* m, /* The number of distance symbols effectively used for distance histograms. It might be less than distance alphabet size for "Large Window Brotli" (32-bit). */ - uint32_t num_effective_dist_codes = block_params.dist.alphabet_size; - if (num_effective_dist_codes > BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS) { - num_effective_dist_codes = BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS; - } - BrotliOptimizeHistograms(num_effective_dist_codes, &mb); + BrotliOptimizeHistograms(block_params.dist.alphabet_size_limit, &mb); } BrotliStoreMetaBlock(m, data, wrapped_last_flush_pos, bytes, mask, prev_byte, prev_byte2, @@ -678,12 +691,23 @@ static BROTLI_BOOL EnsureInitialized(BrotliEncoderState* s) { s->last_bytes_bits_ = 0; s->last_bytes_ = 0; + s->flint_ = BROTLI_FLINT_DONE; s->remaining_metadata_bytes_ = BROTLI_UINT32_MAX; SanitizeParams(&s->params); s->params.lgblock = ComputeLgBlock(&s->params); ChooseDistanceParams(&s->params); + if (s->params.stream_offset != 0) { + s->flint_ = BROTLI_FLINT_NEEDS_2_BYTES; + /* Poison the distance cache. -16 +- 3 is still less than zero (invalid). */ + s->dist_cache_[0] = -16; + s->dist_cache_[1] = -16; + s->dist_cache_[2] = -16; + s->dist_cache_[3] = -16; + memcpy(s->saved_dist_cache_, s->dist_cache_, sizeof(s->saved_dist_cache_)); + } + RingBufferSetup(&s->params, &s->ringbuffer_); /* Initialize last byte with stream header. */ @@ -693,8 +717,14 @@ static BROTLI_BOOL EnsureInitialized(BrotliEncoderState* s) { s->params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY) { lgwin = BROTLI_MAX(int, lgwin, 18); } - EncodeWindowBits(lgwin, s->params.large_window, - &s->last_bytes_, &s->last_bytes_bits_); + if (s->params.stream_offset == 0) { + EncodeWindowBits(lgwin, s->params.large_window, + &s->last_bytes_, &s->last_bytes_bits_); + } else { + /* Bigger values have the same effect, but could cause overflows. */ + s->params.stream_offset = BROTLI_MIN(size_t, + s->params.stream_offset, BROTLI_MAX_BACKWARD_LIMIT(lgwin)); + } } if (s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY) { @@ -712,13 +742,15 @@ static void BrotliEncoderInitParams(BrotliEncoderParams* params) { params->quality = BROTLI_DEFAULT_QUALITY; params->lgwin = BROTLI_DEFAULT_WINDOW; params->lgblock = 0; + params->stream_offset = 0; params->size_hint = 0; params->disable_literal_context_modeling = BROTLI_FALSE; BrotliInitEncoderDictionary(¶ms->dictionary); params->dist.distance_postfix_bits = 0; params->dist.num_direct_distance_codes = 0; - params->dist.alphabet_size = + params->dist.alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE(0, 0, BROTLI_MAX_DISTANCE_BITS); + params->dist.alphabet_size_limit = params->dist.alphabet_size_max; params->dist.max_distance = BROTLI_MAX_DISTANCE; } @@ -734,7 +766,7 @@ static void BrotliEncoderInitState(BrotliEncoderState* s) { s->prev_byte2_ = 0; s->storage_size_ = 0; s->storage_ = 0; - s->hasher_ = NULL; + HasherInit(&s->hasher_); s->large_table_ = NULL; s->large_table_size_ = 0; s->cmd_code_numbits_ = 0; @@ -902,6 +934,7 @@ static void ExtendLastCommand(BrotliEncoderState* s, uint32_t* bytes, (*bytes)--; (*wrapped_last_processed_pos)++; } + } else { } /* The copy length is at most the metablock size, and thus expressible. */ GetLengthCode(last_command->insert_len_, @@ -934,6 +967,7 @@ static BROTLI_BOOL EncodeData( uint32_t mask; MemoryManager* m = &s->memory_manager_; ContextType literal_context_mode; + ContextLut literal_context_lut; data = s->ringbuffer_.buffer_; mask = s->ringbuffer_.mask_; @@ -951,7 +985,10 @@ static BROTLI_BOOL EncodeData( BROTLI_ALLOC(m, uint32_t, kCompressFragmentTwoPassBlockSize); s->literal_buf_ = BROTLI_ALLOC(m, uint8_t, kCompressFragmentTwoPassBlockSize); - if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(s->command_buf_) || + BROTLI_IS_NULL(s->literal_buf_)) { + return BROTLI_FALSE; + } } if (s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY || @@ -1009,7 +1046,7 @@ static BROTLI_BOOL EncodeData( newsize += (bytes / 4) + 16; s->cmd_alloc_size_ = newsize; new_commands = BROTLI_ALLOC(m, Command, newsize); - if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(new_commands)) return BROTLI_FALSE; if (s->commands_) { memcpy(new_commands, s->commands_, sizeof(Command) * s->num_commands_); BROTLI_FREE(m, s->commands_); @@ -1024,6 +1061,7 @@ static BROTLI_BOOL EncodeData( literal_context_mode = ChooseContextMode( &s->params, data, WrapPosition(s->last_flush_pos_), mask, (size_t)(s->input_pos_ - s->last_flush_pos_)); + literal_context_lut = BROTLI_CONTEXT_LUT(literal_context_mode); if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; @@ -1034,20 +1072,23 @@ static BROTLI_BOOL EncodeData( if (s->params.quality == ZOPFLIFICATION_QUALITY) { BROTLI_DCHECK(s->params.hasher.type == 10); BrotliCreateZopfliBackwardReferences(m, bytes, wrapped_last_processed_pos, - data, mask, &s->params, s->hasher_, s->dist_cache_, + data, mask, literal_context_lut, &s->params, + &s->hasher_, s->dist_cache_, &s->last_insert_len_, &s->commands_[s->num_commands_], &s->num_commands_, &s->num_literals_); if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; } else if (s->params.quality == HQ_ZOPFLIFICATION_QUALITY) { BROTLI_DCHECK(s->params.hasher.type == 10); BrotliCreateHqZopfliBackwardReferences(m, bytes, wrapped_last_processed_pos, - data, mask, &s->params, s->hasher_, s->dist_cache_, + data, mask, literal_context_lut, &s->params, + &s->hasher_, s->dist_cache_, &s->last_insert_len_, &s->commands_[s->num_commands_], &s->num_commands_, &s->num_literals_); if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; } else { BrotliCreateBackwardReferences(bytes, wrapped_last_processed_pos, - data, mask, &s->params, s->hasher_, s->dist_cache_, + data, mask, literal_context_lut, &s->params, + &s->hasher_, s->dist_cache_, &s->last_insert_len_, &s->commands_[s->num_commands_], &s->num_commands_, &s->num_literals_); } @@ -1072,7 +1113,7 @@ static BROTLI_BOOL EncodeData( s->num_commands_ < max_commands) { /* Merge with next input block. Everything will happen later. */ if (UpdateLastProcessedPos(s)) { - HasherReset(s->hasher_); + HasherReset(&s->hasher_); } *out_size = 0; return BROTLI_TRUE; @@ -1113,7 +1154,7 @@ static BROTLI_BOOL EncodeData( s->last_bytes_bits_ = storage_ix & 7u; s->last_flush_pos_ = s->input_pos_; if (UpdateLastProcessedPos(s)) { - HasherReset(s->hasher_); + HasherReset(&s->hasher_); } if (s->last_flush_pos_ > 0) { s->prev_byte_ = data[((uint32_t)s->last_flush_pos_ - 1) & mask]; @@ -1174,7 +1215,6 @@ static BROTLI_BOOL BrotliCompressBufferQuality10( size_t total_out_size = 0; uint16_t last_bytes; uint8_t last_bytes_bits; - HasherHandle hasher = NULL; const size_t hasher_eff_size = BROTLI_MIN(size_t, input_size, BROTLI_MAX_BACKWARD_LIMIT(lgwin) + BROTLI_WINDOW_GAP); @@ -1190,6 +1230,9 @@ static BROTLI_BOOL BrotliCompressBufferQuality10( uint8_t prev_byte = 0; uint8_t prev_byte2 = 0; + Hasher hasher; + HasherInit(&hasher); + BrotliEncoderInitParams(¶ms); params.quality = 10; params.lgwin = lgwin; @@ -1226,6 +1269,7 @@ static BROTLI_BOOL BrotliCompressBufferQuality10( ContextType literal_context_mode = ChooseContextMode(¶ms, input_buffer, metablock_start, mask, metablock_end - metablock_start); + ContextLut literal_context_lut = BROTLI_CONTEXT_LUT(literal_context_mode); size_t block_start; for (block_start = metablock_start; block_start < metablock_end; ) { @@ -1234,12 +1278,12 @@ static BROTLI_BOOL BrotliCompressBufferQuality10( ZopfliNode* nodes = BROTLI_ALLOC(m, ZopfliNode, block_size + 1); size_t path_size; size_t new_cmd_alloc_size; - if (BROTLI_IS_OOM(m)) goto oom; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(nodes)) goto oom; BrotliInitZopfliNodes(nodes, block_size + 1); - StitchToPreviousBlockH10(hasher, block_size, block_start, + StitchToPreviousBlockH10(&hasher.privat._H10, block_size, block_start, input_buffer, mask); path_size = BrotliZopfliComputeShortestPath(m, block_size, block_start, - input_buffer, mask, ¶ms, dist_cache, hasher, + input_buffer, mask, literal_context_lut, ¶ms, dist_cache, &hasher, nodes); if (BROTLI_IS_OOM(m)) goto oom; /* We allocate a command buffer in the first iteration of this loop that @@ -1254,7 +1298,7 @@ static BROTLI_BOOL BrotliCompressBufferQuality10( num_commands + path_size + 1); if (cmd_alloc_size != new_cmd_alloc_size) { Command* new_commands = BROTLI_ALLOC(m, Command, new_cmd_alloc_size); - if (BROTLI_IS_OOM(m)) goto oom; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(new_commands)) goto oom; cmd_alloc_size = new_cmd_alloc_size; if (commands) { memcpy(new_commands, commands, sizeof(Command) * num_commands); @@ -1286,7 +1330,7 @@ static BROTLI_BOOL BrotliCompressBufferQuality10( if (metablock_size == 0) { /* Write the ISLAST and ISEMPTY bits. */ storage = BROTLI_ALLOC(m, uint8_t, 16); - if (BROTLI_IS_OOM(m)) goto oom; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(storage)) goto oom; storage[0] = (uint8_t)last_bytes; storage[1] = (uint8_t)(last_bytes >> 8); BrotliWriteBits(2, 3, &storage_ix, storage); @@ -1297,7 +1341,7 @@ static BROTLI_BOOL BrotliCompressBufferQuality10( CreateBackwardReferences is now unused. */ memcpy(dist_cache, saved_dist_cache, 4 * sizeof(dist_cache[0])); storage = BROTLI_ALLOC(m, uint8_t, metablock_size + 16); - if (BROTLI_IS_OOM(m)) goto oom; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(storage)) goto oom; storage[0] = (uint8_t)last_bytes; storage[1] = (uint8_t)(last_bytes >> 8); BrotliStoreUncompressedMetaBlock(is_last, input_buffer, @@ -1318,14 +1362,10 @@ static BROTLI_BOOL BrotliCompressBufferQuality10( /* The number of distance symbols effectively used for distance histograms. It might be less than distance alphabet size for "Large Window Brotli" (32-bit). */ - uint32_t num_effective_dist_codes = block_params.dist.alphabet_size; - if (num_effective_dist_codes > BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS) { - num_effective_dist_codes = BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS; - } - BrotliOptimizeHistograms(num_effective_dist_codes, &mb); + BrotliOptimizeHistograms(block_params.dist.alphabet_size_limit, &mb); } storage = BROTLI_ALLOC(m, uint8_t, 2 * metablock_size + 503); - if (BROTLI_IS_OOM(m)) goto oom; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(storage)) goto oom; storage[0] = (uint8_t)last_bytes; storage[1] = (uint8_t)(last_bytes >> 8); BrotliStoreMetaBlock(m, input_buffer, metablock_start, metablock_size, @@ -1576,7 +1616,10 @@ static BROTLI_BOOL BrotliEncoderCompressStreamFast( BROTLI_ALLOC(m, uint32_t, kCompressFragmentTwoPassBlockSize); s->literal_buf_ = BROTLI_ALLOC(m, uint8_t, kCompressFragmentTwoPassBlockSize); - if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(s->command_buf_) || + BROTLI_IS_NULL(s->literal_buf_)) { + return BROTLI_FALSE; + } } if (s->command_buf_) { command_buf = s->command_buf_; @@ -1584,7 +1627,10 @@ static BROTLI_BOOL BrotliEncoderCompressStreamFast( } else { tmp_command_buf = BROTLI_ALLOC(m, uint32_t, buf_size); tmp_literal_buf = BROTLI_ALLOC(m, uint8_t, buf_size); - if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(tmp_command_buf) || + BROTLI_IS_NULL(tmp_literal_buf)) { + return BROTLI_FALSE; + } command_buf = tmp_command_buf; literal_buf = tmp_literal_buf; } @@ -1640,8 +1686,10 @@ static BROTLI_BOOL BrotliEncoderCompressStreamFast( &storage_ix, storage); if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; } - *next_in += block_size; - *available_in -= block_size; + if (block_size != 0) { + *next_in += block_size; + *available_in -= block_size; + } if (inplace) { size_t out_bytes = storage_ix >> 3; BROTLI_DCHECK(out_bytes <= *available_out); @@ -1786,6 +1834,10 @@ BROTLI_BOOL BrotliEncoderCompressStream( } while (BROTLI_TRUE) { size_t remaining_block_size = RemainingInputBlockSize(s); + /* Shorten input to flint size. */ + if (s->flint_ >= 0 && remaining_block_size > (size_t)s->flint_) { + remaining_block_size = (size_t)s->flint_; + } if (remaining_block_size != 0 && *available_in != 0) { size_t copy_input_size = @@ -1793,10 +1845,18 @@ BROTLI_BOOL BrotliEncoderCompressStream( CopyInputToRingBuffer(s, copy_input_size, *next_in); *next_in += copy_input_size; *available_in -= copy_input_size; + if (s->flint_ > 0) s->flint_ = (int8_t)(s->flint_ - (int)copy_input_size); continue; } if (InjectFlushOrPushOutput(s, available_out, next_out, total_out)) { + /* Exit the "emit flint" workflow. */ + if (s->flint_ == BROTLI_FLINT_WAITING_FOR_FLUSHING) { + CheckFlushComplete(s); + if (s->stream_state_ == BROTLI_STREAM_PROCESSING) { + s->flint_ = BROTLI_FLINT_DONE; + } + } continue; } @@ -1810,6 +1870,11 @@ BROTLI_BOOL BrotliEncoderCompressStream( BROTLI_BOOL force_flush = TO_BROTLI_BOOL( (*available_in == 0) && op == BROTLI_OPERATION_FLUSH); BROTLI_BOOL result; + /* Force emitting (uncompressed) piece containing flint. */ + if (!is_last && s->flint_ == 0) { + s->flint_ = BROTLI_FLINT_WAITING_FOR_FLUSHING; + force_flush = BROTLI_TRUE; + } UpdateSizeHint(s, *available_in); result = EncodeData(s, is_last, force_flush, &s->available_out_, &s->next_out_); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/encoder_dict.c b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/encoder_dict.c index 8b2f6ad4a47..c9e963b89d2 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/encoder_dict.c +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/encoder_dict.c @@ -17,14 +17,15 @@ extern "C" { void BrotliInitEncoderDictionary(BrotliEncoderDictionary* dict) { dict->words = BrotliGetDictionary(); + dict->num_transforms = (uint32_t)BrotliGetTransforms()->num_transforms; - dict->hash_table = kStaticDictionaryHash; + dict->hash_table_words = kStaticDictionaryHashWords; + dict->hash_table_lengths = kStaticDictionaryHashLengths; dict->buckets = kStaticDictionaryBuckets; dict->dict_words = kStaticDictionaryWords; dict->cutoffTransformsCount = kCutoffTransformsCount; dict->cutoffTransforms = kCutoffTransforms; - } #if defined(__cplusplus) || defined(c_plusplus) diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/encoder_dict.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/encoder_dict.h index 3cb6b0ac152..a1c329fbf49 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/encoder_dict.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/encoder_dict.h @@ -19,13 +19,15 @@ extern "C" { /* Dictionary data (words and transforms) for 1 possible context */ typedef struct BrotliEncoderDictionary { const BrotliDictionary* words; + uint32_t num_transforms; /* cut off for fast encoder */ uint32_t cutoffTransformsCount; uint64_t cutoffTransforms; /* from dictionary_hash.h, for fast encoder */ - const uint16_t* hash_table; + const uint16_t* hash_table_words; + const uint8_t* hash_table_lengths; /* from static_dict_lut.h, for slow encoder */ const uint16_t* buckets; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/entropy_encode.c b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/entropy_encode.c index 97f9dfb82aa..b50ccb5d1f6 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/entropy_encode.c +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/entropy_encode.c @@ -18,6 +18,8 @@ extern "C" { #endif +const size_t kBrotliShellGaps[] = {132, 57, 23, 10, 4, 1}; + BROTLI_BOOL BrotliSetDepth( int p0, HuffmanTree* pool, uint8_t* depth, int max_depth) { int stack[16]; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/entropy_encode.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/entropy_encode.h index f23d9c379d0..9618e1d3592 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/entropy_encode.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/entropy_encode.h @@ -76,12 +76,12 @@ BROTLI_INTERNAL void BrotliConvertBitDepthsToSymbols(const uint8_t* depth, size_t len, uint16_t* bits); +BROTLI_INTERNAL extern const size_t kBrotliShellGaps[6]; /* Input size optimized Shell sort. */ typedef BROTLI_BOOL (*HuffmanTreeComparator)( const HuffmanTree*, const HuffmanTree*); static BROTLI_INLINE void SortHuffmanTreeItems(HuffmanTree* items, const size_t n, HuffmanTreeComparator comparator) { - static const size_t gaps[] = {132, 57, 23, 10, 4, 1}; if (n < 13) { /* Insertion sort. */ size_t i; @@ -101,7 +101,7 @@ static BROTLI_INLINE void SortHuffmanTreeItems(HuffmanTree* items, /* Shell sort. */ int g = n < 57 ? 2 : 0; for (; g < 6; ++g) { - size_t gap = gaps[g]; + size_t gap = kBrotliShellGaps[g]; size_t i; for (i = gap; i < n; ++i) { size_t j = i; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/fast_log.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/fast_log.h index cade1235ade..2094f13e556 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/fast_log.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/fast_log.h @@ -19,10 +19,8 @@ extern "C" { #endif static BROTLI_INLINE uint32_t Log2FloorNonZero(size_t n) { - /* TODO: generalize and move to platform.h */ -#if BROTLI_GNUC_HAS_BUILTIN(__builtin_clz, 3, 4, 0) || \ - BROTLI_INTEL_VERSION_CHECK(16, 0, 0) - return 31u ^ (uint32_t)__builtin_clz((uint32_t)n); +#if defined(BROTLI_BSR32) + return BROTLI_BSR32((uint32_t)n); #else uint32_t result = 0; while (n >>= 1) result++; @@ -30,110 +28,31 @@ static BROTLI_INLINE uint32_t Log2FloorNonZero(size_t n) { #endif } +#define BROTLI_LOG2_TABLE_SIZE 256 + /* A lookup table for small values of log2(int) to be used in entropy - computation. + computation. */ +BROTLI_INTERNAL extern const double kBrotliLog2Table[BROTLI_LOG2_TABLE_SIZE]; - ", ".join(["%.16ff" % x for x in [0.0]+[log2(x) for x in range(1, 256)]]) */ -static const float kLog2Table[] = { - 0.0000000000000000f, 0.0000000000000000f, 1.0000000000000000f, - 1.5849625007211563f, 2.0000000000000000f, 2.3219280948873622f, - 2.5849625007211561f, 2.8073549220576042f, 3.0000000000000000f, - 3.1699250014423126f, 3.3219280948873626f, 3.4594316186372978f, - 3.5849625007211565f, 3.7004397181410922f, 3.8073549220576037f, - 3.9068905956085187f, 4.0000000000000000f, 4.0874628412503400f, - 4.1699250014423122f, 4.2479275134435852f, 4.3219280948873626f, - 4.3923174227787607f, 4.4594316186372973f, 4.5235619560570131f, - 4.5849625007211570f, 4.6438561897747244f, 4.7004397181410926f, - 4.7548875021634691f, 4.8073549220576037f, 4.8579809951275728f, - 4.9068905956085187f, 4.9541963103868758f, 5.0000000000000000f, - 5.0443941193584534f, 5.0874628412503400f, 5.1292830169449664f, - 5.1699250014423122f, 5.2094533656289501f, 5.2479275134435852f, - 5.2854022188622487f, 5.3219280948873626f, 5.3575520046180838f, - 5.3923174227787607f, 5.4262647547020979f, 5.4594316186372973f, - 5.4918530963296748f, 5.5235619560570131f, 5.5545888516776376f, - 5.5849625007211570f, 5.6147098441152083f, 5.6438561897747244f, - 5.6724253419714961f, 5.7004397181410926f, 5.7279204545631996f, - 5.7548875021634691f, 5.7813597135246599f, 5.8073549220576046f, - 5.8328900141647422f, 5.8579809951275719f, 5.8826430493618416f, - 5.9068905956085187f, 5.9307373375628867f, 5.9541963103868758f, - 5.9772799234999168f, 6.0000000000000000f, 6.0223678130284544f, - 6.0443941193584534f, 6.0660891904577721f, 6.0874628412503400f, - 6.1085244567781700f, 6.1292830169449672f, 6.1497471195046822f, - 6.1699250014423122f, 6.1898245588800176f, 6.2094533656289510f, - 6.2288186904958804f, 6.2479275134435861f, 6.2667865406949019f, - 6.2854022188622487f, 6.3037807481771031f, 6.3219280948873617f, - 6.3398500028846252f, 6.3575520046180847f, 6.3750394313469254f, - 6.3923174227787598f, 6.4093909361377026f, 6.4262647547020979f, - 6.4429434958487288f, 6.4594316186372982f, 6.4757334309663976f, - 6.4918530963296748f, 6.5077946401986964f, 6.5235619560570131f, - 6.5391588111080319f, 6.5545888516776376f, 6.5698556083309478f, - 6.5849625007211561f, 6.5999128421871278f, 6.6147098441152092f, - 6.6293566200796095f, 6.6438561897747253f, 6.6582114827517955f, - 6.6724253419714952f, 6.6865005271832185f, 6.7004397181410917f, - 6.7142455176661224f, 6.7279204545631988f, 6.7414669864011465f, - 6.7548875021634691f, 6.7681843247769260f, 6.7813597135246599f, - 6.7944158663501062f, 6.8073549220576037f, 6.8201789624151887f, - 6.8328900141647422f, 6.8454900509443757f, 6.8579809951275719f, - 6.8703647195834048f, 6.8826430493618416f, 6.8948177633079437f, - 6.9068905956085187f, 6.9188632372745955f, 6.9307373375628867f, - 6.9425145053392399f, 6.9541963103868758f, 6.9657842846620879f, - 6.9772799234999168f, 6.9886846867721664f, 7.0000000000000000f, - 7.0112272554232540f, 7.0223678130284544f, 7.0334230015374501f, - 7.0443941193584534f, 7.0552824355011898f, 7.0660891904577721f, - 7.0768155970508317f, 7.0874628412503400f, 7.0980320829605272f, - 7.1085244567781700f, 7.1189410727235076f, 7.1292830169449664f, - 7.1395513523987937f, 7.1497471195046822f, 7.1598713367783891f, - 7.1699250014423130f, 7.1799090900149345f, 7.1898245588800176f, - 7.1996723448363644f, 7.2094533656289492f, 7.2191685204621621f, - 7.2288186904958804f, 7.2384047393250794f, 7.2479275134435861f, - 7.2573878426926521f, 7.2667865406949019f, 7.2761244052742384f, - 7.2854022188622487f, 7.2946207488916270f, 7.3037807481771031f, - 7.3128829552843557f, 7.3219280948873617f, 7.3309168781146177f, - 7.3398500028846243f, 7.3487281542310781f, 7.3575520046180847f, - 7.3663222142458151f, 7.3750394313469254f, 7.3837042924740528f, - 7.3923174227787607f, 7.4008794362821844f, 7.4093909361377026f, - 7.4178525148858991f, 7.4262647547020979f, 7.4346282276367255f, - 7.4429434958487288f, 7.4512111118323299f, 7.4594316186372973f, - 7.4676055500829976f, 7.4757334309663976f, 7.4838157772642564f, - 7.4918530963296748f, 7.4998458870832057f, 7.5077946401986964f, - 7.5156998382840436f, 7.5235619560570131f, 7.5313814605163119f, - 7.5391588111080319f, 7.5468944598876373f, 7.5545888516776376f, - 7.5622424242210728f, 7.5698556083309478f, 7.5774288280357487f, - 7.5849625007211561f, 7.5924570372680806f, 7.5999128421871278f, - 7.6073303137496113f, 7.6147098441152075f, 7.6220518194563764f, - 7.6293566200796095f, 7.6366246205436488f, 7.6438561897747244f, - 7.6510516911789290f, 7.6582114827517955f, 7.6653359171851765f, - 7.6724253419714952f, 7.6794800995054464f, 7.6865005271832185f, - 7.6934869574993252f, 7.7004397181410926f, 7.7073591320808825f, - 7.7142455176661224f, 7.7210991887071856f, 7.7279204545631996f, - 7.7347096202258392f, 7.7414669864011465f, 7.7481928495894596f, - 7.7548875021634691f, 7.7615512324444795f, 7.7681843247769260f, - 7.7747870596011737f, 7.7813597135246608f, 7.7879025593914317f, - 7.7944158663501062f, 7.8008998999203047f, 7.8073549220576037f, - 7.8137811912170374f, 7.8201789624151887f, 7.8265484872909159f, - 7.8328900141647422f, 7.8392037880969445f, 7.8454900509443757f, - 7.8517490414160571f, 7.8579809951275719f, 7.8641861446542798f, - 7.8703647195834048f, 7.8765169465650002f, 7.8826430493618425f, - 7.8887432488982601f, 7.8948177633079446f, 7.9008668079807496f, - 7.9068905956085187f, 7.9128893362299619f, 7.9188632372745955f, - 7.9248125036057813f, 7.9307373375628867f, 7.9366379390025719f, - 7.9425145053392399f, 7.9483672315846778f, 7.9541963103868758f, - 7.9600019320680806f, 7.9657842846620870f, 7.9715435539507720f, - 7.9772799234999168f, 7.9829935746943104f, 7.9886846867721664f, - 7.9943534368588578f -}; +/* Visual Studio 2012 and Android API levels < 18 do not have the log2() + * function defined, so we use log() and a multiplication instead. */ +#if !defined(BROTLI_HAVE_LOG2) +#if ((defined(_MSC_VER) && _MSC_VER <= 1700) || \ + (defined(__ANDROID_API__) && __ANDROID_API__ < 18)) +#define BROTLI_HAVE_LOG2 0 +#else +#define BROTLI_HAVE_LOG2 1 +#endif +#endif #define LOG_2_INV 1.4426950408889634 /* Faster logarithm for small integers, with the property of log2(0) == 0. */ static BROTLI_INLINE double FastLog2(size_t v) { - if (v < sizeof(kLog2Table) / sizeof(kLog2Table[0])) { - return kLog2Table[v]; + if (v < BROTLI_LOG2_TABLE_SIZE) { + return kBrotliLog2Table[v]; } -#if (defined(_MSC_VER) && _MSC_VER <= 1700) || \ - (defined(__ANDROID_API__) && __ANDROID_API__ < 18) - /* Visual Studio 2012 and Android API levels < 18 do not have the log2() - * function defined, so we use log() and a multiplication instead. */ +#if !(BROTLI_HAVE_LOG2) return log((double)v) * LOG_2_INV; #else return log2((double)v); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/find_match_length.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/find_match_length.h index bc428cffdaf..f8853a70fbb 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/find_match_length.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/find_match_length.h @@ -17,8 +17,7 @@ extern "C" { #endif /* Separate implementation for little-endian 64-bit targets, for speed. */ -#if defined(__GNUC__) && defined(_LP64) && defined(BROTLI_LITTLE_ENDIAN) - +#if defined(BROTLI_TZCNT64) && BROTLI_64_BITS && BROTLI_LITTLE_ENDIAN static BROTLI_INLINE size_t FindMatchLengthWithLimit(const uint8_t* s1, const uint8_t* s2, size_t limit) { @@ -32,7 +31,7 @@ static BROTLI_INLINE size_t FindMatchLengthWithLimit(const uint8_t* s1, } else { uint64_t x = BROTLI_UNALIGNED_LOAD64LE(s2) ^ BROTLI_UNALIGNED_LOAD64LE(s1 + matched); - size_t matching_bits = (size_t)__builtin_ctzll(x); + size_t matching_bits = (size_t)BROTLI_TZCNT64(x); matched += matching_bits >> 3; return matched; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash.h index 8c5a7bb5ad5..6362f69b9f5 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash.h @@ -27,34 +27,19 @@ extern "C" { #endif -/* Pointer to hasher data. - * - * Excluding initialization and destruction, hasher can be passed as - * HasherHandle by value. - * - * Typically hasher data consists of 3 sections: - * * HasherCommon structure - * * private structured hasher data, depending on hasher type - * * private dynamic hasher data, depending on hasher type and parameters - * - * Using "define" instead of "typedef", because on MSVC __restrict does not work - * on typedef pointer types. */ -#define HasherHandle uint8_t* - typedef struct { + /* Dynamically allocated area; first member for quickest access. */ + void* extra; + + size_t dict_num_lookups; + size_t dict_num_matches; + BrotliHasherParams params; /* False if hasher needs to be "prepared" before use. */ BROTLI_BOOL is_prepared_; - - size_t dict_num_lookups; - size_t dict_num_matches; } HasherCommon; -static BROTLI_INLINE HasherCommon* GetHasherCommon(HasherHandle handle) { - return (HasherCommon*)handle; -} - #define score_t size_t static const uint32_t kCutoffTransformsCount = 10; @@ -149,17 +134,13 @@ static BROTLI_INLINE score_t BackwardReferencePenaltyUsingLastDistance( } static BROTLI_INLINE BROTLI_BOOL TestStaticDictionaryItem( - const BrotliEncoderDictionary* dictionary, size_t item, + const BrotliEncoderDictionary* dictionary, size_t len, size_t word_idx, const uint8_t* data, size_t max_length, size_t max_backward, size_t max_distance, HasherSearchResult* out) { - size_t len; - size_t word_idx; size_t offset; size_t matchlen; size_t backward; score_t score; - len = item & 0x1F; - word_idx = item >> 5; offset = dictionary->words->offsets_by_length[len] + len * word_idx; if (len > max_length) { return BROTLI_FALSE; @@ -193,25 +174,24 @@ static BROTLI_INLINE BROTLI_BOOL TestStaticDictionaryItem( static BROTLI_INLINE void SearchInStaticDictionary( const BrotliEncoderDictionary* dictionary, - HasherHandle handle, const uint8_t* data, size_t max_length, + HasherCommon* common, const uint8_t* data, size_t max_length, size_t max_backward, size_t max_distance, HasherSearchResult* out, BROTLI_BOOL shallow) { size_t key; size_t i; - HasherCommon* self = GetHasherCommon(handle); - if (self->dict_num_matches < (self->dict_num_lookups >> 7)) { + if (common->dict_num_matches < (common->dict_num_lookups >> 7)) { return; } key = Hash14(data) << 1; for (i = 0; i < (shallow ? 1u : 2u); ++i, ++key) { - size_t item = dictionary->hash_table[key]; - self->dict_num_lookups++; - if (item != 0) { + common->dict_num_lookups++; + if (dictionary->hash_table_lengths[key] != 0) { BROTLI_BOOL item_matches = TestStaticDictionaryItem( - dictionary, item, data, + dictionary, dictionary->hash_table_lengths[key], + dictionary->hash_table_words[key], data, max_length, max_backward, max_distance, out); if (item_matches) { - self->dict_num_matches++; + common->dict_num_matches++; } } } @@ -260,37 +240,37 @@ static BROTLI_INLINE size_t BackwardMatchLengthCode(const BackwardMatch* self) { /* MAX_NUM_MATCHES == 64 + MAX_TREE_SEARCH_DEPTH */ #define MAX_NUM_MATCHES_H10 128 -/* For BUCKET_SWEEP == 1, enabling the dictionary lookup makes compression +/* For BUCKET_SWEEP_BITS == 0, enabling the dictionary lookup makes compression a little faster (0.5% - 1%) and it compresses 0.15% better on small text and HTML inputs. */ #define HASHER() H2 #define BUCKET_BITS 16 -#define BUCKET_SWEEP 1 +#define BUCKET_SWEEP_BITS 0 #define HASH_LEN 5 #define USE_DICTIONARY 1 #include "./hash_longest_match_quickly_inc.h" /* NOLINT(build/include) */ -#undef BUCKET_SWEEP +#undef BUCKET_SWEEP_BITS #undef USE_DICTIONARY #undef HASHER #define HASHER() H3 -#define BUCKET_SWEEP 2 +#define BUCKET_SWEEP_BITS 1 #define USE_DICTIONARY 0 #include "./hash_longest_match_quickly_inc.h" /* NOLINT(build/include) */ #undef USE_DICTIONARY -#undef BUCKET_SWEEP +#undef BUCKET_SWEEP_BITS #undef BUCKET_BITS #undef HASHER #define HASHER() H4 #define BUCKET_BITS 17 -#define BUCKET_SWEEP 4 +#define BUCKET_SWEEP_BITS 2 #define USE_DICTIONARY 1 #include "./hash_longest_match_quickly_inc.h" /* NOLINT(build/include) */ #undef USE_DICTIONARY #undef HASH_LEN -#undef BUCKET_SWEEP +#undef BUCKET_SWEEP_BITS #undef BUCKET_BITS #undef HASHER @@ -334,13 +314,13 @@ static BROTLI_INLINE size_t BackwardMatchLengthCode(const BackwardMatch* self) { #define HASHER() H54 #define BUCKET_BITS 20 -#define BUCKET_SWEEP 4 +#define BUCKET_SWEEP_BITS 2 #define HASH_LEN 7 #define USE_DICTIONARY 0 #include "./hash_longest_match_quickly_inc.h" /* NOLINT(build/include) */ #undef USE_DICTIONARY #undef HASH_LEN -#undef BUCKET_SWEEP +#undef BUCKET_SWEEP_BITS #undef BUCKET_BITS #undef HASHER @@ -393,97 +373,107 @@ static BROTLI_INLINE size_t BackwardMatchLengthCode(const BackwardMatch* self) { #undef CAT #undef EXPAND_CAT -#define FOR_GENERIC_HASHERS(H) H(2) H(3) H(4) H(5) H(6) H(40) H(41) H(42) H(54)\ - H(35) H(55) H(65) +#define FOR_SIMPLE_HASHERS(H) H(2) H(3) H(4) H(5) H(6) H(40) H(41) H(42) H(54) +#define FOR_COMPOSITE_HASHERS(H) H(35) H(55) H(65) +#define FOR_GENERIC_HASHERS(H) FOR_SIMPLE_HASHERS(H) FOR_COMPOSITE_HASHERS(H) #define FOR_ALL_HASHERS(H) FOR_GENERIC_HASHERS(H) H(10) -static BROTLI_INLINE void DestroyHasher( - MemoryManager* m, HasherHandle* handle) { - if (*handle == NULL) return; - BROTLI_FREE(m, *handle); +typedef struct { + HasherCommon common; + + union { +#define MEMBER_(N) \ + H ## N _H ## N; + FOR_ALL_HASHERS(MEMBER_) +#undef MEMBER_ + } privat; +} Hasher; + +/* MUST be invoked before any other method. */ +static BROTLI_INLINE void HasherInit(Hasher* hasher) { + hasher->common.extra = NULL; } -static BROTLI_INLINE void HasherReset(HasherHandle handle) { - if (handle == NULL) return; - GetHasherCommon(handle)->is_prepared_ = BROTLI_FALSE; +static BROTLI_INLINE void DestroyHasher(MemoryManager* m, Hasher* hasher) { + if (hasher->common.extra == NULL) return; + BROTLI_FREE(m, hasher->common.extra); +} + +static BROTLI_INLINE void HasherReset(Hasher* hasher) { + hasher->common.is_prepared_ = BROTLI_FALSE; } static BROTLI_INLINE size_t HasherSize(const BrotliEncoderParams* params, BROTLI_BOOL one_shot, const size_t input_size) { - size_t result = sizeof(HasherCommon); switch (params->hasher.type) { -#define SIZE_(N) \ - case N: \ - result += HashMemAllocInBytesH ## N(params, one_shot, input_size); \ - break; +#define SIZE_(N) \ + case N: \ + return HashMemAllocInBytesH ## N(params, one_shot, input_size); FOR_ALL_HASHERS(SIZE_) #undef SIZE_ default: break; } - return result; + return 0; /* Default case. */ } -static BROTLI_INLINE void HasherSetup(MemoryManager* m, HasherHandle* handle, +static BROTLI_INLINE void HasherSetup(MemoryManager* m, Hasher* hasher, BrotliEncoderParams* params, const uint8_t* data, size_t position, size_t input_size, BROTLI_BOOL is_last) { - HasherHandle self = NULL; - HasherCommon* common = NULL; BROTLI_BOOL one_shot = (position == 0 && is_last); - if (*handle == NULL) { + if (hasher->common.extra == NULL) { size_t alloc_size; ChooseHasher(params, ¶ms->hasher); alloc_size = HasherSize(params, one_shot, input_size); - self = BROTLI_ALLOC(m, uint8_t, alloc_size); - if (BROTLI_IS_OOM(m)) return; - *handle = self; - common = GetHasherCommon(self); - common->params = params->hasher; - switch (common->params.type) { -#define INITIALIZE_(N) \ - case N: \ - InitializeH ## N(*handle, params); \ + hasher->common.extra = BROTLI_ALLOC(m, uint8_t, alloc_size); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(hasher->common.extra)) return; + hasher->common.params = params->hasher; + switch (hasher->common.params.type) { +#define INITIALIZE_(N) \ + case N: \ + InitializeH ## N(&hasher->common, \ + &hasher->privat._H ## N, params); \ break; FOR_ALL_HASHERS(INITIALIZE_); #undef INITIALIZE_ default: break; } - HasherReset(*handle); + HasherReset(hasher); } - self = *handle; - common = GetHasherCommon(self); - if (!common->is_prepared_) { - switch (common->params.type) { -#define PREPARE_(N) \ - case N: \ - PrepareH ## N(self, one_shot, input_size, data); \ + if (!hasher->common.is_prepared_) { + switch (hasher->common.params.type) { +#define PREPARE_(N) \ + case N: \ + PrepareH ## N( \ + &hasher->privat._H ## N, \ + one_shot, input_size, data); \ break; FOR_ALL_HASHERS(PREPARE_) #undef PREPARE_ default: break; } if (position == 0) { - common->dict_num_lookups = 0; - common->dict_num_matches = 0; + hasher->common.dict_num_lookups = 0; + hasher->common.dict_num_matches = 0; } - common->is_prepared_ = BROTLI_TRUE; + hasher->common.is_prepared_ = BROTLI_TRUE; } } static BROTLI_INLINE void InitOrStitchToPreviousBlock( - MemoryManager* m, HasherHandle* handle, const uint8_t* data, size_t mask, + MemoryManager* m, Hasher* hasher, const uint8_t* data, size_t mask, BrotliEncoderParams* params, size_t position, size_t input_size, BROTLI_BOOL is_last) { - HasherHandle self; - HasherSetup(m, handle, params, data, position, input_size, is_last); + HasherSetup(m, hasher, params, data, position, input_size, is_last); if (BROTLI_IS_OOM(m)) return; - self = *handle; - switch (GetHasherCommon(self)->params.type) { -#define INIT_(N) \ - case N: \ - StitchToPreviousBlockH ## N(self, input_size, position, data, mask); \ + switch (hasher->common.params.type) { +#define INIT_(N) \ + case N: \ + StitchToPreviousBlockH ## N( \ + &hasher->privat._H ## N, \ + input_size, position, data, mask); \ break; FOR_ALL_HASHERS(INIT_) #undef INIT_ diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_composite_inc.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_composite_inc.h index b266aa2f8da..cba156c0e23 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_composite_inc.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_composite_inc.h @@ -28,20 +28,25 @@ static BROTLI_INLINE size_t FN(StoreLookahead)(void) { } typedef struct HashComposite { - HasherHandle ha; - HasherHandle hb; + HASHER_A ha; + HASHER_B hb; + HasherCommon hb_common; + + /* Shortcuts. */ + void* extra; + HasherCommon* common; + + BROTLI_BOOL fresh; const BrotliEncoderParams* params; } HashComposite; -static BROTLI_INLINE HashComposite* FN(Self)(HasherHandle handle) { - return (HashComposite*)&(GetHasherCommon(handle)[1]); -} +static void FN(Initialize)(HasherCommon* common, + HashComposite* BROTLI_RESTRICT self, const BrotliEncoderParams* params) { + self->common = common; + self->extra = common->extra; -static void FN(Initialize)( - HasherHandle handle, const BrotliEncoderParams* params) { - HashComposite* self = FN(Self)(handle); - self->ha = 0; - self->hb = 0; + self->hb_common = *self->common; + self->fresh = BROTLI_TRUE; self->params = params; /* TODO: Initialize of the hashers is defered to Prepare (and params remembered here) because we don't get the one_shot and input_size params @@ -49,87 +54,71 @@ static void FN(Initialize)( those params to all hashers FN(Initialize) */ } -static void FN(Prepare)(HasherHandle handle, BROTLI_BOOL one_shot, - size_t input_size, const uint8_t* data) { - HashComposite* self = FN(Self)(handle); - if (!self->ha) { - HasherCommon* common_a; - HasherCommon* common_b; - - self->ha = handle + sizeof(HasherCommon) + sizeof(HashComposite); - common_a = (HasherCommon*)self->ha; - common_a->params = self->params->hasher; - common_a->is_prepared_ = BROTLI_FALSE; - common_a->dict_num_lookups = 0; - common_a->dict_num_matches = 0; - FN_A(Initialize)(self->ha, self->params); - - self->hb = self->ha + sizeof(HasherCommon) + FN_A(HashMemAllocInBytes)( - self->params, one_shot, input_size); - common_b = (HasherCommon*)self->hb; - common_b->params = self->params->hasher; - common_b->is_prepared_ = BROTLI_FALSE; - common_b->dict_num_lookups = 0; - common_b->dict_num_matches = 0; - FN_B(Initialize)(self->hb, self->params); +static void FN(Prepare)( + HashComposite* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, + size_t input_size, const uint8_t* BROTLI_RESTRICT data) { + if (self->fresh) { + self->fresh = BROTLI_FALSE; + self->hb_common.extra = (uint8_t*)self->extra + + FN_A(HashMemAllocInBytes)(self->params, one_shot, input_size); + + FN_A(Initialize)(self->common, &self->ha, self->params); + FN_B(Initialize)(&self->hb_common, &self->hb, self->params); } - FN_A(Prepare)(self->ha, one_shot, input_size, data); - FN_B(Prepare)(self->hb, one_shot, input_size, data); + FN_A(Prepare)(&self->ha, one_shot, input_size, data); + FN_B(Prepare)(&self->hb, one_shot, input_size, data); } static BROTLI_INLINE size_t FN(HashMemAllocInBytes)( const BrotliEncoderParams* params, BROTLI_BOOL one_shot, size_t input_size) { - return sizeof(HashComposite) + 2 * sizeof(HasherCommon) + - FN_A(HashMemAllocInBytes)(params, one_shot, input_size) + + return FN_A(HashMemAllocInBytes)(params, one_shot, input_size) + FN_B(HashMemAllocInBytes)(params, one_shot, input_size); } -static BROTLI_INLINE void FN(Store)(HasherHandle BROTLI_RESTRICT handle, +static BROTLI_INLINE void FN(Store)(HashComposite* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { - HashComposite* self = FN(Self)(handle); - FN_A(Store)(self->ha, data, mask, ix); - FN_B(Store)(self->hb, data, mask, ix); + FN_A(Store)(&self->ha, data, mask, ix); + FN_B(Store)(&self->hb, data, mask, ix); } -static BROTLI_INLINE void FN(StoreRange)(HasherHandle handle, - const uint8_t* data, const size_t mask, const size_t ix_start, +static BROTLI_INLINE void FN(StoreRange)( + HashComposite* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data, + const size_t mask, const size_t ix_start, const size_t ix_end) { - HashComposite* self = FN(Self)(handle); - FN_A(StoreRange)(self->ha, data, mask, ix_start, ix_end); - FN_B(StoreRange)(self->hb, data, mask, ix_start, ix_end); + FN_A(StoreRange)(&self->ha, data, mask, ix_start, ix_end); + FN_B(StoreRange)(&self->hb, data, mask, ix_start, ix_end); } -static BROTLI_INLINE void FN(StitchToPreviousBlock)(HasherHandle handle, +static BROTLI_INLINE void FN(StitchToPreviousBlock)( + HashComposite* BROTLI_RESTRICT self, size_t num_bytes, size_t position, const uint8_t* ringbuffer, size_t ring_buffer_mask) { - HashComposite* self = FN(Self)(handle); - FN_A(StitchToPreviousBlock)(self->ha, num_bytes, position, ringbuffer, - ring_buffer_mask); - FN_B(StitchToPreviousBlock)(self->hb, num_bytes, position, ringbuffer, - ring_buffer_mask); + FN_A(StitchToPreviousBlock)(&self->ha, num_bytes, position, + ringbuffer, ring_buffer_mask); + FN_B(StitchToPreviousBlock)(&self->hb, num_bytes, position, + ringbuffer, ring_buffer_mask); } static BROTLI_INLINE void FN(PrepareDistanceCache)( - HasherHandle handle, int* BROTLI_RESTRICT distance_cache) { - HashComposite* self = FN(Self)(handle); - FN_A(PrepareDistanceCache)(self->ha, distance_cache); - FN_B(PrepareDistanceCache)(self->hb, distance_cache); + HashComposite* BROTLI_RESTRICT self, int* BROTLI_RESTRICT distance_cache) { + FN_A(PrepareDistanceCache)(&self->ha, distance_cache); + FN_B(PrepareDistanceCache)(&self->hb, distance_cache); } -static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle, +static BROTLI_INLINE void FN(FindLongestMatch)( + HashComposite* BROTLI_RESTRICT self, const BrotliEncoderDictionary* dictionary, const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix, const size_t max_length, const size_t max_backward, - const size_t gap, const size_t max_distance, + const size_t dictionary_distance, const size_t max_distance, HasherSearchResult* BROTLI_RESTRICT out) { - HashComposite* self = FN(Self)(handle); - FN_A(FindLongestMatch)(self->ha, dictionary, data, ring_buffer_mask, - distance_cache, cur_ix, max_length, max_backward, gap, + FN_A(FindLongestMatch)(&self->ha, dictionary, data, ring_buffer_mask, + distance_cache, cur_ix, max_length, max_backward, dictionary_distance, max_distance, out); - FN_B(FindLongestMatch)(self->hb, dictionary, data, ring_buffer_mask, - distance_cache, cur_ix, max_length, max_backward, gap, + FN_B(FindLongestMatch)(&self->hb, dictionary, data, ring_buffer_mask, + distance_cache, cur_ix, max_length, max_backward, dictionary_distance, max_distance, out); } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_forgetful_chain_inc.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_forgetful_chain_inc.h index 41cb3ff03ac..bfae6ba6a20 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_forgetful_chain_inc.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_forgetful_chain_inc.h @@ -28,7 +28,7 @@ static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 4; } static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 4; } /* HashBytes is the function that chooses the bucket to place the address in.*/ -static BROTLI_INLINE size_t FN(HashBytes)(const uint8_t* data) { +static BROTLI_INLINE size_t FN(HashBytes)(const uint8_t* BROTLI_RESTRICT data) { const uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; /* The higher bits contain more mixture from the multiplication, so we take our results from there. */ @@ -45,28 +45,56 @@ typedef struct FN(Bank) { } FN(Bank); typedef struct HashForgetfulChain { - uint32_t addr[BUCKET_SIZE]; - uint16_t head[BUCKET_SIZE]; - /* Truncated hash used for quick rejection of "distance cache" candidates. */ - uint8_t tiny_hash[65536]; - FN(Bank) banks[NUM_BANKS]; - uint16_t free_slot_idx[NUM_BANKS]; + uint16_t free_slot_idx[NUM_BANKS]; /* Up to 1KiB. Move to dynamic? */ size_t max_hops; + + /* Shortcuts. */ + void* extra; + HasherCommon* common; + + /* --- Dynamic size members --- */ + + /* uint32_t addr[BUCKET_SIZE]; */ + + /* uint16_t head[BUCKET_SIZE]; */ + + /* Truncated hash used for quick rejection of "distance cache" candidates. */ + /* uint8_t tiny_hash[65536];*/ + + /* FN(Bank) banks[NUM_BANKS]; */ } HashForgetfulChain; -static BROTLI_INLINE HashForgetfulChain* FN(Self)(HasherHandle handle) { - return (HashForgetfulChain*)&(GetHasherCommon(handle)[1]); +static uint32_t* FN(Addr)(void* extra) { + return (uint32_t*)extra; +} + +static uint16_t* FN(Head)(void* extra) { + return (uint16_t*)(&FN(Addr)(extra)[BUCKET_SIZE]); +} + +static uint8_t* FN(TinyHash)(void* extra) { + return (uint8_t*)(&FN(Head)(extra)[BUCKET_SIZE]); +} + +static FN(Bank)* FN(Banks)(void* extra) { + return (FN(Bank)*)(&FN(TinyHash)(extra)[65536]); } static void FN(Initialize)( - HasherHandle handle, const BrotliEncoderParams* params) { - FN(Self)(handle)->max_hops = - (params->quality > 6 ? 7u : 8u) << (params->quality - 4); + HasherCommon* common, HashForgetfulChain* BROTLI_RESTRICT self, + const BrotliEncoderParams* params) { + self->common = common; + self->extra = common->extra; + + self->max_hops = (params->quality > 6 ? 7u : 8u) << (params->quality - 4); } -static void FN(Prepare)(HasherHandle handle, BROTLI_BOOL one_shot, - size_t input_size, const uint8_t* data) { - HashForgetfulChain* self = FN(Self)(handle); +static void FN(Prepare)( + HashForgetfulChain* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, + size_t input_size, const uint8_t* BROTLI_RESTRICT data) { + uint32_t* BROTLI_RESTRICT addr = FN(Addr)(self->extra); + uint16_t* BROTLI_RESTRICT head = FN(Head)(self->extra); + uint8_t* BROTLI_RESTRICT tiny_hash = FN(TinyHash)(self->extra); /* Partial preparation is 100 times slower (per socket). */ size_t partial_prepare_threshold = BUCKET_SIZE >> 6; if (one_shot && input_size <= partial_prepare_threshold) { @@ -74,17 +102,17 @@ static void FN(Prepare)(HasherHandle handle, BROTLI_BOOL one_shot, for (i = 0; i < input_size; ++i) { size_t bucket = FN(HashBytes)(&data[i]); /* See InitEmpty comment. */ - self->addr[bucket] = 0xCCCCCCCC; - self->head[bucket] = 0xCCCC; + addr[bucket] = 0xCCCCCCCC; + head[bucket] = 0xCCCC; } } else { /* Fill |addr| array with 0xCCCCCCCC value. Because of wrapping, position processed by hasher never reaches 3GB + 64M; this makes all new chains to be terminated after the first node. */ - memset(self->addr, 0xCC, sizeof(self->addr)); - memset(self->head, 0, sizeof(self->head)); + memset(addr, 0xCC, sizeof(uint32_t) * BUCKET_SIZE); + memset(head, 0, sizeof(uint16_t) * BUCKET_SIZE); } - memset(self->tiny_hash, 0, sizeof(self->tiny_hash)); + memset(tiny_hash, 0, sizeof(uint8_t) * 65536); memset(self->free_slot_idx, 0, sizeof(self->free_slot_idx)); } @@ -94,51 +122,58 @@ static BROTLI_INLINE size_t FN(HashMemAllocInBytes)( BROTLI_UNUSED(params); BROTLI_UNUSED(one_shot); BROTLI_UNUSED(input_size); - return sizeof(HashForgetfulChain); + return sizeof(uint32_t) * BUCKET_SIZE + sizeof(uint16_t) * BUCKET_SIZE + + sizeof(uint8_t) * 65536 + sizeof(FN(Bank)) * NUM_BANKS; } /* Look at 4 bytes at &data[ix & mask]. Compute a hash from these, and prepend node to corresponding chain; also update tiny_hash for current position. */ -static BROTLI_INLINE void FN(Store)(HasherHandle BROTLI_RESTRICT handle, +static BROTLI_INLINE void FN(Store)(HashForgetfulChain* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { - HashForgetfulChain* self = FN(Self)(handle); + uint32_t* BROTLI_RESTRICT addr = FN(Addr)(self->extra); + uint16_t* BROTLI_RESTRICT head = FN(Head)(self->extra); + uint8_t* BROTLI_RESTRICT tiny_hash = FN(TinyHash)(self->extra); + FN(Bank)* BROTLI_RESTRICT banks = FN(Banks)(self->extra); const size_t key = FN(HashBytes)(&data[ix & mask]); const size_t bank = key & (NUM_BANKS - 1); const size_t idx = self->free_slot_idx[bank]++ & (BANK_SIZE - 1); - size_t delta = ix - self->addr[key]; - self->tiny_hash[(uint16_t)ix] = (uint8_t)key; + size_t delta = ix - addr[key]; + tiny_hash[(uint16_t)ix] = (uint8_t)key; if (delta > 0xFFFF) delta = CAPPED_CHAINS ? 0 : 0xFFFF; - self->banks[bank].slots[idx].delta = (uint16_t)delta; - self->banks[bank].slots[idx].next = self->head[key]; - self->addr[key] = (uint32_t)ix; - self->head[key] = (uint16_t)idx; + banks[bank].slots[idx].delta = (uint16_t)delta; + banks[bank].slots[idx].next = head[key]; + addr[key] = (uint32_t)ix; + head[key] = (uint16_t)idx; } -static BROTLI_INLINE void FN(StoreRange)(HasherHandle handle, - const uint8_t* data, const size_t mask, const size_t ix_start, - const size_t ix_end) { +static BROTLI_INLINE void FN(StoreRange)( + HashForgetfulChain* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, const size_t mask, + const size_t ix_start, const size_t ix_end) { size_t i; for (i = ix_start; i < ix_end; ++i) { - FN(Store)(handle, data, mask, i); + FN(Store)(self, data, mask, i); } } -static BROTLI_INLINE void FN(StitchToPreviousBlock)(HasherHandle handle, +static BROTLI_INLINE void FN(StitchToPreviousBlock)( + HashForgetfulChain* BROTLI_RESTRICT self, size_t num_bytes, size_t position, const uint8_t* ringbuffer, size_t ring_buffer_mask) { if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) { /* Prepare the hashes for three last bytes of the last write. These could not be calculated before, since they require knowledge of both the previous and the current block. */ - FN(Store)(handle, ringbuffer, ring_buffer_mask, position - 3); - FN(Store)(handle, ringbuffer, ring_buffer_mask, position - 2); - FN(Store)(handle, ringbuffer, ring_buffer_mask, position - 1); + FN(Store)(self, ringbuffer, ring_buffer_mask, position - 3); + FN(Store)(self, ringbuffer, ring_buffer_mask, position - 2); + FN(Store)(self, ringbuffer, ring_buffer_mask, position - 1); } } static BROTLI_INLINE void FN(PrepareDistanceCache)( - HasherHandle handle, int* BROTLI_RESTRICT distance_cache) { - BROTLI_UNUSED(handle); + HashForgetfulChain* BROTLI_RESTRICT self, + int* BROTLI_RESTRICT distance_cache) { + BROTLI_UNUSED(self); PrepareDistanceCache(distance_cache, NUM_LAST_DISTANCES_TO_CHECK); } @@ -153,14 +188,18 @@ static BROTLI_INLINE void FN(PrepareDistanceCache)( Does not look for matches further away than max_backward. Writes the best match into |out|. |out|->score is updated only if a better match is found. */ -static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle, +static BROTLI_INLINE void FN(FindLongestMatch)( + HashForgetfulChain* BROTLI_RESTRICT self, const BrotliEncoderDictionary* dictionary, const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix, const size_t max_length, const size_t max_backward, - const size_t gap, const size_t max_distance, + const size_t dictionary_distance, const size_t max_distance, HasherSearchResult* BROTLI_RESTRICT out) { - HashForgetfulChain* self = FN(Self)(handle); + uint32_t* BROTLI_RESTRICT addr = FN(Addr)(self->extra); + uint16_t* BROTLI_RESTRICT head = FN(Head)(self->extra); + uint8_t* BROTLI_RESTRICT tiny_hashes = FN(TinyHash)(self->extra); + FN(Bank)* BROTLI_RESTRICT banks = FN(Banks)(self->extra); const size_t cur_ix_masked = cur_ix & ring_buffer_mask; /* Don't accept a short copy from far away. */ score_t min_score = out->score; @@ -176,7 +215,7 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle, const size_t backward = (size_t)distance_cache[i]; size_t prev_ix = (cur_ix - backward); /* For distance code 0 we want to consider 2-byte matches. */ - if (i > 0 && self->tiny_hash[(uint16_t)prev_ix] != tiny_hash) continue; + if (i > 0 && tiny_hashes[(uint16_t)prev_ix] != tiny_hash) continue; if (prev_ix >= cur_ix || backward > max_backward) { continue; } @@ -204,16 +243,16 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle, const size_t bank = key & (NUM_BANKS - 1); size_t backward = 0; size_t hops = self->max_hops; - size_t delta = cur_ix - self->addr[key]; - size_t slot = self->head[key]; + size_t delta = cur_ix - addr[key]; + size_t slot = head[key]; while (hops--) { size_t prev_ix; size_t last = slot; backward += delta; if (backward > max_backward || (CAPPED_CHAINS && !delta)) break; prev_ix = (cur_ix - backward) & ring_buffer_mask; - slot = self->banks[bank].slots[last].next; - delta = self->banks[bank].slots[last].delta; + slot = banks[bank].slots[last].next; + delta = banks[bank].slots[last].delta; if (cur_ix_masked + best_len > ring_buffer_mask || prev_ix + best_len > ring_buffer_mask || data[cur_ix_masked + best_len] != data[prev_ix + best_len]) { @@ -238,11 +277,11 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle, } } } - FN(Store)(handle, data, ring_buffer_mask, cur_ix); + FN(Store)(self, data, ring_buffer_mask, cur_ix); } if (out->score == min_score) { SearchInStaticDictionary(dictionary, - handle, &data[cur_ix_masked], max_length, max_backward + gap, + self->common, &data[cur_ix_masked], max_length, dictionary_distance, max_distance, out, BROTLI_FALSE); } } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_longest_match64_inc.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_longest_match64_inc.h index cb953a644fc..956fb304b36 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_longest_match64_inc.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_longest_match64_inc.h @@ -20,7 +20,7 @@ static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 8; } static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 8; } /* HashBytes is the function that chooses the bucket to place the address in. */ -static BROTLI_INLINE uint32_t FN(HashBytes)(const uint8_t* data, +static BROTLI_INLINE uint32_t FN(HashBytes)(const uint8_t* BROTLI_RESTRICT data, const uint64_t mask, const int shift) { const uint64_t h = (BROTLI_UNALIGNED_LOAD64LE(data) & mask) * kHashMul64Long; @@ -42,43 +42,43 @@ typedef struct HashLongestMatch { /* Mask for accessing entries in a block (in a ring-buffer manner). */ uint32_t block_mask_; + int block_bits_; + int num_last_distances_to_check_; + + /* Shortcuts. */ + HasherCommon* common_; + /* --- Dynamic size members --- */ /* Number of entries in a particular bucket. */ - /* uint16_t num[bucket_size]; */ + uint16_t* num_; /* uint16_t[bucket_size]; */ /* Buckets containing block_size_ of backward references. */ - /* uint32_t* buckets[bucket_size * block_size]; */ + uint32_t* buckets_; /* uint32_t[bucket_size * block_size]; */ } HashLongestMatch; -static BROTLI_INLINE HashLongestMatch* FN(Self)(HasherHandle handle) { - return (HashLongestMatch*)&(GetHasherCommon(handle)[1]); -} - -static BROTLI_INLINE uint16_t* FN(Num)(HashLongestMatch* self) { - return (uint16_t*)(&self[1]); -} - -static BROTLI_INLINE uint32_t* FN(Buckets)(HashLongestMatch* self) { - return (uint32_t*)(&FN(Num)(self)[self->bucket_size_]); -} - static void FN(Initialize)( - HasherHandle handle, const BrotliEncoderParams* params) { - HasherCommon* common = GetHasherCommon(handle); - HashLongestMatch* self = FN(Self)(handle); + HasherCommon* common, HashLongestMatch* BROTLI_RESTRICT self, + const BrotliEncoderParams* params) { + self->common_ = common; + BROTLI_UNUSED(params); self->hash_shift_ = 64 - common->params.bucket_bits; self->hash_mask_ = (~((uint64_t)0U)) >> (64 - 8 * common->params.hash_len); self->bucket_size_ = (size_t)1 << common->params.bucket_bits; + self->block_bits_ = common->params.block_bits; self->block_size_ = (size_t)1 << common->params.block_bits; self->block_mask_ = (uint32_t)(self->block_size_ - 1); + self->num_last_distances_to_check_ = + common->params.num_last_distances_to_check; + self->num_ = (uint16_t*)common->extra; + self->buckets_ = (uint32_t*)&self->num_[self->bucket_size_]; } -static void FN(Prepare)(HasherHandle handle, BROTLI_BOOL one_shot, - size_t input_size, const uint8_t* data) { - HashLongestMatch* self = FN(Self)(handle); - uint16_t* num = FN(Num)(self); +static void FN(Prepare)( + HashLongestMatch* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, + size_t input_size, const uint8_t* BROTLI_RESTRICT data) { + uint16_t* BROTLI_RESTRICT num = self->num_; /* Partial preparation is 100 times slower (per socket). */ size_t partial_prepare_threshold = self->bucket_size_ >> 6; if (one_shot && input_size <= partial_prepare_threshold) { @@ -100,50 +100,52 @@ static BROTLI_INLINE size_t FN(HashMemAllocInBytes)( size_t block_size = (size_t)1 << params->hasher.block_bits; BROTLI_UNUSED(one_shot); BROTLI_UNUSED(input_size); - return sizeof(HashLongestMatch) + bucket_size * (2 + 4 * block_size); + return sizeof(uint16_t) * bucket_size + + sizeof(uint32_t) * bucket_size * block_size; } /* Look at 4 bytes at &data[ix & mask]. Compute a hash from these, and store the value of ix at that position. */ -static BROTLI_INLINE void FN(Store)(HasherHandle handle, const uint8_t* data, +static BROTLI_INLINE void FN(Store)( + HashLongestMatch* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { - HashLongestMatch* self = FN(Self)(handle); - uint16_t* num = FN(Num)(self); + uint16_t* BROTLI_RESTRICT num = self->num_; + uint32_t* BROTLI_RESTRICT buckets = self->buckets_; const uint32_t key = FN(HashBytes)(&data[ix & mask], self->hash_mask_, self->hash_shift_); const size_t minor_ix = num[key] & self->block_mask_; - const size_t offset = - minor_ix + (key << GetHasherCommon(handle)->params.block_bits); - FN(Buckets)(self)[offset] = (uint32_t)ix; + const size_t offset = minor_ix + (key << self->block_bits_); ++num[key]; + buckets[offset] = (uint32_t)ix; } -static BROTLI_INLINE void FN(StoreRange)(HasherHandle handle, - const uint8_t* data, const size_t mask, const size_t ix_start, - const size_t ix_end) { +static BROTLI_INLINE void FN(StoreRange)(HashLongestMatch* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, const size_t mask, + const size_t ix_start, const size_t ix_end) { size_t i; for (i = ix_start; i < ix_end; ++i) { - FN(Store)(handle, data, mask, i); + FN(Store)(self, data, mask, i); } } -static BROTLI_INLINE void FN(StitchToPreviousBlock)(HasherHandle handle, +static BROTLI_INLINE void FN(StitchToPreviousBlock)( + HashLongestMatch* BROTLI_RESTRICT self, size_t num_bytes, size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask) { if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) { /* Prepare the hashes for three last bytes of the last write. These could not be calculated before, since they require knowledge of both the previous and the current block. */ - FN(Store)(handle, ringbuffer, ringbuffer_mask, position - 3); - FN(Store)(handle, ringbuffer, ringbuffer_mask, position - 2); - FN(Store)(handle, ringbuffer, ringbuffer_mask, position - 1); + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 3); + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 2); + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 1); } } static BROTLI_INLINE void FN(PrepareDistanceCache)( - HasherHandle handle, int* BROTLI_RESTRICT distance_cache) { - PrepareDistanceCache(distance_cache, - GetHasherCommon(handle)->params.num_last_distances_to_check); + HashLongestMatch* BROTLI_RESTRICT self, + int* BROTLI_RESTRICT distance_cache) { + PrepareDistanceCache(distance_cache, self->num_last_distances_to_check_); } /* Find a longest backward match of &data[cur_ix] up to the length of @@ -157,17 +159,16 @@ static BROTLI_INLINE void FN(PrepareDistanceCache)( Does not look for matches further away than max_backward. Writes the best match into |out|. |out|->score is updated only if a better match is found. */ -static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle, +static BROTLI_INLINE void FN(FindLongestMatch)( + HashLongestMatch* BROTLI_RESTRICT self, const BrotliEncoderDictionary* dictionary, const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix, const size_t max_length, const size_t max_backward, - const size_t gap, const size_t max_distance, + const size_t dictionary_distance, const size_t max_distance, HasherSearchResult* BROTLI_RESTRICT out) { - HasherCommon* common = GetHasherCommon(handle); - HashLongestMatch* self = FN(Self)(handle); - uint16_t* num = FN(Num)(self); - uint32_t* buckets = FN(Buckets)(self); + uint16_t* BROTLI_RESTRICT num = self->num_; + uint32_t* BROTLI_RESTRICT buckets = self->buckets_; const size_t cur_ix_masked = cur_ix & ring_buffer_mask; /* Don't accept a short copy from far away. */ score_t min_score = out->score; @@ -177,7 +178,7 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle, out->len = 0; out->len_code_delta = 0; /* Try last distance first. */ - for (i = 0; i < (size_t)common->params.num_last_distances_to_check; ++i) { + for (i = 0; i < (size_t)self->num_last_distances_to_check_; ++i) { const size_t backward = (size_t)distance_cache[i]; size_t prev_ix = (size_t)(cur_ix - backward); if (prev_ix >= cur_ix) { @@ -218,8 +219,7 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle, { const uint32_t key = FN(HashBytes)( &data[cur_ix_masked], self->hash_mask_, self->hash_shift_); - uint32_t* BROTLI_RESTRICT bucket = - &buckets[key << common->params.block_bits]; + uint32_t* BROTLI_RESTRICT bucket = &buckets[key << self->block_bits_]; const size_t down = (num[key] > self->block_size_) ? (num[key] - self->block_size_) : 0u; @@ -259,7 +259,7 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle, } if (min_score == out->score) { SearchInStaticDictionary(dictionary, - handle, &data[cur_ix_masked], max_length, max_backward + gap, + self->common_, &data[cur_ix_masked], max_length, dictionary_distance, max_distance, out, BROTLI_FALSE); } } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_longest_match_inc.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_longest_match_inc.h index 457f5a9ed2e..27f4463d7f3 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_longest_match_inc.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_longest_match_inc.h @@ -20,7 +20,8 @@ static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 4; } static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 4; } /* HashBytes is the function that chooses the bucket to place the address in. */ -static uint32_t FN(HashBytes)(const uint8_t* data, const int shift) { +static uint32_t FN(HashBytes)( + const uint8_t* BROTLI_RESTRICT data, const int shift) { uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; /* The higher bits contain more mixture from the multiplication, so we take our results from there. */ @@ -38,42 +39,46 @@ typedef struct HashLongestMatch { /* Mask for accessing entries in a block (in a ring-buffer manner). */ uint32_t block_mask_; + int block_bits_; + int num_last_distances_to_check_; + + /* Shortcuts. */ + HasherCommon* common_; + /* --- Dynamic size members --- */ /* Number of entries in a particular bucket. */ - /* uint16_t num[bucket_size]; */ + uint16_t* num_; /* uint16_t[bucket_size]; */ /* Buckets containing block_size_ of backward references. */ - /* uint32_t* buckets[bucket_size * block_size]; */ + uint32_t* buckets_; /* uint32_t[bucket_size * block_size]; */ } HashLongestMatch; -static BROTLI_INLINE HashLongestMatch* FN(Self)(HasherHandle handle) { - return (HashLongestMatch*)&(GetHasherCommon(handle)[1]); -} - -static BROTLI_INLINE uint16_t* FN(Num)(HashLongestMatch* self) { - return (uint16_t*)(&self[1]); -} - -static BROTLI_INLINE uint32_t* FN(Buckets)(HashLongestMatch* self) { - return (uint32_t*)(&FN(Num)(self)[self->bucket_size_]); +static BROTLI_INLINE uint16_t* FN(Num)(void* extra) { + return (uint16_t*)extra; } static void FN(Initialize)( - HasherHandle handle, const BrotliEncoderParams* params) { - HasherCommon* common = GetHasherCommon(handle); - HashLongestMatch* self = FN(Self)(handle); + HasherCommon* common, HashLongestMatch* BROTLI_RESTRICT self, + const BrotliEncoderParams* params) { + self->common_ = common; + BROTLI_UNUSED(params); self->hash_shift_ = 32 - common->params.bucket_bits; self->bucket_size_ = (size_t)1 << common->params.bucket_bits; self->block_size_ = (size_t)1 << common->params.block_bits; self->block_mask_ = (uint32_t)(self->block_size_ - 1); + self->num_ = (uint16_t*)common->extra; + self->buckets_ = (uint32_t*)(&self->num_[self->bucket_size_]); + self->block_bits_ = common->params.block_bits; + self->num_last_distances_to_check_ = + common->params.num_last_distances_to_check; } -static void FN(Prepare)(HasherHandle handle, BROTLI_BOOL one_shot, - size_t input_size, const uint8_t* data) { - HashLongestMatch* self = FN(Self)(handle); - uint16_t* num = FN(Num)(self); +static void FN(Prepare)( + HashLongestMatch* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, + size_t input_size, const uint8_t* BROTLI_RESTRICT data) { + uint16_t* BROTLI_RESTRICT num = self->num_; /* Partial preparation is 100 times slower (per socket). */ size_t partial_prepare_threshold = self->bucket_size_ >> 6; if (one_shot && input_size <= partial_prepare_threshold) { @@ -94,49 +99,49 @@ static BROTLI_INLINE size_t FN(HashMemAllocInBytes)( size_t block_size = (size_t)1 << params->hasher.block_bits; BROTLI_UNUSED(one_shot); BROTLI_UNUSED(input_size); - return sizeof(HashLongestMatch) + bucket_size * (2 + 4 * block_size); + return sizeof(uint16_t) * bucket_size + + sizeof(uint32_t) * bucket_size * block_size; } /* Look at 4 bytes at &data[ix & mask]. Compute a hash from these, and store the value of ix at that position. */ -static BROTLI_INLINE void FN(Store)(HasherHandle handle, const uint8_t* data, +static BROTLI_INLINE void FN(Store)( + HashLongestMatch* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { - HashLongestMatch* self = FN(Self)(handle); - uint16_t* num = FN(Num)(self); const uint32_t key = FN(HashBytes)(&data[ix & mask], self->hash_shift_); - const size_t minor_ix = num[key] & self->block_mask_; - const size_t offset = - minor_ix + (key << GetHasherCommon(handle)->params.block_bits); - FN(Buckets)(self)[offset] = (uint32_t)ix; - ++num[key]; + const size_t minor_ix = self->num_[key] & self->block_mask_; + const size_t offset = minor_ix + (key << self->block_bits_); + self->buckets_[offset] = (uint32_t)ix; + ++self->num_[key]; } -static BROTLI_INLINE void FN(StoreRange)(HasherHandle handle, - const uint8_t* data, const size_t mask, const size_t ix_start, - const size_t ix_end) { +static BROTLI_INLINE void FN(StoreRange)(HashLongestMatch* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, const size_t mask, + const size_t ix_start, const size_t ix_end) { size_t i; for (i = ix_start; i < ix_end; ++i) { - FN(Store)(handle, data, mask, i); + FN(Store)(self, data, mask, i); } } -static BROTLI_INLINE void FN(StitchToPreviousBlock)(HasherHandle handle, +static BROTLI_INLINE void FN(StitchToPreviousBlock)( + HashLongestMatch* BROTLI_RESTRICT self, size_t num_bytes, size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask) { if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) { /* Prepare the hashes for three last bytes of the last write. These could not be calculated before, since they require knowledge of both the previous and the current block. */ - FN(Store)(handle, ringbuffer, ringbuffer_mask, position - 3); - FN(Store)(handle, ringbuffer, ringbuffer_mask, position - 2); - FN(Store)(handle, ringbuffer, ringbuffer_mask, position - 1); + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 3); + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 2); + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 1); } } static BROTLI_INLINE void FN(PrepareDistanceCache)( - HasherHandle handle, int* BROTLI_RESTRICT distance_cache) { - PrepareDistanceCache(distance_cache, - GetHasherCommon(handle)->params.num_last_distances_to_check); + HashLongestMatch* BROTLI_RESTRICT self, + int* BROTLI_RESTRICT distance_cache) { + PrepareDistanceCache(distance_cache, self->num_last_distances_to_check_); } /* Find a longest backward match of &data[cur_ix] up to the length of @@ -150,17 +155,16 @@ static BROTLI_INLINE void FN(PrepareDistanceCache)( Does not look for matches further away than max_backward. Writes the best match into |out|. |out|->score is updated only if a better match is found. */ -static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle, +static BROTLI_INLINE void FN(FindLongestMatch)( + HashLongestMatch* BROTLI_RESTRICT self, const BrotliEncoderDictionary* dictionary, const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix, const size_t max_length, const size_t max_backward, - const size_t gap, const size_t max_distance, + const size_t dictionary_distance, const size_t max_distance, HasherSearchResult* BROTLI_RESTRICT out) { - HasherCommon* common = GetHasherCommon(handle); - HashLongestMatch* self = FN(Self)(handle); - uint16_t* num = FN(Num)(self); - uint32_t* buckets = FN(Buckets)(self); + uint16_t* BROTLI_RESTRICT num = self->num_; + uint32_t* BROTLI_RESTRICT buckets = self->buckets_; const size_t cur_ix_masked = cur_ix & ring_buffer_mask; /* Don't accept a short copy from far away. */ score_t min_score = out->score; @@ -170,7 +174,7 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle, out->len = 0; out->len_code_delta = 0; /* Try last distance first. */ - for (i = 0; i < (size_t)common->params.num_last_distances_to_check; ++i) { + for (i = 0; i < (size_t)self->num_last_distances_to_check_; ++i) { const size_t backward = (size_t)distance_cache[i]; size_t prev_ix = (size_t)(cur_ix - backward); if (prev_ix >= cur_ix) { @@ -211,8 +215,7 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle, { const uint32_t key = FN(HashBytes)(&data[cur_ix_masked], self->hash_shift_); - uint32_t* BROTLI_RESTRICT bucket = - &buckets[key << common->params.block_bits]; + uint32_t* BROTLI_RESTRICT bucket = &buckets[key << self->block_bits_]; const size_t down = (num[key] > self->block_size_) ? (num[key] - self->block_size_) : 0u; for (i = num[key]; i > down;) { @@ -251,7 +254,7 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle, } if (min_score == out->score) { SearchInStaticDictionary(dictionary, - handle, &data[cur_ix_masked], max_length, max_backward + gap, + self->common_, &data[cur_ix_masked], max_length, dictionary_distance, max_distance, out, BROTLI_FALSE); } } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_longest_match_quickly_inc.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_longest_match_quickly_inc.h index a7b9639febf..e5ba840ab97 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_longest_match_quickly_inc.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_longest_match_quickly_inc.h @@ -5,15 +5,16 @@ See file LICENSE for detail or copy at https://opensource.org/licenses/MIT */ -/* template parameters: FN, BUCKET_BITS, BUCKET_SWEEP, HASH_LEN, +/* template parameters: FN, BUCKET_BITS, BUCKET_SWEEP_BITS, HASH_LEN, USE_DICTIONARY */ #define HashLongestMatchQuickly HASHER() #define BUCKET_SIZE (1 << BUCKET_BITS) - -#define HASH_MAP_SIZE (4 << BUCKET_BITS) +#define BUCKET_MASK (BUCKET_SIZE - 1) +#define BUCKET_SWEEP (1 << BUCKET_SWEEP_BITS) +#define BUCKET_SWEEP_MASK ((BUCKET_SWEEP - 1) << 3) static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 8; } static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 8; } @@ -32,39 +33,50 @@ static uint32_t FN(HashBytes)(const uint8_t* data) { /* A (forgetful) hash table to the data seen by the compressor, to help create backward references to previous data. - This is a hash map of fixed size (BUCKET_SIZE). Starting from the - given index, BUCKET_SWEEP buckets are used to store values of a key. */ + This is a hash map of fixed size (BUCKET_SIZE). */ typedef struct HashLongestMatchQuickly { - uint32_t buckets_[BUCKET_SIZE + BUCKET_SWEEP]; -} HashLongestMatchQuickly; + /* Shortcuts. */ + HasherCommon* common; -static BROTLI_INLINE HashLongestMatchQuickly* FN(Self)(HasherHandle handle) { - return (HashLongestMatchQuickly*)&(GetHasherCommon(handle)[1]); -} + /* --- Dynamic size members --- */ + + uint32_t* buckets_; /* uint32_t[BUCKET_SIZE]; */ +} HashLongestMatchQuickly; static void FN(Initialize)( - HasherHandle handle, const BrotliEncoderParams* params) { - BROTLI_UNUSED(handle); + HasherCommon* common, HashLongestMatchQuickly* BROTLI_RESTRICT self, + const BrotliEncoderParams* params) { + self->common = common; + BROTLI_UNUSED(params); + self->buckets_ = (uint32_t*)common->extra; } -static void FN(Prepare)(HasherHandle handle, BROTLI_BOOL one_shot, - size_t input_size, const uint8_t* data) { - HashLongestMatchQuickly* self = FN(Self)(handle); +static void FN(Prepare)( + HashLongestMatchQuickly* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, + size_t input_size, const uint8_t* BROTLI_RESTRICT data) { + uint32_t* BROTLI_RESTRICT buckets = self->buckets_; /* Partial preparation is 100 times slower (per socket). */ - size_t partial_prepare_threshold = HASH_MAP_SIZE >> 7; + size_t partial_prepare_threshold = BUCKET_SIZE >> 5; if (one_shot && input_size <= partial_prepare_threshold) { size_t i; for (i = 0; i < input_size; ++i) { const uint32_t key = FN(HashBytes)(&data[i]); - memset(&self->buckets_[key], 0, BUCKET_SWEEP * sizeof(self->buckets_[0])); + if (BUCKET_SWEEP == 1) { + buckets[key] = 0; + } else { + uint32_t j; + for (j = 0; j < BUCKET_SWEEP; ++j) { + buckets[(key + (j << 3)) & BUCKET_MASK] = 0; + } + } } } else { /* It is not strictly necessary to fill this buffer here, but not filling will make the results of the compression stochastic (but correct). This is because random data would cause the system to find accidentally good backward references here and there. */ - memset(&self->buckets_[0], 0, sizeof(self->buckets_)); + memset(buckets, 0, sizeof(uint32_t) * BUCKET_SIZE); } } @@ -74,45 +86,53 @@ static BROTLI_INLINE size_t FN(HashMemAllocInBytes)( BROTLI_UNUSED(params); BROTLI_UNUSED(one_shot); BROTLI_UNUSED(input_size); - return sizeof(HashLongestMatchQuickly); + return sizeof(uint32_t) * BUCKET_SIZE; } /* Look at 5 bytes at &data[ix & mask]. Compute a hash from these, and store the value somewhere within [ix .. ix+3]. */ -static BROTLI_INLINE void FN(Store)(HasherHandle handle, - const uint8_t* data, const size_t mask, const size_t ix) { +static BROTLI_INLINE void FN(Store)( + HashLongestMatchQuickly* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { const uint32_t key = FN(HashBytes)(&data[ix & mask]); - /* Wiggle the value with the bucket sweep range. */ - const uint32_t off = (ix >> 3) % BUCKET_SWEEP; - FN(Self)(handle)->buckets_[key + off] = (uint32_t)ix; + if (BUCKET_SWEEP == 1) { + self->buckets_[key] = (uint32_t)ix; + } else { + /* Wiggle the value with the bucket sweep range. */ + const uint32_t off = ix & BUCKET_SWEEP_MASK; + self->buckets_[(key + off) & BUCKET_MASK] = (uint32_t)ix; + } } -static BROTLI_INLINE void FN(StoreRange)(HasherHandle handle, - const uint8_t* data, const size_t mask, const size_t ix_start, - const size_t ix_end) { +static BROTLI_INLINE void FN(StoreRange)( + HashLongestMatchQuickly* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, const size_t mask, + const size_t ix_start, const size_t ix_end) { size_t i; for (i = ix_start; i < ix_end; ++i) { - FN(Store)(handle, data, mask, i); + FN(Store)(self, data, mask, i); } } static BROTLI_INLINE void FN(StitchToPreviousBlock)( - HasherHandle handle, size_t num_bytes, size_t position, + HashLongestMatchQuickly* BROTLI_RESTRICT self, + size_t num_bytes, size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask) { if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) { /* Prepare the hashes for three last bytes of the last write. These could not be calculated before, since they require knowledge of both the previous and the current block. */ - FN(Store)(handle, ringbuffer, ringbuffer_mask, position - 3); - FN(Store)(handle, ringbuffer, ringbuffer_mask, position - 2); - FN(Store)(handle, ringbuffer, ringbuffer_mask, position - 1); + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 3); + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 2); + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 1); } } static BROTLI_INLINE void FN(PrepareDistanceCache)( - HasherHandle handle, int* BROTLI_RESTRICT distance_cache) { - BROTLI_UNUSED(handle); + HashLongestMatchQuickly* BROTLI_RESTRICT self, + int* BROTLI_RESTRICT distance_cache) { + BROTLI_UNUSED(self); BROTLI_UNUSED(distance_cache); } @@ -125,17 +145,19 @@ static BROTLI_INLINE void FN(PrepareDistanceCache)( Writes the best match into |out|. |out|->score is updated only if a better match is found. */ static BROTLI_INLINE void FN(FindLongestMatch)( - HasherHandle handle, const BrotliEncoderDictionary* dictionary, + HashLongestMatchQuickly* BROTLI_RESTRICT self, + const BrotliEncoderDictionary* dictionary, const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix, const size_t max_length, const size_t max_backward, - const size_t gap, const size_t max_distance, + const size_t dictionary_distance, const size_t max_distance, HasherSearchResult* BROTLI_RESTRICT out) { - HashLongestMatchQuickly* self = FN(Self)(handle); + uint32_t* BROTLI_RESTRICT buckets = self->buckets_; const size_t best_len_in = out->len; const size_t cur_ix_masked = cur_ix & ring_buffer_mask; - const uint32_t key = FN(HashBytes)(&data[cur_ix_masked]); int compare_char = data[cur_ix_masked + best_len_in]; + size_t key = FN(HashBytes)(&data[cur_ix_masked]); + size_t key_out; score_t min_score = out->score; score_t best_score = out->score; size_t best_len = best_len_in; @@ -145,21 +167,21 @@ static BROTLI_INLINE void FN(FindLongestMatch)( if (prev_ix < cur_ix) { prev_ix &= (uint32_t)ring_buffer_mask; if (compare_char == data[prev_ix + best_len]) { - size_t len = FindMatchLengthWithLimit(&data[prev_ix], - &data[cur_ix_masked], - max_length); + const size_t len = FindMatchLengthWithLimit( + &data[prev_ix], &data[cur_ix_masked], max_length); if (len >= 4) { const score_t score = BackwardReferenceScoreUsingLastDistance(len); if (best_score < score) { - best_score = score; - best_len = len; out->len = len; out->distance = cached_backward; - out->score = best_score; - compare_char = data[cur_ix_masked + best_len]; + out->score = score; if (BUCKET_SWEEP == 1) { - self->buckets_[key] = (uint32_t)cur_ix; + buckets[key] = (uint32_t)cur_ix; return; + } else { + best_len = len; + best_score = score; + compare_char = data[cur_ix_masked + len]; } } } @@ -169,8 +191,8 @@ static BROTLI_INLINE void FN(FindLongestMatch)( size_t backward; size_t len; /* Only one to look for, don't bother to prepare for a loop. */ - prev_ix = self->buckets_[key]; - self->buckets_[key] = (uint32_t)cur_ix; + prev_ix = buckets[key]; + buckets[key] = (uint32_t)cur_ix; backward = cur_ix - prev_ix; prev_ix &= (uint32_t)ring_buffer_mask; if (compare_char != data[prev_ix + best_len_in]) { @@ -192,12 +214,17 @@ static BROTLI_INLINE void FN(FindLongestMatch)( } } } else { - uint32_t* bucket = self->buckets_ + key; - int i; - prev_ix = *bucket++; - for (i = 0; i < BUCKET_SWEEP; ++i, prev_ix = *bucket++) { - const size_t backward = cur_ix - prev_ix; + size_t keys[BUCKET_SWEEP]; + size_t i; + for (i = 0; i < BUCKET_SWEEP; ++i) { + keys[i] = (key + (i << 3)) & BUCKET_MASK; + } + key_out = keys[(cur_ix & BUCKET_SWEEP_MASK) >> 3]; + for (i = 0; i < BUCKET_SWEEP; ++i) { size_t len; + size_t backward; + prev_ix = buckets[keys[i]]; + backward = cur_ix - prev_ix; prev_ix &= (uint32_t)ring_buffer_mask; if (compare_char != data[prev_ix + best_len]) { continue; @@ -211,25 +238,29 @@ static BROTLI_INLINE void FN(FindLongestMatch)( if (len >= 4) { const score_t score = BackwardReferenceScore(len, backward); if (best_score < score) { - best_score = score; best_len = len; - out->len = best_len; - out->distance = backward; + out->len = len; + compare_char = data[cur_ix_masked + len]; + best_score = score; out->score = score; - compare_char = data[cur_ix_masked + best_len]; + out->distance = backward; } } } } if (USE_DICTIONARY && min_score == out->score) { SearchInStaticDictionary(dictionary, - handle, &data[cur_ix_masked], max_length, max_backward + gap, + self->common, &data[cur_ix_masked], max_length, dictionary_distance, max_distance, out, BROTLI_TRUE); } - self->buckets_[key + ((cur_ix >> 3) % BUCKET_SWEEP)] = (uint32_t)cur_ix; + if (BUCKET_SWEEP != 1) { + buckets[key_out] = (uint32_t)cur_ix; + } } -#undef HASH_MAP_SIZE +#undef BUCKET_SWEEP_MASK +#undef BUCKET_SWEEP +#undef BUCKET_MASK #undef BUCKET_SIZE #undef HashLongestMatchQuickly diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_rolling_inc.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_rolling_inc.h index 17f8a408e24..586ae738591 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_rolling_inc.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_rolling_inc.h @@ -51,13 +51,9 @@ typedef struct HashRolling { uint32_t factor_remove; } HashRolling; -static BROTLI_INLINE HashRolling* FN(Self)(HasherHandle handle) { - return (HashRolling*)&(GetHasherCommon(handle)[1]); -} - static void FN(Initialize)( - HasherHandle handle, const BrotliEncoderParams* params) { - HashRolling* self = FN(Self)(handle); + HasherCommon* common, HashRolling* BROTLI_RESTRICT self, + const BrotliEncoderParams* params) { size_t i; self->state = 0; self->next_ix = 0; @@ -71,7 +67,7 @@ static void FN(Initialize)( self->factor_remove *= self->factor; } - self->table = (uint32_t*)((HasherHandle)self + sizeof(HashRolling)); + self->table = (uint32_t*)common->extra; for (i = 0; i < NUMBUCKETS; i++) { self->table[i] = FN(kInvalidPos); } @@ -79,9 +75,8 @@ static void FN(Initialize)( BROTLI_UNUSED(params); } -static void FN(Prepare)(HasherHandle handle, BROTLI_BOOL one_shot, - size_t input_size, const uint8_t* data) { - HashRolling* self = FN(Self)(handle); +static void FN(Prepare)(HashRolling* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, + size_t input_size, const uint8_t* BROTLI_RESTRICT data) { size_t i; /* Too small size, cannot use this hasher. */ if (input_size < CHUNKLEN) return; @@ -96,36 +91,36 @@ static void FN(Prepare)(HasherHandle handle, BROTLI_BOOL one_shot, static BROTLI_INLINE size_t FN(HashMemAllocInBytes)( const BrotliEncoderParams* params, BROTLI_BOOL one_shot, size_t input_size) { - return sizeof(HashRolling) + NUMBUCKETS * sizeof(uint32_t); + return NUMBUCKETS * sizeof(uint32_t); BROTLI_UNUSED(params); BROTLI_UNUSED(one_shot); BROTLI_UNUSED(input_size); } -static BROTLI_INLINE void FN(Store)(HasherHandle BROTLI_RESTRICT handle, +static BROTLI_INLINE void FN(Store)(HashRolling* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { - BROTLI_UNUSED(handle); + BROTLI_UNUSED(self); BROTLI_UNUSED(data); BROTLI_UNUSED(mask); BROTLI_UNUSED(ix); } -static BROTLI_INLINE void FN(StoreRange)(HasherHandle handle, - const uint8_t* data, const size_t mask, const size_t ix_start, - const size_t ix_end) { - BROTLI_UNUSED(handle); +static BROTLI_INLINE void FN(StoreRange)(HashRolling* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, const size_t mask, + const size_t ix_start, const size_t ix_end) { + BROTLI_UNUSED(self); BROTLI_UNUSED(data); BROTLI_UNUSED(mask); BROTLI_UNUSED(ix_start); BROTLI_UNUSED(ix_end); } -static BROTLI_INLINE void FN(StitchToPreviousBlock)(HasherHandle handle, +static BROTLI_INLINE void FN(StitchToPreviousBlock)( + HashRolling* BROTLI_RESTRICT self, size_t num_bytes, size_t position, const uint8_t* ringbuffer, size_t ring_buffer_mask) { /* In this case we must re-initialize the hasher from scratch from the current position. */ - HashRolling* self = FN(Self)(handle); size_t position_masked; size_t available = num_bytes; if ((position & (JUMP - 1)) != 0) { @@ -139,28 +134,29 @@ static BROTLI_INLINE void FN(StitchToPreviousBlock)(HasherHandle handle, available = ring_buffer_mask - position_masked; } - FN(Prepare)(handle, BROTLI_FALSE, available, + FN(Prepare)(self, BROTLI_FALSE, available, ringbuffer + (position & ring_buffer_mask)); self->next_ix = position; BROTLI_UNUSED(num_bytes); } static BROTLI_INLINE void FN(PrepareDistanceCache)( - HasherHandle handle, int* BROTLI_RESTRICT distance_cache) { - BROTLI_UNUSED(handle); + HashRolling* BROTLI_RESTRICT self, + int* BROTLI_RESTRICT distance_cache) { + BROTLI_UNUSED(self); BROTLI_UNUSED(distance_cache); } -static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle, +static BROTLI_INLINE void FN(FindLongestMatch)( + HashRolling* BROTLI_RESTRICT self, const BrotliEncoderDictionary* dictionary, const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix, const size_t max_length, const size_t max_backward, - const size_t gap, const size_t max_distance, + const size_t dictionary_distance, const size_t max_distance, HasherSearchResult* BROTLI_RESTRICT out) { - HashRolling* self = FN(Self)(handle); const size_t cur_ix_masked = cur_ix & ring_buffer_mask; - size_t pos = self->next_ix; + size_t pos; if ((cur_ix & (JUMP - 1)) != 0) return; @@ -209,7 +205,7 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle, backup-hasher, the main hasher already searches in it. */ BROTLI_UNUSED(dictionary); BROTLI_UNUSED(distance_cache); - BROTLI_UNUSED(gap); + BROTLI_UNUSED(dictionary_distance); BROTLI_UNUSED(max_distance); } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_to_binary_tree_inc.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_to_binary_tree_inc.h index 7fb0356f556..9880e0aef68 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_to_binary_tree_inc.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/hash_to_binary_tree_inc.h @@ -24,7 +24,7 @@ static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return MAX_TREE_COMP_LENGTH; } -static uint32_t FN(HashBytes)(const uint8_t* data) { +static uint32_t FN(HashBytes)(const uint8_t* BROTLI_RESTRICT data) { uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; /* The higher bits contain more mixture from the multiplication, so we take our results from there. */ @@ -38,7 +38,7 @@ typedef struct HashToBinaryTree { /* Hash table that maps the 4-byte hashes of the sequence to the last position where this hash was found, which is the root of the binary tree of sequences that share this hash bucket. */ - uint32_t buckets_[BUCKET_SIZE]; + uint32_t* buckets_; /* uint32_t[BUCKET_SIZE]; */ /* A position used to mark a non-existent sequence, i.e. a tree is empty if its root is at invalid_pos_ and a node is a leaf if both its children @@ -51,34 +51,30 @@ typedef struct HashToBinaryTree { corresponding to a hash is a sequence starting at buckets_[hash] and the left and right children of a sequence starting at pos are forest_[2 * pos] and forest_[2 * pos + 1]. */ - /* uint32_t forest[2 * num_nodes] */ + uint32_t* forest_; /* uint32_t[2 * num_nodes] */ } HashToBinaryTree; -static BROTLI_INLINE HashToBinaryTree* FN(Self)(HasherHandle handle) { - return (HashToBinaryTree*)&(GetHasherCommon(handle)[1]); -} - -static BROTLI_INLINE uint32_t* FN(Forest)(HashToBinaryTree* self) { - return (uint32_t*)(&self[1]); -} - static void FN(Initialize)( - HasherHandle handle, const BrotliEncoderParams* params) { - HashToBinaryTree* self = FN(Self)(handle); + HasherCommon* common, HashToBinaryTree* BROTLI_RESTRICT self, + const BrotliEncoderParams* params) { + self->buckets_ = (uint32_t*)common->extra; + self->forest_ = &self->buckets_[BUCKET_SIZE]; + self->window_mask_ = (1u << params->lgwin) - 1u; self->invalid_pos_ = (uint32_t)(0 - self->window_mask_); } -static void FN(Prepare)(HasherHandle handle, BROTLI_BOOL one_shot, - size_t input_size, const uint8_t* data) { - HashToBinaryTree* self = FN(Self)(handle); +static void FN(Prepare) + (HashToBinaryTree* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, + size_t input_size, const uint8_t* BROTLI_RESTRICT data) { uint32_t invalid_pos = self->invalid_pos_; uint32_t i; + uint32_t* BROTLI_RESTRICT buckets = self->buckets_; BROTLI_UNUSED(data); BROTLI_UNUSED(one_shot); BROTLI_UNUSED(input_size); for (i = 0; i < BUCKET_SIZE; i++) { - self->buckets_[i] = invalid_pos; + buckets[i] = invalid_pos; } } @@ -89,15 +85,17 @@ static BROTLI_INLINE size_t FN(HashMemAllocInBytes)( if (one_shot && input_size < num_nodes) { num_nodes = input_size; } - return sizeof(HashToBinaryTree) + 2 * sizeof(uint32_t) * num_nodes; + return sizeof(uint32_t) * BUCKET_SIZE + 2 * sizeof(uint32_t) * num_nodes; } -static BROTLI_INLINE size_t FN(LeftChildIndex)(HashToBinaryTree* self, +static BROTLI_INLINE size_t FN(LeftChildIndex)( + HashToBinaryTree* BROTLI_RESTRICT self, const size_t pos) { return 2 * (pos & self->window_mask_); } -static BROTLI_INLINE size_t FN(RightChildIndex)(HashToBinaryTree* self, +static BROTLI_INLINE size_t FN(RightChildIndex)( + HashToBinaryTree* BROTLI_RESTRICT self, const size_t pos) { return 2 * (pos & self->window_mask_) + 1; } @@ -113,7 +111,7 @@ static BROTLI_INLINE size_t FN(RightChildIndex)(HashToBinaryTree* self, This function must be called with increasing cur_ix positions. */ static BROTLI_INLINE BackwardMatch* FN(StoreAndFindMatches)( - HashToBinaryTree* self, const uint8_t* const BROTLI_RESTRICT data, + HashToBinaryTree* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data, const size_t cur_ix, const size_t ring_buffer_mask, const size_t max_length, const size_t max_backward, size_t* const BROTLI_RESTRICT best_len, BackwardMatch* BROTLI_RESTRICT matches) { @@ -123,8 +121,9 @@ static BROTLI_INLINE BackwardMatch* FN(StoreAndFindMatches)( const BROTLI_BOOL should_reroot_tree = TO_BROTLI_BOOL(max_length >= MAX_TREE_COMP_LENGTH); const uint32_t key = FN(HashBytes)(&data[cur_ix_masked]); - uint32_t* forest = FN(Forest)(self); - size_t prev_ix = self->buckets_[key]; + uint32_t* BROTLI_RESTRICT buckets = self->buckets_; + uint32_t* BROTLI_RESTRICT forest = self->forest_; + size_t prev_ix = buckets[key]; /* The forest index of the rightmost node of the left subtree of the new root, updated as we traverse and re-root the tree of the hash bucket. */ size_t node_left = FN(LeftChildIndex)(self, cur_ix); @@ -139,7 +138,7 @@ static BROTLI_INLINE BackwardMatch* FN(StoreAndFindMatches)( size_t best_len_right = 0; size_t depth_remaining; if (should_reroot_tree) { - self->buckets_[key] = (uint32_t)cur_ix; + buckets[key] = (uint32_t)cur_ix; } for (depth_remaining = MAX_TREE_SEARCH_DEPTH; ; --depth_remaining) { const size_t backward = cur_ix - prev_ix; @@ -199,11 +198,13 @@ static BROTLI_INLINE BackwardMatch* FN(StoreAndFindMatches)( matches in matches[0] to matches[*num_matches - 1]. The matches will be sorted by strictly increasing length and (non-strictly) increasing distance. */ -static BROTLI_INLINE size_t FN(FindAllMatches)(HasherHandle handle, - const BrotliEncoderDictionary* dictionary, const uint8_t* data, +static BROTLI_INLINE size_t FN(FindAllMatches)( + HashToBinaryTree* BROTLI_RESTRICT self, + const BrotliEncoderDictionary* dictionary, + const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, const size_t cur_ix, const size_t max_length, const size_t max_backward, - const size_t gap, const BrotliEncoderParams* params, + const size_t dictionary_distance, const BrotliEncoderParams* params, BackwardMatch* matches) { BackwardMatch* const orig_matches = matches; const size_t cur_ix_masked = cur_ix & ring_buffer_mask; @@ -236,7 +237,7 @@ static BROTLI_INLINE size_t FN(FindAllMatches)(HasherHandle handle, } } if (best_len < max_length) { - matches = FN(StoreAndFindMatches)(FN(Self)(handle), data, cur_ix, + matches = FN(StoreAndFindMatches)(self, data, cur_ix, ring_buffer_mask, max_length, max_backward, &best_len, matches); } for (i = 0; i <= BROTLI_MAX_STATIC_DICTIONARY_MATCH_LEN; ++i) { @@ -252,7 +253,7 @@ static BROTLI_INLINE size_t FN(FindAllMatches)(HasherHandle handle, for (l = minlen; l <= maxlen; ++l) { uint32_t dict_id = dict_matches[l]; if (dict_id < kInvalidMatch) { - size_t distance = max_backward + gap + (dict_id >> 5) + 1; + size_t distance = dictionary_distance + (dict_id >> 5) + 1; if (distance <= params->dist.max_distance) { InitDictionaryBackwardMatch(matches++, distance, l, dict_id & 31); } @@ -266,18 +267,18 @@ static BROTLI_INLINE size_t FN(FindAllMatches)(HasherHandle handle, /* Stores the hash of the next 4 bytes and re-roots the binary tree at the current sequence, without returning any matches. REQUIRES: ix + MAX_TREE_COMP_LENGTH <= end-of-current-block */ -static BROTLI_INLINE void FN(Store)(HasherHandle handle, const uint8_t* data, +static BROTLI_INLINE void FN(Store)(HashToBinaryTree* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { - HashToBinaryTree* self = FN(Self)(handle); /* Maximum distance is window size - 16, see section 9.1. of the spec. */ const size_t max_backward = self->window_mask_ - BROTLI_WINDOW_GAP + 1; FN(StoreAndFindMatches)(self, data, ix, mask, MAX_TREE_COMP_LENGTH, max_backward, NULL, NULL); } -static BROTLI_INLINE void FN(StoreRange)(HasherHandle handle, - const uint8_t* data, const size_t mask, const size_t ix_start, - const size_t ix_end) { +static BROTLI_INLINE void FN(StoreRange)(HashToBinaryTree* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, const size_t mask, + const size_t ix_start, const size_t ix_end) { size_t i = ix_start; size_t j = ix_start; if (ix_start + 63 <= ix_end) { @@ -285,18 +286,18 @@ static BROTLI_INLINE void FN(StoreRange)(HasherHandle handle, } if (ix_start + 512 <= i) { for (; j < i; j += 8) { - FN(Store)(handle, data, mask, j); + FN(Store)(self, data, mask, j); } } for (; i < ix_end; ++i) { - FN(Store)(handle, data, mask, i); + FN(Store)(self, data, mask, i); } } -static BROTLI_INLINE void FN(StitchToPreviousBlock)(HasherHandle handle, +static BROTLI_INLINE void FN(StitchToPreviousBlock)( + HashToBinaryTree* BROTLI_RESTRICT self, size_t num_bytes, size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask) { - HashToBinaryTree* self = FN(Self)(handle); if (num_bytes >= FN(HashTypeLength)() - 1 && position >= MAX_TREE_COMP_LENGTH) { /* Store the last `MAX_TREE_COMP_LENGTH - 1` positions in the hasher. diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/memory.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/memory.h index ab928d019be..832e7b2b6e3 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/memory.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/memory.h @@ -56,6 +56,18 @@ BROTLI_INTERNAL void BrotliFree(MemoryManager* m, void* p); #define BROTLI_IS_OOM(M) (!!(M)->is_oom) #endif /* BROTLI_ENCODER_EXIT_ON_OOM */ +/* +BROTLI_IS_NULL is a fake check, BROTLI_IS_OOM does the heavy lifting. +The only purpose of it is to explain static analyzers the state of things. +NB: use ONLY together with BROTLI_IS_OOM + AND ONLY for allocations in the current scope. + */ +#if defined(__clang_analyzer__) && !defined(BROTLI_ENCODER_EXIT_ON_OOM) +#define BROTLI_IS_NULL(A) ((A) == nullptr) +#else /* defined(__clang_analyzer__) */ +#define BROTLI_IS_NULL(A) (!!0) +#endif /* defined(__clang_analyzer__) */ + BROTLI_INTERNAL void BrotliWipeOutMemoryManager(MemoryManager* m); /* @@ -66,18 +78,18 @@ A: array C: capacity R: requested size */ -#define BROTLI_ENSURE_CAPACITY(M, T, A, C, R) { \ - if (C < (R)) { \ - size_t _new_size = (C == 0) ? (R) : C; \ - T* new_array; \ - while (_new_size < (R)) _new_size *= 2; \ - new_array = BROTLI_ALLOC((M), T, _new_size); \ - if (!BROTLI_IS_OOM(M) && C != 0) \ - memcpy(new_array, A, C * sizeof(T)); \ - BROTLI_FREE((M), A); \ - A = new_array; \ - C = _new_size; \ - } \ +#define BROTLI_ENSURE_CAPACITY(M, T, A, C, R) { \ + if (C < (R)) { \ + size_t _new_size = (C == 0) ? (R) : C; \ + T* new_array; \ + while (_new_size < (R)) _new_size *= 2; \ + new_array = BROTLI_ALLOC((M), T, _new_size); \ + if (!BROTLI_IS_OOM(M) && !BROTLI_IS_NULL(new_array) && C != 0) \ + memcpy(new_array, A, C * sizeof(T)); \ + BROTLI_FREE((M), A); \ + A = new_array; \ + C = _new_size; \ + } \ } /* diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/metablock.c b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/metablock.c index 4e80044f318..5aa4d4f17c8 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/metablock.c +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/metablock.c @@ -28,34 +28,30 @@ extern "C" { void BrotliInitDistanceParams(BrotliEncoderParams* params, uint32_t npostfix, uint32_t ndirect) { BrotliDistanceParams* dist_params = ¶ms->dist; - uint32_t alphabet_size, max_distance; + uint32_t alphabet_size_max; + uint32_t alphabet_size_limit; + uint32_t max_distance; dist_params->distance_postfix_bits = npostfix; dist_params->num_direct_distance_codes = ndirect; - alphabet_size = BROTLI_DISTANCE_ALPHABET_SIZE( + alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE( npostfix, ndirect, BROTLI_MAX_DISTANCE_BITS); + alphabet_size_limit = alphabet_size_max; max_distance = ndirect + (1U << (BROTLI_MAX_DISTANCE_BITS + npostfix + 2)) - (1U << (npostfix + 2)); if (params->large_window) { - static const uint32_t bound[BROTLI_MAX_NPOSTFIX + 1] = {0, 4, 12, 28}; - uint32_t postfix = 1U << npostfix; - alphabet_size = BROTLI_DISTANCE_ALPHABET_SIZE( + BrotliDistanceCodeLimit limit = BrotliCalculateDistanceCodeLimit( + BROTLI_MAX_ALLOWED_DISTANCE, npostfix, ndirect); + alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE( npostfix, ndirect, BROTLI_LARGE_MAX_DISTANCE_BITS); - /* The maximum distance is set so that no distance symbol used can encode - a distance larger than BROTLI_MAX_ALLOWED_DISTANCE with all - its extra bits set. */ - if (ndirect < bound[npostfix]) { - max_distance = BROTLI_MAX_ALLOWED_DISTANCE - (bound[npostfix] - ndirect); - } else if (ndirect >= bound[npostfix] + postfix) { - max_distance = (3U << 29) - 4 + (ndirect - bound[npostfix]); - } else { - max_distance = BROTLI_MAX_ALLOWED_DISTANCE; - } + alphabet_size_limit = limit.max_alphabet_size; + max_distance = limit.max_distance; } - dist_params->alphabet_size = alphabet_size; + dist_params->alphabet_size_max = alphabet_size_max; + dist_params->alphabet_size_limit = alphabet_size_limit; dist_params->max_distance = max_distance; } @@ -200,7 +196,7 @@ void BrotliBuildMetaBlock(MemoryManager* m, literal_context_multiplier = 1 << BROTLI_LITERAL_CONTEXT_BITS; literal_context_modes = BROTLI_ALLOC(m, ContextType, mb->literal_split.num_types); - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(literal_context_modes)) return; for (i = 0; i < mb->literal_split.num_types; ++i) { literal_context_modes[i] = literal_context_mode; } @@ -210,21 +206,21 @@ void BrotliBuildMetaBlock(MemoryManager* m, mb->literal_split.num_types * literal_context_multiplier; literal_histograms = BROTLI_ALLOC(m, HistogramLiteral, literal_histograms_size); - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(literal_histograms)) return; ClearHistogramsLiteral(literal_histograms, literal_histograms_size); distance_histograms_size = mb->distance_split.num_types << BROTLI_DISTANCE_CONTEXT_BITS; distance_histograms = BROTLI_ALLOC(m, HistogramDistance, distance_histograms_size); - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(distance_histograms)) return; ClearHistogramsDistance(distance_histograms, distance_histograms_size); BROTLI_DCHECK(mb->command_histograms == 0); mb->command_histograms_size = mb->command_split.num_types; mb->command_histograms = BROTLI_ALLOC(m, HistogramCommand, mb->command_histograms_size); - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(mb->command_histograms)) return; ClearHistogramsCommand(mb->command_histograms, mb->command_histograms_size); BrotliBuildHistogramsWithContext(cmds, num_commands, @@ -238,13 +234,13 @@ void BrotliBuildMetaBlock(MemoryManager* m, mb->literal_split.num_types << BROTLI_LITERAL_CONTEXT_BITS; mb->literal_context_map = BROTLI_ALLOC(m, uint32_t, mb->literal_context_map_size); - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(mb->literal_context_map)) return; BROTLI_DCHECK(mb->literal_histograms == 0); mb->literal_histograms_size = mb->literal_context_map_size; mb->literal_histograms = BROTLI_ALLOC(m, HistogramLiteral, mb->literal_histograms_size); - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(mb->literal_histograms)) return; BrotliClusterHistogramsLiteral(m, literal_histograms, literal_histograms_size, kMaxNumberOfHistograms, mb->literal_histograms, @@ -269,13 +265,13 @@ void BrotliBuildMetaBlock(MemoryManager* m, mb->distance_split.num_types << BROTLI_DISTANCE_CONTEXT_BITS; mb->distance_context_map = BROTLI_ALLOC(m, uint32_t, mb->distance_context_map_size); - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(mb->distance_context_map)) return; BROTLI_DCHECK(mb->distance_histograms == 0); mb->distance_histograms_size = mb->distance_context_map_size; mb->distance_histograms = BROTLI_ALLOC(m, HistogramDistance, mb->distance_histograms_size); - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(mb->distance_histograms)) return; BrotliClusterHistogramsDistance(m, distance_histograms, mb->distance_context_map_size, @@ -373,7 +369,7 @@ static void InitContextBlockSplitter( *histograms_size = max_num_types * num_contexts; *histograms = BROTLI_ALLOC(m, HistogramLiteral, *histograms_size); self->histograms_ = *histograms; - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(*histograms)) return; /* Clear only current histogram. */ ClearHistogramsLiteral(&self->histograms_[0], num_contexts); self->last_histogram_ix_[0] = self->last_histogram_ix_[1] = 0; @@ -423,7 +419,7 @@ static void ContextBlockSplitterFinishBlock( double combined_entropy[2 * BROTLI_MAX_STATIC_CONTEXTS]; double diff[2] = { 0.0 }; size_t i; - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(combined_histo)) return; for (i = 0; i < num_contexts; ++i) { size_t curr_histo_ix = self->curr_histogram_ix_ + i; size_t j; @@ -527,7 +523,7 @@ static void MapStaticContexts(MemoryManager* m, mb->literal_split.num_types << BROTLI_LITERAL_CONTEXT_BITS; mb->literal_context_map = BROTLI_ALLOC(m, uint32_t, mb->literal_context_map_size); - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(mb->literal_context_map)) return; for (i = 0; i < mb->literal_split.num_types; ++i) { uint32_t offset = (uint32_t)(i * num_contexts); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/metablock_inc.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/metablock_inc.h index dcc9d3c4a64..ed507ef5ef4 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/metablock_inc.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/metablock_inc.h @@ -71,7 +71,7 @@ static void FN(InitBlockSplitter)( *histograms_size = max_num_types; *histograms = BROTLI_ALLOC(m, HistogramType, *histograms_size); self->histograms_ = *histograms; - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(*histograms)) return; /* Clear only current histogram. */ FN(HistogramClear)(&self->histograms_[0]); self->last_histogram_ix_[0] = self->last_histogram_ix_[1] = 0; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/params.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/params.h index 6ecf1d3f995..54a7f007363 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/params.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/params.h @@ -23,7 +23,8 @@ typedef struct BrotliHasherParams { typedef struct BrotliDistanceParams { uint32_t distance_postfix_bits; uint32_t num_direct_distance_codes; - uint32_t alphabet_size; + uint32_t alphabet_size_max; + uint32_t alphabet_size_limit; size_t max_distance; } BrotliDistanceParams; @@ -33,6 +34,7 @@ typedef struct BrotliEncoderParams { int quality; int lgwin; int lgblock; + size_t stream_offset; size_t size_hint; BROTLI_BOOL disable_literal_context_modeling; BROTLI_BOOL large_window; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/ringbuffer.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/ringbuffer.h index 86079a89d35..8dce1480399 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/ringbuffer.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/ringbuffer.h @@ -75,7 +75,7 @@ static BROTLI_INLINE void RingBufferInitBuffer( uint8_t* new_data = BROTLI_ALLOC( m, uint8_t, 2 + buflen + kSlackForEightByteHashingEverywhere); size_t i; - if (BROTLI_IS_OOM(m)) return; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(new_data)) return; if (rb->data_) { memcpy(new_data, rb->data_, 2 + rb->cur_size_ + kSlackForEightByteHashingEverywhere); @@ -125,6 +125,9 @@ static BROTLI_INLINE void RingBufferWrite( later when we copy the last two bytes to the first two positions. */ rb->buffer_[rb->size_ - 2] = 0; rb->buffer_[rb->size_ - 1] = 0; + /* Initialize tail; might be touched by "best_len++" optimization when + ring buffer is "full". */ + rb->buffer_[rb->size_] = 241; } { const size_t masked_pos = rb->pos_ & rb->mask_; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/utf8_util.c b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/utf8_util.c index 04a7805161b..e802b6a7517 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/utf8_util.c +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/utf8_util.c @@ -77,7 +77,7 @@ BROTLI_BOOL BrotliIsMostlyUTF8( i += bytes_read; if (symbol < 0x110000) size_utf8 += bytes_read; } - return TO_BROTLI_BOOL(size_utf8 > min_fraction * (double)length); + return TO_BROTLI_BOOL((double)size_utf8 > min_fraction * (double)length); } #if defined(__cplusplus) || defined(c_plusplus) diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/write_bits.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/write_bits.h index 36515a6893f..f6f88b45be0 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/write_bits.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/enc/write_bits.h @@ -16,8 +16,6 @@ extern "C" { #endif -/*#define BIT_WRITER_DEBUG */ - /* This function writes bits into bytes in increasing addresses, and within a byte least-significant-bit first. @@ -28,7 +26,7 @@ extern "C" { 0000 0RRR 0000 0000 0000 0000 - Now, we could write 5 or less bits in MSB by just sifting by 3 + Now, we could write 5 or less bits in MSB by just shifting by 3 and OR'ing to BYTE-0. For n bits, we take the last 5 bits, OR that with high bits in BYTE-0, @@ -37,37 +35,41 @@ static BROTLI_INLINE void BrotliWriteBits(size_t n_bits, uint64_t bits, size_t* BROTLI_RESTRICT pos, uint8_t* BROTLI_RESTRICT array) { + BROTLI_LOG(("WriteBits %2d 0x%08x%08x %10d\n", (int)n_bits, + (uint32_t)(bits >> 32), (uint32_t)(bits & 0xFFFFFFFF), + (int)*pos)); + BROTLI_DCHECK((bits >> n_bits) == 0); + BROTLI_DCHECK(n_bits <= 56); #if defined(BROTLI_LITTLE_ENDIAN) /* This branch of the code can write up to 56 bits at a time, 7 bits are lost by being perhaps already in *p and at least 1 bit is needed to initialize the bit-stream ahead (i.e. if 7 bits are in *p and we write 57 bits, then the next write will access a byte that was never initialized). */ - uint8_t* p = &array[*pos >> 3]; - uint64_t v = (uint64_t)(*p); /* Zero-extend 8 to 64 bits. */ - BROTLI_LOG(("WriteBits %2d 0x%08x%08x %10d\n", (int)n_bits, - (uint32_t)(bits >> 32), (uint32_t)(bits & 0xFFFFFFFF), - (int)*pos)); - BROTLI_DCHECK((bits >> n_bits) == 0); - BROTLI_DCHECK(n_bits <= 56); - v |= bits << (*pos & 7); - BROTLI_UNALIGNED_STORE64LE(p, v); /* Set some bits. */ - *pos += n_bits; + { + uint8_t* p = &array[*pos >> 3]; + uint64_t v = (uint64_t)(*p); /* Zero-extend 8 to 64 bits. */ + v |= bits << (*pos & 7); + BROTLI_UNALIGNED_STORE64LE(p, v); /* Set some bits. */ + *pos += n_bits; + } #else /* implicit & 0xFF is assumed for uint8_t arithmetics */ - uint8_t* array_pos = &array[*pos >> 3]; - const size_t bits_reserved_in_first_byte = (*pos & 7); - size_t bits_left_to_write; - bits <<= bits_reserved_in_first_byte; - *array_pos++ |= (uint8_t)bits; - for (bits_left_to_write = n_bits + bits_reserved_in_first_byte; - bits_left_to_write >= 9; - bits_left_to_write -= 8) { - bits >>= 8; - *array_pos++ = (uint8_t)bits; + { + uint8_t* array_pos = &array[*pos >> 3]; + const size_t bits_reserved_in_first_byte = (*pos & 7); + size_t bits_left_to_write; + bits <<= bits_reserved_in_first_byte; + *array_pos++ |= (uint8_t)bits; + for (bits_left_to_write = n_bits + bits_reserved_in_first_byte; + bits_left_to_write >= 9; + bits_left_to_write -= 8) { + bits >>= 8; + *array_pos++ = (uint8_t)bits; + } + *array_pos = 0; + *pos += n_bits; } - *array_pos = 0; - *pos += n_bits; #endif } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/include/brotli/encode.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/include/brotli/encode.h index 0ced7e55be7..b2774cb6316 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/include/brotli/encode.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/include/brotli/encode.h @@ -201,7 +201,23 @@ typedef enum BrotliEncoderParameter { * * Range is from 0 to (15 << NPOSTFIX) in steps of (1 << NPOSTFIX). */ - BROTLI_PARAM_NDIRECT = 8 + BROTLI_PARAM_NDIRECT = 8, + /** + * Number of bytes of input stream already processed by a different instance. + * + * @note It is important to configure all the encoder instances with same + * parameters (except this one) in order to allow all the encoded parts + * obey the same restrictions implied by header. + * + * If offset is not 0, then stream header is omitted. + * In any case output start is byte aligned, so for proper streams stitching + * "predecessor" stream must be flushed. + * + * Range is not artificially limited, but all the values greater or equal to + * maximal window size have the same effect. Values greater than 2**30 are not + * allowed. + */ + BROTLI_PARAM_STREAM_OFFSET = 9 } BrotliEncoderParameter; /** @@ -274,6 +290,11 @@ BROTLI_ENC_API size_t BrotliEncoderMaxCompressedSize(size_t input_size); * @note If ::BrotliEncoderMaxCompressedSize(@p input_size) returns non-zero * value, then output is guaranteed to be no longer than that. * + * @note If @p lgwin is greater than ::BROTLI_MAX_WINDOW_BITS then resulting + * stream might be incompatible with RFC 7932; to decode such streams, + * decoder should be configured with + * ::BROTLI_DECODER_PARAM_LARGE_WINDOW = @c 1 + * * @param quality quality parameter value, e.g. ::BROTLI_DEFAULT_QUALITY * @param lgwin lgwin parameter value, e.g. ::BROTLI_DEFAULT_WINDOW * @param mode mode parameter value, e.g. ::BROTLI_DEFAULT_MODE diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/include/brotli/port.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/include/brotli/port.h index 20dc2314d80..825237a3357 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/include/brotli/port.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/brotli/include/brotli/port.h @@ -218,6 +218,20 @@ BROTLI_GNUC_VERSION_CHECK(major, minor, patch) #endif +#if defined(__has_feature) +#define BROTLI_HAS_FEATURE(feature) __has_feature(feature) +#else +#define BROTLI_HAS_FEATURE(feature) (0) +#endif + +#if defined(ADDRESS_SANITIZER) || BROTLI_HAS_FEATURE(address_sanitizer) || \ + defined(THREAD_SANITIZER) || BROTLI_HAS_FEATURE(thread_sanitizer) || \ + defined(MEMORY_SANITIZER) || BROTLI_HAS_FEATURE(memory_sanitizer) +#define BROTLI_SANITIZED 1 +#else +#define BROTLI_SANITIZED 0 +#endif + #if defined(_WIN32) || defined(__CYGWIN__) #define BROTLI_PUBLIC #elif BROTLI_GNUC_VERSION_CHECK(3, 3, 0) || \ diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/tmpfile2.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/tmpfile2.cpp index d9e5280b2cc..9e4a26dbfb7 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/tmpfile2.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/tmpfile2.cpp @@ -3,7 +3,7 @@ * works on POSIX and Windows systems. * License: Revised BSD license used by FontForge * https://github.com/fontforge/fontforge/blob/master/LICENSE -* (C) 2017-2020 Martin Gieseking <martin.gieseking@uos.de> */ +* (C) 2017-2021 Martin Gieseking <martin.gieseking@uos.de> */ #include <cstdio> #include <cstdlib> diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/xxHash/xxh3.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/xxHash/xxh3.h index 9e3e88ad61e..7e83e6418af 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/xxHash/xxh3.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/xxHash/xxh3.h @@ -1,7 +1,7 @@ /* * xxHash - Extremely Fast Hash algorithm * Development source file for `xxh3` - * Copyright (C) 2019-present, Yann Collet + * Copyright (C) 2019-2020 Yann Collet * * BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) * @@ -34,2079 +34,22 @@ */ /* - * Note: This file is separated for development purposes. - * It will be integrated into `xxhash.h` when development stage is completed. + * Note: This file used to host the source code of XXH3_* variants. + * during the development period. + * The source code is now properly integrated within xxhash.h. * - * Credit: most of the work on vectorial and asm variants comes from @easyaspi314 - */ - -#ifndef XXH3_H_1397135465 -#define XXH3_H_1397135465 - -/* === Dependencies === */ -#ifndef XXHASH_H_5627135585666179 -/* special: when including `xxh3.h` directly, turn on XXH_INLINE_ALL */ -# undef XXH_INLINE_ALL /* avoid redefinition */ -# define XXH_INLINE_ALL -#endif -#include "xxhash.h" - - -/* === Compiler specifics === */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */ -# define XXH_RESTRICT restrict -#else -/* Note: it might be useful to define __restrict or __restrict__ for some C++ compilers */ -# define XXH_RESTRICT /* disable */ -#endif - -#if (defined(__GNUC__) && (__GNUC__ >= 3)) \ - || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) \ - || defined(__clang__) -# define XXH_likely(x) __builtin_expect(x, 1) -# define XXH_unlikely(x) __builtin_expect(x, 0) -#else -# define XXH_likely(x) (x) -# define XXH_unlikely(x) (x) -#endif - -#if defined(__GNUC__) -# if defined(__AVX2__) -# include <immintrin.h> -# elif defined(__SSE2__) -# include <emmintrin.h> -# elif defined(__ARM_NEON__) || defined(__ARM_NEON) -# define inline __inline__ /* clang bug */ -# include <arm_neon.h> -# undef inline -# endif -#elif defined(_MSC_VER) -# include <intrin.h> -#endif - -/* - * One goal of XXH3 is to make it fast on both 32-bit and 64-bit, while - * remaining a true 64-bit/128-bit hash function. - * - * This is done by prioritizing a subset of 64-bit operations that can be - * emulated without too many steps on the average 32-bit machine. - * - * For example, these two lines seem similar, and run equally fast on 64-bit: - * - * xxh_u64 x; - * x ^= (x >> 47); // good - * x ^= (x >> 13); // bad - * - * However, to a 32-bit machine, there is a major difference. - * - * x ^= (x >> 47) looks like this: - * - * x.lo ^= (x.hi >> (47 - 32)); - * - * while x ^= (x >> 13) looks like this: - * - * // note: funnel shifts are not usually cheap. - * x.lo ^= (x.lo >> 13) | (x.hi << (32 - 13)); - * x.hi ^= (x.hi >> 13); - * - * The first one is significantly faster than the second, simply because the - * shift is larger than 32. This means: - * - All the bits we need are in the upper 32 bits, so we can ignore the lower - * 32 bits in the shift. - * - The shift result will always fit in the lower 32 bits, and therefore, - * we can ignore the upper 32 bits in the xor. - * - * Thanks to this optimization, XXH3 only requires these features to be efficient: - * - * - Usable unaligned access - * - A 32-bit or 64-bit ALU - * - If 32-bit, a decent ADC instruction - * - A 32 or 64-bit multiply with a 64-bit result - * - For the 128-bit variant, a decent byteswap helps short inputs. - * - * The first two are already required by XXH32, and almost all 32-bit and 64-bit - * platforms which can run XXH32 can run XXH3 efficiently. - * - * Thumb-1, the classic 16-bit only subset of ARM's instruction set, is one - * notable exception. - * - * First of all, Thumb-1 lacks support for the UMULL instruction which - * performs the important long multiply. This means numerous __aeabi_lmul - * calls. - * - * Second of all, the 8 functional registers are just not enough. - * Setup for __aeabi_lmul, byteshift loads, pointers, and all arithmetic need - * Lo registers, and this shuffling results in thousands more MOVs than A32. - * - * A32 and T32 don't have this limitation. They can access all 14 registers, - * do a 32->64 multiply with UMULL, and the flexible operand allowing free - * shifts is helpful, too. - * - * Therefore, we do a quick sanity check. - * - * If compiling Thumb-1 for a target which supports ARM instructions, we will - * emit a warning, as it is not a "sane" platform to compile for. - * - * Usually, if this happens, it is because of an accident and you probably need - * to specify -march, as you likely meant to compile for a newer architecture. - */ -#if defined(__thumb__) && !defined(__thumb2__) && defined(__ARM_ARCH_ISA_ARM) -# warning "XXH3 is highly inefficient without ARM or Thumb-2." -#endif - -/* ========================================== - * Vectorization detection - * ========================================== */ -#define XXH_SCALAR 0 /* Portable scalar version */ -#define XXH_SSE2 1 /* SSE2 for Pentium 4 and all x86_64 */ -#define XXH_AVX2 2 /* AVX2 for Haswell and Bulldozer */ -#define XXH_NEON 3 /* NEON for most ARMv7-A and all AArch64 */ -#define XXH_VSX 4 /* VSX and ZVector for POWER8/z13 */ - -#ifndef XXH_VECTOR /* can be defined on command line */ -# if defined(__AVX2__) -# define XXH_VECTOR XXH_AVX2 -# elif defined(__SSE2__) || defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP == 2)) -# define XXH_VECTOR XXH_SSE2 -# elif defined(__GNUC__) /* msvc support maybe later */ \ - && (defined(__ARM_NEON__) || defined(__ARM_NEON)) \ - && (defined(__LITTLE_ENDIAN__) /* We only support little endian NEON */ \ - || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) -# define XXH_VECTOR XXH_NEON -# elif (defined(__PPC64__) && defined(__POWER8_VECTOR__)) \ - || (defined(__s390x__) && defined(__VEC__)) \ - && defined(__GNUC__) /* TODO: IBM XL */ -# define XXH_VECTOR XXH_VSX -# else -# define XXH_VECTOR XXH_SCALAR -# endif -#endif - -/* - * Controls the alignment of the accumulator. - * This is for compatibility with aligned vector loads, which are usually faster. - */ -#ifndef XXH_ACC_ALIGN -# if XXH_VECTOR == XXH_SCALAR /* scalar */ -# define XXH_ACC_ALIGN 8 -# elif XXH_VECTOR == XXH_SSE2 /* sse2 */ -# define XXH_ACC_ALIGN 16 -# elif XXH_VECTOR == XXH_AVX2 /* avx2 */ -# define XXH_ACC_ALIGN 32 -# elif XXH_VECTOR == XXH_NEON /* neon */ -# define XXH_ACC_ALIGN 16 -# elif XXH_VECTOR == XXH_VSX /* vsx */ -# define XXH_ACC_ALIGN 16 -# endif -#endif - -/* - * UGLY HACK: - * GCC usually generates the best code with -O3 for xxHash. - * - * However, when targeting AVX2, it is overzealous in its unrolling resulting - * in code roughly 3/4 the speed of Clang. - * - * There are other issues, such as GCC splitting _mm256_loadu_si256 into - * _mm_loadu_si128 + _mm256_inserti128_si256. This is an optimization which - * only applies to Sandy and Ivy Bridge... which don't even support AVX2. - * - * That is why when compiling the AVX2 version, it is recommended to use either - * -O2 -mavx2 -march=haswell - * or - * -O2 -mavx2 -mno-avx256-split-unaligned-load - * for decent performance, or to use Clang instead. - * - * Fortunately, we can control the first one with a pragma that forces GCC into - * -O2, but the other one we can't control without "failed to inline always - * inline function due to target mismatch" warnings. - */ -#if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \ - && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \ - && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */ -# pragma GCC push_options -# pragma GCC optimize("-O2") -#endif - - -#if XXH_VECTOR == XXH_NEON -/* - * NEON's setup for vmlal_u32 is a little more complicated than it is on - * SSE2, AVX2, and VSX. - * - * While PMULUDQ and VMULEUW both perform a mask, VMLAL.U32 performs an upcast. - * - * To do the same operation, the 128-bit 'Q' register needs to be split into - * two 64-bit 'D' registers, performing this operation:: - * - * [ a | b ] - * | '---------. .--------' | - * | x | - * | .---------' '--------. | - * [ a & 0xFFFFFFFF | b & 0xFFFFFFFF ],[ a >> 32 | b >> 32 ] - * - * Due to significant changes in aarch64, the fastest method for aarch64 is - * completely different than the fastest method for ARMv7-A. - * - * ARMv7-A treats D registers as unions overlaying Q registers, so modifying - * D11 will modify the high half of Q5. This is similar to how modifying AH - * will only affect bits 8-15 of AX on x86. - * - * VZIP takes two registers, and puts even lanes in one register and odd lanes - * in the other. - * - * On ARMv7-A, this strangely modifies both parameters in place instead of - * taking the usual 3-operand form. - * - * Therefore, if we want to do this, we can simply use a D-form VZIP.32 on the - * lower and upper halves of the Q register to end up with the high and low - * halves where we want - all in one instruction. - * - * vzip.32 d10, d11 @ d10 = { d10[0], d11[0] }; d11 = { d10[1], d11[1] } - * - * Unfortunately we need inline assembly for this: Instructions modifying two - * registers at once is not possible in GCC or Clang's IR, and they have to - * create a copy. - * - * aarch64 requires a different approach. - * - * In order to make it easier to write a decent compiler for aarch64, many - * quirks were removed, such as conditional execution. - * - * NEON was also affected by this. - * - * aarch64 cannot access the high bits of a Q-form register, and writes to a - * D-form register zero the high bits, similar to how writes to W-form scalar - * registers (or DWORD registers on x86_64) work. - * - * The formerly free vget_high intrinsics now require a vext (with a few - * exceptions) - * - * Additionally, VZIP was replaced by ZIP1 and ZIP2, which are the equivalent - * of PUNPCKL* and PUNPCKH* in SSE, respectively, in order to only modify one - * operand. - * - * The equivalent of the VZIP.32 on the lower and upper halves would be this - * mess: - * - * ext v2.4s, v0.4s, v0.4s, #2 // v2 = { v0[2], v0[3], v0[0], v0[1] } - * zip1 v1.2s, v0.2s, v2.2s // v1 = { v0[0], v2[0] } - * zip2 v0.2s, v0.2s, v1.2s // v0 = { v0[1], v2[1] } - * - * Instead, we use a literal downcast, vmovn_u64 (XTN), and vshrn_n_u64 (SHRN): - * - * shrn v1.2s, v0.2d, #32 // v1 = (uint32x2_t)(v0 >> 32); - * xtn v0.2s, v0.2d // v0 = (uint32x2_t)(v0 & 0xFFFFFFFF); - * - * This is available on ARMv7-A, but is less efficient than a single VZIP.32. - */ - -/* - * Function-like macro: - * void XXH_SPLIT_IN_PLACE(uint64x2_t &in, uint32x2_t &outLo, uint32x2_t &outHi) - * { - * outLo = (uint32x2_t)(in & 0xFFFFFFFF); - * outHi = (uint32x2_t)(in >> 32); - * in = UNDEFINED; - * } - */ -# if !defined(XXH_NO_VZIP_HACK) /* define to disable */ \ - && defined(__GNUC__) \ - && !defined(__aarch64__) && !defined(__arm64__) -# define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \ - do { \ - /* Undocumented GCC/Clang operand modifier: %e0 = lower D half, %f0 = upper D half */ \ - /* https://github.com/gcc-mirror/gcc/blob/38cf91e5/gcc/config/arm/arm.c#L22486 */ \ - /* https://github.com/llvm-mirror/llvm/blob/2c4ca683/lib/Target/ARM/ARMAsmPrinter.cpp#L399 */ \ - __asm__("vzip.32 %e0, %f0" : "+w" (in)); \ - (outLo) = vget_low_u32 (vreinterpretq_u32_u64(in)); \ - (outHi) = vget_high_u32(vreinterpretq_u32_u64(in)); \ - } while (0) -# else -# define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \ - do { \ - (outLo) = vmovn_u64 (in); \ - (outHi) = vshrn_n_u64 ((in), 32); \ - } while (0) -# endif -#endif /* XXH_VECTOR == XXH_NEON */ - -/* - * VSX and Z Vector helpers. - * - * This is very messy, and any pull requests to clean this up are welcome. - * - * There are a lot of problems with supporting VSX and s390x, due to - * inconsistent intrinsics, spotty coverage, and multiple endiannesses. - */ -#if XXH_VECTOR == XXH_VSX -# if defined(__s390x__) -# include <s390intrin.h> -# else -# include <altivec.h> -# endif - -# undef vector /* Undo the pollution */ - -typedef __vector unsigned long long xxh_u64x2; -typedef __vector unsigned char xxh_u8x16; -typedef __vector unsigned xxh_u32x4; - -# ifndef XXH_VSX_BE -# if defined(__BIG_ENDIAN__) \ - || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) -# define XXH_VSX_BE 1 -# elif defined(__VEC_ELEMENT_REG_ORDER__) && __VEC_ELEMENT_REG_ORDER__ == __ORDER_BIG_ENDIAN__ -# warning "-maltivec=be is not recommended. Please use native endianness." -# define XXH_VSX_BE 1 -# else -# define XXH_VSX_BE 0 -# endif -# endif /* !defined(XXH_VSX_BE) */ - -# if XXH_VSX_BE -/* A wrapper for POWER9's vec_revb. */ -# if defined(__POWER9_VECTOR__) || (defined(__clang__) && defined(__s390x__)) -# define XXH_vec_revb vec_revb -# else -XXH_FORCE_INLINE xxh_u64x2 XXH_vec_revb(xxh_u64x2 val) -{ - xxh_u8x16 const vByteSwap = { 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08 }; - return vec_perm(val, val, vByteSwap); -} -# endif -# endif /* XXH_VSX_BE */ - -/* - * Performs an unaligned load and byte swaps it on big endian. - */ -XXH_FORCE_INLINE xxh_u64x2 XXH_vec_loadu(const void *ptr) -{ - xxh_u64x2 ret; - memcpy(&ret, ptr, sizeof(xxh_u64x2)); -# if XXH_VSX_BE - ret = XXH_vec_revb(ret); -# endif - return ret; -} - -/* - * vec_mulo and vec_mule are very problematic intrinsics on PowerPC - * - * These intrinsics weren't added until GCC 8, despite existing for a while, - * and they are endian dependent. Also, their meaning swap depending on version. - * */ -# if defined(__s390x__) - /* s390x is always big endian, no issue on this platform */ -# define XXH_vec_mulo vec_mulo -# define XXH_vec_mule vec_mule -# elif defined(__clang__) && __has_builtin(__builtin_altivec_vmuleuw) -/* Clang has a better way to control this, we can just use the builtin which doesn't swap. */ -# define XXH_vec_mulo __builtin_altivec_vmulouw -# define XXH_vec_mule __builtin_altivec_vmuleuw -# else -/* gcc needs inline assembly */ -/* Adapted from https://github.com/google/highwayhash/blob/master/highwayhash/hh_vsx.h. */ -XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mulo(xxh_u32x4 a, xxh_u32x4 b) -{ - xxh_u64x2 result; - __asm__("vmulouw %0, %1, %2" : "=v" (result) : "v" (a), "v" (b)); - return result; -} -XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mule(xxh_u32x4 a, xxh_u32x4 b) -{ - xxh_u64x2 result; - __asm__("vmuleuw %0, %1, %2" : "=v" (result) : "v" (a), "v" (b)); - return result; -} -# endif /* XXH_vec_mulo, XXH_vec_mule */ -#endif /* XXH_VECTOR == XXH_VSX */ - - -/* prefetch - * can be disabled, by declaring XXH_NO_PREFETCH build macro */ -#if defined(XXH_NO_PREFETCH) -# define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */ -#else -# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) /* _mm_prefetch() is not defined outside of x86/x64 */ -# include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ -# define XXH_PREFETCH(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0) -# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) ) -# define XXH_PREFETCH(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */) -# else -# define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */ -# endif -#endif /* XXH_NO_PREFETCH */ - - -/* ========================================== - * XXH3 default settings - * ========================================== */ - -#define XXH_SECRET_DEFAULT_SIZE 192 /* minimum XXH3_SECRET_SIZE_MIN */ - -#if (XXH_SECRET_DEFAULT_SIZE < XXH3_SECRET_SIZE_MIN) -# error "default keyset is not large enough" -#endif - -/* Pseudorandom secret taken directly from FARSH */ -XXH_ALIGN(64) static const xxh_u8 kSecret[XXH_SECRET_DEFAULT_SIZE] = { - 0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c, - 0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f, - 0xcb, 0x79, 0xe6, 0x4e, 0xcc, 0xc0, 0xe5, 0x78, 0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21, - 0xb8, 0x08, 0x46, 0x74, 0xf7, 0x43, 0x24, 0x8e, 0xe0, 0x35, 0x90, 0xe6, 0x81, 0x3a, 0x26, 0x4c, - 0x3c, 0x28, 0x52, 0xbb, 0x91, 0xc3, 0x00, 0xcb, 0x88, 0xd0, 0x65, 0x8b, 0x1b, 0x53, 0x2e, 0xa3, - 0x71, 0x64, 0x48, 0x97, 0xa2, 0x0d, 0xf9, 0x4e, 0x38, 0x19, 0xef, 0x46, 0xa9, 0xde, 0xac, 0xd8, - 0xa8, 0xfa, 0x76, 0x3f, 0xe3, 0x9c, 0x34, 0x3f, 0xf9, 0xdc, 0xbb, 0xc7, 0xc7, 0x0b, 0x4f, 0x1d, - 0x8a, 0x51, 0xe0, 0x4b, 0xcd, 0xb4, 0x59, 0x31, 0xc8, 0x9f, 0x7e, 0xc9, 0xd9, 0x78, 0x73, 0x64, - - 0xea, 0xc5, 0xac, 0x83, 0x34, 0xd3, 0xeb, 0xc3, 0xc5, 0x81, 0xa0, 0xff, 0xfa, 0x13, 0x63, 0xeb, - 0x17, 0x0d, 0xdd, 0x51, 0xb7, 0xf0, 0xda, 0x49, 0xd3, 0x16, 0x55, 0x26, 0x29, 0xd4, 0x68, 0x9e, - 0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc, 0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce, - 0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e, -}; - -/* - * Does a 32-bit to 64-bit long multiply. - * - * Wraps __emulu on MSVC x86 because it tends to call __allmul when it doesn't - * need to (but it shouldn't need to anyways, it is about 7 instructions to do - * a 64x64 multiply...). Since we know that this will _always_ emit MULL, we - * use that instead of the normal method. - * - * If you are compiling for platforms like Thumb-1 and don't have a better option, - * you may also want to write your own long multiply routine here. - * - * XXH_FORCE_INLINE xxh_u64 XXH_mult32to64(xxh_u64 x, xxh_u64 y) - * { - * return (x & 0xFFFFFFFF) * (y & 0xFFFFFFFF); - * } - */ -#if defined(_MSC_VER) && defined(_M_IX86) -# include <intrin.h> -# define XXH_mult32to64(x, y) __emulu((unsigned)(x), (unsigned)(y)) -#else -/* - * Downcast + upcast is usually better than masking on older compilers like - * GCC 4.2 (especially 32-bit ones), all without affecting newer compilers. - * - * The other method, (x & 0xFFFFFFFF) * (y & 0xFFFFFFFF), will AND both operands - * and perform a full 64x64 multiply -- entirely redundant on 32-bit. - */ -# define XXH_mult32to64(x, y) ((xxh_u64)(xxh_u32)(x) * (xxh_u64)(xxh_u32)(y)) -#endif - -/* - * Calculates a 64->128-bit long multiply. - * - * Uses __uint128_t and _umul128 if available, otherwise uses a scalar version. - */ -static XXH128_hash_t -XXH_mult64to128(xxh_u64 lhs, xxh_u64 rhs) -{ - /* - * GCC/Clang __uint128_t method. - * - * On most 64-bit targets, GCC and Clang define a __uint128_t type. - * This is usually the best way as it usually uses a native long 64-bit - * multiply, such as MULQ on x86_64 or MUL + UMULH on aarch64. - * - * Usually. - * - * Despite being a 32-bit platform, Clang (and emscripten) define this type - * despite not having the arithmetic for it. This results in a laggy - * compiler builtin call which calculates a full 128-bit multiply. - * In that case it is best to use the portable one. - * https://github.com/Cyan4973/xxHash/issues/211#issuecomment-515575677 - */ -#if defined(__GNUC__) && !defined(__wasm__) \ - && defined(__SIZEOF_INT128__) \ - || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 128) - - __uint128_t product = (__uint128_t)lhs * (__uint128_t)rhs; - XXH128_hash_t const r128 = { (xxh_u64)(product), (xxh_u64)(product >> 64) }; - return r128; - - /* - * MSVC for x64's _umul128 method. - * - * xxh_u64 _umul128(xxh_u64 Multiplier, xxh_u64 Multiplicand, xxh_u64 *HighProduct); - * - * This compiles to single operand MUL on x64. - */ -#elif defined(_M_X64) || defined(_M_IA64) - -#ifndef _MSC_VER -# pragma intrinsic(_umul128) -#endif - xxh_u64 product_high; - xxh_u64 const product_low = _umul128(lhs, rhs, &product_high); - XXH128_hash_t const r128 = { product_low, product_high }; - return r128; - -#else - /* - * Portable scalar method. Optimized for 32-bit and 64-bit ALUs. - * - * This is a fast and simple grade school multiply, which is shown below - * with base 10 arithmetic instead of base 0x100000000. - * - * 9 3 // D2 lhs = 93 - * x 7 5 // D2 rhs = 75 - * ---------- - * 1 5 // D2 lo_lo = (93 % 10) * (75 % 10) = 15 - * 4 5 | // D2 hi_lo = (93 / 10) * (75 % 10) = 45 - * 2 1 | // D2 lo_hi = (93 % 10) * (75 / 10) = 21 - * + 6 3 | | // D2 hi_hi = (93 / 10) * (75 / 10) = 63 - * --------- - * 2 7 | // D2 cross = (15 / 10) + (45 % 10) + 21 = 27 - * + 6 7 | | // D2 upper = (27 / 10) + (45 / 10) + 63 = 67 - * --------- - * 6 9 7 5 // D4 res = (27 * 10) + (15 % 10) + (67 * 100) = 6975 - * - * The reasons for adding the products like this are: - * 1. It avoids manual carry tracking. Just like how - * (9 * 9) + 9 + 9 = 99, the same applies with this for UINT64_MAX. - * This avoids a lot of complexity. - * - * 2. It hints for, and on Clang, compiles to, the powerful UMAAL - * instruction available in ARM's Digital Signal Processing extension - * in 32-bit ARMv6 and later, which is shown below: - * - * void UMAAL(xxh_u32 *RdLo, xxh_u32 *RdHi, xxh_u32 Rn, xxh_u32 Rm) - * { - * xxh_u64 product = (xxh_u64)*RdLo * (xxh_u64)*RdHi + Rn + Rm; - * *RdLo = (xxh_u32)(product & 0xFFFFFFFF); - * *RdHi = (xxh_u32)(product >> 32); - * } - * - * This instruction was designed for efficient long multiplication, and - * allows this to be calculated in only 4 instructions at speeds - * comparable to some 64-bit ALUs. - * - * 3. It isn't terrible on other platforms. Usually this will be a couple - * of 32-bit ADD/ADCs. - */ - - /* First calculate all of the cross products. */ - xxh_u64 const lo_lo = XXH_mult32to64(lhs & 0xFFFFFFFF, rhs & 0xFFFFFFFF); - xxh_u64 const hi_lo = XXH_mult32to64(lhs >> 32, rhs & 0xFFFFFFFF); - xxh_u64 const lo_hi = XXH_mult32to64(lhs & 0xFFFFFFFF, rhs >> 32); - xxh_u64 const hi_hi = XXH_mult32to64(lhs >> 32, rhs >> 32); - - /* Now add the products together. These will never overflow. */ - xxh_u64 const cross = (lo_lo >> 32) + (hi_lo & 0xFFFFFFFF) + lo_hi; - xxh_u64 const upper = (hi_lo >> 32) + (cross >> 32) + hi_hi; - xxh_u64 const lower = (cross << 32) | (lo_lo & 0xFFFFFFFF); - - XXH128_hash_t r128 = { lower, upper }; - return r128; -#endif -} - -/* - * Does a 64-bit to 128-bit multiply, then XOR folds it. - * - * The reason for the separate function is to prevent passing too many structs - * around by value. This will hopefully inline the multiply, but we don't force it. - */ -static xxh_u64 -XXH3_mul128_fold64(xxh_u64 lhs, xxh_u64 rhs) -{ - XXH128_hash_t product = XXH_mult64to128(lhs, rhs); - return product.low64 ^ product.high64; -} - -/* Seems to produce slightly better code on GCC for some reason. */ -XXH_FORCE_INLINE xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift) -{ - XXH_ASSERT(0 <= shift && shift < 64); - return v64 ^ (v64 >> shift); -} - -/* - * We don't need to (or want to) mix as much as XXH64. - * - * Short hashes are more evenly distributed, so it isn't necessary. - */ -static XXH64_hash_t XXH3_avalanche(xxh_u64 h64) -{ - h64 = XXH_xorshift64(h64, 37); - h64 *= 0x165667919E3779F9ULL; - h64 = XXH_xorshift64(h64, 32); - return h64; -} - - -/* ========================================== - * Short keys - * ========================================== - * One of the shortcomings of XXH32 and XXH64 was that their performance was - * sub-optimal on short lengths. It used an iterative algorithm which strongly - * favored lengths that were a multiple of 4 or 8. - * - * Instead of iterating over individual inputs, we use a set of single shot - * functions which piece together a range of lengths and operate in constant time. + * xxh3.h is no longer useful, + * but it is still provided for compatibility with source code + * which used to include it directly. * - * Additionally, the number of multiplies has been significantly reduced. This - * reduces latency, especially when emulating 64-bit multiplies on 32-bit. + * Programs are now highly discourage to include xxh3.h. + * Include `xxhash.h` instead, which is the officially supported interface. * - * Depending on the platform, this may or may not be faster than XXH32, but it - * is almost guaranteed to be faster than XXH64. + * In the future, xxh3.h will start to generate warnings, then errors, + * then it will be removed from source package and from include directory. */ -/* - * At very short lengths, there isn't enough input to fully hide secrets, or use - * the entire secret. - * - * There is also only a limited amount of mixing we can do before significantly - * impacting performance. - * - * Therefore, we use different sections of the secret and always mix two secret - * samples with an XOR. This should have no effect on performance on the - * seedless or withSeed variants because everything _should_ be constant folded - * by modern compilers. - * - * The XOR mixing hides individual parts of the secret and increases entropy. - * - * This adds an extra layer of strength for custom secrets. - */ -XXH_FORCE_INLINE XXH64_hash_t -XXH3_len_1to3_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) -{ - XXH_ASSERT(input != NULL); - XXH_ASSERT(1 <= len && len <= 3); - XXH_ASSERT(secret != NULL); - /* - * len = 1: combined = { input[0], 0x01, input[0], input[0] } - * len = 2: combined = { input[1], 0x02, input[0], input[1] } - * len = 3: combined = { input[2], 0x03, input[0], input[1] } - */ - { xxh_u8 const c1 = input[0]; - xxh_u8 const c2 = input[len >> 1]; - xxh_u8 const c3 = input[len - 1]; - xxh_u32 const combined = ((xxh_u32)c1<<16) | (((xxh_u32)c2) << 24) | (((xxh_u32)c3) << 0) | (((xxh_u32)len) << 8); - xxh_u64 const bitflip = (XXH_readLE32(secret) ^ XXH_readLE32(secret+4)) + seed; - xxh_u64 const keyed = (xxh_u64)combined ^ bitflip; - xxh_u64 const mixed = keyed * PRIME64_1; - return XXH3_avalanche(mixed); - } -} - -XXH_FORCE_INLINE XXH64_hash_t -XXH3_len_4to8_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) -{ - XXH_ASSERT(input != NULL); - XXH_ASSERT(secret != NULL); - XXH_ASSERT(4 <= len && len < 8); - seed ^= (xxh_u64)XXH_swap32((xxh_u32)seed) << 32; - { xxh_u32 const input1 = XXH_readLE32(input); - xxh_u32 const input2 = XXH_readLE32(input + len - 4); - xxh_u64 const bitflip = (XXH_readLE64(secret+8) ^ XXH_readLE64(secret+16)) - seed; - xxh_u64 const input64 = input2 + (((xxh_u64)input1) << 32); - xxh_u64 x = input64 ^ bitflip; - /* this mix is inspired by Pelle Evensen's rrmxmx */ - x ^= XXH_rotl64(x, 49) ^ XXH_rotl64(x, 24); - x *= 0x9FB21C651E98DF25ULL; - x ^= (x >> 35) + len ; - x *= 0x9FB21C651E98DF25ULL; - return XXH_xorshift64(x, 28); - } -} - -XXH_FORCE_INLINE XXH64_hash_t -XXH3_len_9to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) -{ - XXH_ASSERT(input != NULL); - XXH_ASSERT(secret != NULL); - XXH_ASSERT(8 <= len && len <= 16); - { xxh_u64 const bitflip1 = (XXH_readLE64(secret+24) ^ XXH_readLE64(secret+32)) + seed; - xxh_u64 const bitflip2 = (XXH_readLE64(secret+40) ^ XXH_readLE64(secret+48)) - seed; - xxh_u64 const input_lo = XXH_readLE64(input) ^ bitflip1; - xxh_u64 const input_hi = XXH_readLE64(input + len - 8) ^ bitflip2; - xxh_u64 const acc = len - + XXH_swap64(input_lo) + input_hi - + XXH3_mul128_fold64(input_lo, input_hi); - return XXH3_avalanche(acc); - } -} - -XXH_FORCE_INLINE XXH64_hash_t -XXH3_len_0to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) -{ - XXH_ASSERT(len <= 16); - { if (XXH_likely(len > 8)) return XXH3_len_9to16_64b(input, len, secret, seed); - if (XXH_likely(len >= 4)) return XXH3_len_4to8_64b(input, len, secret, seed); - if (len) return XXH3_len_1to3_64b(input, len, secret, seed); - return XXH3_avalanche((PRIME64_1 + seed) ^ (XXH_readLE64(secret+56) ^ XXH_readLE64(secret+64))); - } -} - -/* - * DISCLAIMER: There are known *seed-dependent* multicollisions here due to - * multiplication by zero, affecting hashes of lengths 17 to 240. - * - * However, they are very unlikely. - * - * Keep this in mind when using the unseeded XXH3_64bits() variant: As with all - * unseeded non-cryptographic hashes, it does not attempt to defend itself - * against specially crafted inputs, only random inputs. - * - * Compared to classic UMAC where a 1 in 2^31 chance of 4 consecutive bytes - * cancelling out the secret is taken an arbitrary number of times (addressed - * in XXH3_accumulate_512), this collision is very unlikely with random inputs - * and/or proper seeding: - * - * This only has a 1 in 2^63 chance of 8 consecutive bytes cancelling out, in a - * function that is only called up to 16 times per hash with up to 240 bytes of - * input. - * - * This is not too bad for a non-cryptographic hash function, especially with - * only 64 bit outputs. - * - * The 128-bit variant (which trades some speed for strength) is NOT affected - * by this, although it is always a good idea to use a proper seed if you care - * about strength. - */ -XXH_FORCE_INLINE xxh_u64 XXH3_mix16B(const xxh_u8* XXH_RESTRICT input, - const xxh_u8* XXH_RESTRICT secret, xxh_u64 seed64) -{ -#if defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \ - && defined(__i386__) && defined(__SSE2__) /* x86 + SSE2 */ \ - && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable like XXH32 hack */ - /* - * UGLY HACK: - * GCC for x86 tends to autovectorize the 128-bit multiply, resulting in - * slower code. - * - * By forcing seed64 into a register, we disrupt the cost model and - * cause it to scalarize. See `XXH32_round()` - * - * FIXME: Clang's output is still _much_ faster -- On an AMD Ryzen 3600, - * XXH3_64bits @ len=240 runs at 4.6 GB/s with Clang 9, but 3.3 GB/s on - * GCC 9.2, despite both emitting scalar code. - * - * GCC generates much better scalar code than Clang for the rest of XXH3, - * which is why finding a more optimal codepath is an interest. - */ - __asm__ ("" : "+r" (seed64)); -#endif - { xxh_u64 const input_lo = XXH_readLE64(input); - xxh_u64 const input_hi = XXH_readLE64(input+8); - return XXH3_mul128_fold64( - input_lo ^ (XXH_readLE64(secret) + seed64), - input_hi ^ (XXH_readLE64(secret+8) - seed64) - ); - } -} +/* Simulate the same impact as including the old xxh3.h source file */ -/* For mid range keys, XXH3 uses a Mum-hash variant. */ -XXH_FORCE_INLINE XXH64_hash_t -XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len, - const xxh_u8* XXH_RESTRICT secret, size_t secretSize, - XXH64_hash_t seed) -{ - XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize; - XXH_ASSERT(16 < len && len <= 128); - - { xxh_u64 acc = len * PRIME64_1; - if (len > 32) { - if (len > 64) { - if (len > 96) { - acc += XXH3_mix16B(input+48, secret+96, seed); - acc += XXH3_mix16B(input+len-64, secret+112, seed); - } - acc += XXH3_mix16B(input+32, secret+64, seed); - acc += XXH3_mix16B(input+len-48, secret+80, seed); - } - acc += XXH3_mix16B(input+16, secret+32, seed); - acc += XXH3_mix16B(input+len-32, secret+48, seed); - } - acc += XXH3_mix16B(input+0, secret+0, seed); - acc += XXH3_mix16B(input+len-16, secret+16, seed); - - return XXH3_avalanche(acc); - } -} - -#define XXH3_MIDSIZE_MAX 240 - -XXH_NO_INLINE XXH64_hash_t -XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len, - const xxh_u8* XXH_RESTRICT secret, size_t secretSize, - XXH64_hash_t seed) -{ - XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize; - XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX); - - #define XXH3_MIDSIZE_STARTOFFSET 3 - #define XXH3_MIDSIZE_LASTOFFSET 17 - - { xxh_u64 acc = len * PRIME64_1; - int const nbRounds = (int)len / 16; - int i; - for (i=0; i<8; i++) { - acc += XXH3_mix16B(input+(16*i), secret+(16*i), seed); - } - acc = XXH3_avalanche(acc); - XXH_ASSERT(nbRounds >= 8); -#if defined(__clang__) /* Clang */ \ - && (defined(__ARM_NEON) || defined(__ARM_NEON__)) /* NEON */ \ - && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable */ - /* - * UGLY HACK: - * Clang for ARMv7-A tries to vectorize this loop, similar to GCC x86. - * In everywhere else, it uses scalar code. - * - * For 64->128-bit multiplies, even if the NEON was 100% optimal, it - * would still be slower than UMAAL (see XXH_mult64to128). - * - * Unfortunately, Clang doesn't handle the long multiplies properly and - * converts them to the nonexistent "vmulq_u64" intrinsic, which is then - * scalarized into an ugly mess of VMOV.32 instructions. - * - * This mess is difficult to avoid without turning autovectorization - * off completely, but they are usually relatively minor and/or not - * worth it to fix. - * - * This loop is the easiest to fix, as unlike XXH32, this pragma - * _actually works_ because it is a loop vectorization instead of an - * SLP vectorization. - */ - #pragma clang loop vectorize(disable) -#endif - for (i=8 ; i < nbRounds; i++) { - acc += XXH3_mix16B(input+(16*i), secret+(16*(i-8)) + XXH3_MIDSIZE_STARTOFFSET, seed); - } - /* last bytes */ - acc += XXH3_mix16B(input + len - 16, secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET, seed); - return XXH3_avalanche(acc); - } -} - - -/* === Long Keys === */ - -#define STRIPE_LEN 64 -#define XXH_SECRET_CONSUME_RATE 8 /* nb of secret bytes consumed at each accumulation */ -#define ACC_NB (STRIPE_LEN / sizeof(xxh_u64)) - -typedef enum { XXH3_acc_64bits, XXH3_acc_128bits } XXH3_accWidth_e; - -/* - * XXH3_accumulate_512 is the tightest loop for long inputs, and it is the most optimized. - * - * It is a hardened version of UMAC, based off of FARSH's implementation. - * - * This was chosen because it adapts quite well to 32-bit, 64-bit, and SIMD - * implementations, and it is ridiculously fast. - * - * We harden it by mixing the original input to the accumulators as well as the product. - * - * This means that in the (relatively likely) case of a multiply by zero, the - * original input is preserved. - * - * On 128-bit inputs, we swap 64-bit pairs when we add the input to improve - * cross-pollination, as otherwise the upper and lower halves would be - * essentially independent. - * - * This doesn't matter on 64-bit hashes since they all get merged together in - * the end, so we skip the extra step. - * - * Both XXH3_64bits and XXH3_128bits use this subroutine. - */ -XXH_FORCE_INLINE void -XXH3_accumulate_512( void* XXH_RESTRICT acc, - const void* XXH_RESTRICT input, - const void* XXH_RESTRICT secret, - XXH3_accWidth_e accWidth) -{ -#if (XXH_VECTOR == XXH_AVX2) - - XXH_ASSERT((((size_t)acc) & 31) == 0); - { XXH_ALIGN(32) __m256i* const xacc = (__m256i *) acc; - /* Unaligned. This is mainly for pointer arithmetic, and because - * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */ - const __m256i* const xinput = (const __m256i *) input; - /* Unaligned. This is mainly for pointer arithmetic, and because - * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */ - const __m256i* const xsecret = (const __m256i *) secret; - - size_t i; - for (i=0; i < STRIPE_LEN/sizeof(__m256i); i++) { - /* data_vec = xinput[i]; */ - __m256i const data_vec = _mm256_loadu_si256 (xinput+i); - /* key_vec = xsecret[i]; */ - __m256i const key_vec = _mm256_loadu_si256 (xsecret+i); - /* data_key = data_vec ^ key_vec; */ - __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec); - /* data_key_lo = data_key >> 32; */ - __m256i const data_key_lo = _mm256_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); - /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ - __m256i const product = _mm256_mul_epu32 (data_key, data_key_lo); - if (accWidth == XXH3_acc_128bits) { - /* xacc[i] += swap(data_vec); */ - __m256i const data_swap = _mm256_shuffle_epi32(data_vec, _MM_SHUFFLE(1, 0, 3, 2)); - __m256i const sum = _mm256_add_epi64(xacc[i], data_swap); - /* xacc[i] += product; */ - xacc[i] = _mm256_add_epi64(product, sum); - } else { /* XXH3_acc_64bits */ - /* xacc[i] += data_vec; */ - __m256i const sum = _mm256_add_epi64(xacc[i], data_vec); - /* xacc[i] += product; */ - xacc[i] = _mm256_add_epi64(product, sum); - } - } } - -#elif (XXH_VECTOR == XXH_SSE2) - - /* SSE2 is just a half-scale version of the AVX2 version. */ - XXH_ASSERT((((size_t)acc) & 15) == 0); - { XXH_ALIGN(16) __m128i* const xacc = (__m128i *) acc; - /* Unaligned. This is mainly for pointer arithmetic, and because - * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */ - const __m128i* const xinput = (const __m128i *) input; - /* Unaligned. This is mainly for pointer arithmetic, and because - * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */ - const __m128i* const xsecret = (const __m128i *) secret; - - size_t i; - for (i=0; i < STRIPE_LEN/sizeof(__m128i); i++) { - /* data_vec = xinput[i]; */ - __m128i const data_vec = _mm_loadu_si128 (xinput+i); - /* key_vec = xsecret[i]; */ - __m128i const key_vec = _mm_loadu_si128 (xsecret+i); - /* data_key = data_vec ^ key_vec; */ - __m128i const data_key = _mm_xor_si128 (data_vec, key_vec); - /* data_key_lo = data_key >> 32; */ - __m128i const data_key_lo = _mm_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); - /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ - __m128i const product = _mm_mul_epu32 (data_key, data_key_lo); - if (accWidth == XXH3_acc_128bits) { - /* xacc[i] += swap(data_vec); */ - __m128i const data_swap = _mm_shuffle_epi32(data_vec, _MM_SHUFFLE(1,0,3,2)); - __m128i const sum = _mm_add_epi64(xacc[i], data_swap); - /* xacc[i] += product; */ - xacc[i] = _mm_add_epi64(product, sum); - } else { /* XXH3_acc_64bits */ - /* xacc[i] += data_vec; */ - __m128i const sum = _mm_add_epi64(xacc[i], data_vec); - /* xacc[i] += product; */ - xacc[i] = _mm_add_epi64(product, sum); - } - } } - -#elif (XXH_VECTOR == XXH_NEON) - - XXH_ASSERT((((size_t)acc) & 15) == 0); - { - XXH_ALIGN(16) uint64x2_t* const xacc = (uint64x2_t *) acc; - /* We don't use a uint32x4_t pointer because it causes bus errors on ARMv7. */ - uint8_t const* const xinput = (const uint8_t *) input; - uint8_t const* const xsecret = (const uint8_t *) secret; - - size_t i; - for (i=0; i < STRIPE_LEN / sizeof(uint64x2_t); i++) { - /* data_vec = xinput[i]; */ - uint8x16_t data_vec = vld1q_u8(xinput + (i * 16)); - /* key_vec = xsecret[i]; */ - uint8x16_t key_vec = vld1q_u8(xsecret + (i * 16)); - /* data_key = data_vec ^ key_vec; */ - uint64x2_t data_key = vreinterpretq_u64_u8(veorq_u8(data_vec, key_vec)); - uint32x2_t data_key_lo, data_key_hi; - if (accWidth == XXH3_acc_64bits) { - /* xacc[i] += data_vec; */ - xacc[i] = vaddq_u64 (xacc[i], vreinterpretq_u64_u8(data_vec)); - } else { /* XXH3_acc_128bits */ - /* xacc[i] += swap(data_vec); */ - uint64x2_t const data64 = vreinterpretq_u64_u8(data_vec); - uint64x2_t const swapped = vextq_u64(data64, data64, 1); - xacc[i] = vaddq_u64 (xacc[i], swapped); - } - /* data_key_lo = (uint32x2_t) (data_key & 0xFFFFFFFF); - * data_key_hi = (uint32x2_t) (data_key >> 32); - * data_key = UNDEFINED; */ - XXH_SPLIT_IN_PLACE(data_key, data_key_lo, data_key_hi); - /* xacc[i] += (uint64x2_t) data_key_lo * (uint64x2_t) data_key_hi; */ - xacc[i] = vmlal_u32 (xacc[i], data_key_lo, data_key_hi); - - } - } - -#elif (XXH_VECTOR == XXH_VSX) - xxh_u64x2* const xacc = (xxh_u64x2*) acc; /* presumed aligned */ - xxh_u64x2 const* const xinput = (xxh_u64x2 const*) input; /* no alignment restriction */ - xxh_u64x2 const* const xsecret = (xxh_u64x2 const*) secret; /* no alignment restriction */ - xxh_u64x2 const v32 = { 32, 32 }; - size_t i; - for (i = 0; i < STRIPE_LEN / sizeof(xxh_u64x2); i++) { - /* data_vec = xinput[i]; */ - xxh_u64x2 const data_vec = XXH_vec_loadu(xinput + i); - /* key_vec = xsecret[i]; */ - xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + i); - xxh_u64x2 const data_key = data_vec ^ key_vec; - /* shuffled = (data_key << 32) | (data_key >> 32); */ - xxh_u32x4 const shuffled = (xxh_u32x4)vec_rl(data_key, v32); - /* product = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)shuffled & 0xFFFFFFFF); */ - xxh_u64x2 const product = XXH_vec_mulo((xxh_u32x4)data_key, shuffled); - xacc[i] += product; - - if (accWidth == XXH3_acc_64bits) { - xacc[i] += data_vec; - } else { /* XXH3_acc_128bits */ - /* swap high and low halves */ -#ifdef __s390x__ - xxh_u64x2 const data_swapped = vec_permi(data_vec, data_vec, 2); -#else - xxh_u64x2 const data_swapped = vec_xxpermdi(data_vec, data_vec, 2); -#endif - xacc[i] += data_swapped; - } - } - -#else /* scalar variant of Accumulator - universal */ - - XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64* const xacc = (xxh_u64*) acc; /* presumed aligned */ - const xxh_u8* const xinput = (const xxh_u8*) input; /* no alignment restriction */ - const xxh_u8* const xsecret = (const xxh_u8*) secret; /* no alignment restriction */ - size_t i; - XXH_ASSERT(((size_t)acc & (XXH_ACC_ALIGN-1)) == 0); - for (i=0; i < ACC_NB; i++) { - xxh_u64 const data_val = XXH_readLE64(xinput + 8*i); - xxh_u64 const data_key = data_val ^ XXH_readLE64(xsecret + i*8); - - if (accWidth == XXH3_acc_64bits) { - xacc[i] += data_val; - } else { - xacc[i ^ 1] += data_val; /* swap adjacent lanes */ - } - xacc[i] += XXH_mult32to64(data_key & 0xFFFFFFFF, data_key >> 32); - } -#endif -} - -/* - * XXH3_scrambleAcc: Scrambles the accumulators to improve mixing. - * - * Multiplication isn't perfect, as explained by Google in HighwayHash: - * - * // Multiplication mixes/scrambles bytes 0-7 of the 64-bit result to - * // varying degrees. In descending order of goodness, bytes - * // 3 4 2 5 1 6 0 7 have quality 228 224 164 160 100 96 36 32. - * // As expected, the upper and lower bytes are much worse. - * - * Source: https://github.com/google/highwayhash/blob/0aaf66b/highwayhash/hh_avx2.h#L291 - * - * Since our algorithm uses a pseudorandom secret to add some variance into the - * mix, we don't need to (or want to) mix as often or as much as HighwayHash does. - * - * This isn't as tight as XXH3_accumulate, but still written in SIMD to avoid - * extraction. - * - * Both XXH3_64bits and XXH3_128bits use this subroutine. - */ -XXH_FORCE_INLINE void -XXH3_scrambleAcc(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) -{ -#if (XXH_VECTOR == XXH_AVX2) - - XXH_ASSERT((((size_t)acc) & 31) == 0); - { XXH_ALIGN(32) __m256i* const xacc = (__m256i*) acc; - /* Unaligned. This is mainly for pointer arithmetic, and because - * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */ - const __m256i* const xsecret = (const __m256i *) secret; - const __m256i prime32 = _mm256_set1_epi32((int)PRIME32_1); - - size_t i; - for (i=0; i < STRIPE_LEN/sizeof(__m256i); i++) { - /* xacc[i] ^= (xacc[i] >> 47) */ - __m256i const acc_vec = xacc[i]; - __m256i const shifted = _mm256_srli_epi64 (acc_vec, 47); - __m256i const data_vec = _mm256_xor_si256 (acc_vec, shifted); - /* xacc[i] ^= xsecret; */ - __m256i const key_vec = _mm256_loadu_si256 (xsecret+i); - __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec); - - /* xacc[i] *= PRIME32_1; */ - __m256i const data_key_hi = _mm256_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); - __m256i const prod_lo = _mm256_mul_epu32 (data_key, prime32); - __m256i const prod_hi = _mm256_mul_epu32 (data_key_hi, prime32); - xacc[i] = _mm256_add_epi64(prod_lo, _mm256_slli_epi64(prod_hi, 32)); - } - } - -#elif (XXH_VECTOR == XXH_SSE2) - - XXH_ASSERT((((size_t)acc) & 15) == 0); - { XXH_ALIGN(16) __m128i* const xacc = (__m128i*) acc; - /* Unaligned. This is mainly for pointer arithmetic, and because - * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */ - const __m128i* const xsecret = (const __m128i *) secret; - const __m128i prime32 = _mm_set1_epi32((int)PRIME32_1); - - size_t i; - for (i=0; i < STRIPE_LEN/sizeof(__m128i); i++) { - /* xacc[i] ^= (xacc[i] >> 47) */ - __m128i const acc_vec = xacc[i]; - __m128i const shifted = _mm_srli_epi64 (acc_vec, 47); - __m128i const data_vec = _mm_xor_si128 (acc_vec, shifted); - /* xacc[i] ^= xsecret[i]; */ - __m128i const key_vec = _mm_loadu_si128 (xsecret+i); - __m128i const data_key = _mm_xor_si128 (data_vec, key_vec); - - /* xacc[i] *= PRIME32_1; */ - __m128i const data_key_hi = _mm_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); - __m128i const prod_lo = _mm_mul_epu32 (data_key, prime32); - __m128i const prod_hi = _mm_mul_epu32 (data_key_hi, prime32); - xacc[i] = _mm_add_epi64(prod_lo, _mm_slli_epi64(prod_hi, 32)); - } - } - -#elif (XXH_VECTOR == XXH_NEON) - - XXH_ASSERT((((size_t)acc) & 15) == 0); - - { uint64x2_t* xacc = (uint64x2_t*) acc; - uint8_t const* xsecret = (uint8_t const*) secret; - uint32x2_t prime = vdup_n_u32 (PRIME32_1); - - size_t i; - for (i=0; i < STRIPE_LEN/sizeof(uint64x2_t); i++) { - /* xacc[i] ^= (xacc[i] >> 47); */ - uint64x2_t acc_vec = xacc[i]; - uint64x2_t shifted = vshrq_n_u64 (acc_vec, 47); - uint64x2_t data_vec = veorq_u64 (acc_vec, shifted); - - /* xacc[i] ^= xsecret[i]; */ - uint8x16_t key_vec = vld1q_u8(xsecret + (i * 16)); - uint64x2_t data_key = veorq_u64(data_vec, vreinterpretq_u64_u8(key_vec)); - - /* xacc[i] *= PRIME32_1 */ - uint32x2_t data_key_lo, data_key_hi; - /* data_key_lo = (uint32x2_t) (xacc[i] & 0xFFFFFFFF); - * data_key_hi = (uint32x2_t) (xacc[i] >> 32); - * xacc[i] = UNDEFINED; */ - XXH_SPLIT_IN_PLACE(data_key, data_key_lo, data_key_hi); - { /* - * prod_hi = (data_key >> 32) * PRIME32_1; - * - * Avoid vmul_u32 + vshll_n_u32 since Clang 6 and 7 will - * incorrectly "optimize" this: - * tmp = vmul_u32(vmovn_u64(a), vmovn_u64(b)); - * shifted = vshll_n_u32(tmp, 32); - * to this: - * tmp = "vmulq_u64"(a, b); // no such thing! - * shifted = vshlq_n_u64(tmp, 32); - * - * However, unlike SSE, Clang lacks a 64-bit multiply routine - * for NEON, and it scalarizes two 64-bit multiplies instead. - * - * vmull_u32 has the same timing as vmul_u32, and it avoids - * this bug completely. - * See https://bugs.llvm.org/show_bug.cgi?id=39967 - */ - uint64x2_t prod_hi = vmull_u32 (data_key_hi, prime); - /* xacc[i] = prod_hi << 32; */ - xacc[i] = vshlq_n_u64(prod_hi, 32); - /* xacc[i] += (prod_hi & 0xFFFFFFFF) * PRIME32_1; */ - xacc[i] = vmlal_u32(xacc[i], data_key_lo, prime); - } - } } - -#elif (XXH_VECTOR == XXH_VSX) - - XXH_ASSERT((((size_t)acc) & 15) == 0); - - { xxh_u64x2* const xacc = (xxh_u64x2*) acc; - const xxh_u64x2* const xsecret = (const xxh_u64x2*) secret; - /* constants */ - xxh_u64x2 const v32 = { 32, 32 }; - xxh_u64x2 const v47 = { 47, 47 }; - xxh_u32x4 const prime = { PRIME32_1, PRIME32_1, PRIME32_1, PRIME32_1 }; - size_t i; - for (i = 0; i < STRIPE_LEN / sizeof(xxh_u64x2); i++) { - /* xacc[i] ^= (xacc[i] >> 47); */ - xxh_u64x2 const acc_vec = xacc[i]; - xxh_u64x2 const data_vec = acc_vec ^ (acc_vec >> v47); - - /* xacc[i] ^= xsecret[i]; */ - xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + i); - xxh_u64x2 const data_key = data_vec ^ key_vec; - - /* xacc[i] *= PRIME32_1 */ - /* prod_lo = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)prime & 0xFFFFFFFF); */ - xxh_u64x2 const prod_even = XXH_vec_mule((xxh_u32x4)data_key, prime); - /* prod_hi = ((xxh_u64x2)data_key >> 32) * ((xxh_u64x2)prime >> 32); */ - xxh_u64x2 const prod_odd = XXH_vec_mulo((xxh_u32x4)data_key, prime); - xacc[i] = prod_odd + (prod_even << v32); - } } - -#else /* scalar variant of Scrambler - universal */ - - XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64* const xacc = (xxh_u64*) acc; /* presumed aligned */ - const xxh_u8* const xsecret = (const xxh_u8*) secret; /* no alignment restriction */ - size_t i; - XXH_ASSERT((((size_t)acc) & (XXH_ACC_ALIGN-1)) == 0); - for (i=0; i < ACC_NB; i++) { - xxh_u64 const key64 = XXH_readLE64(xsecret + 8*i); - xxh_u64 acc64 = xacc[i]; - acc64 = XXH_xorshift64(acc64, 47); - acc64 ^= key64; - acc64 *= PRIME32_1; - xacc[i] = acc64; - } - -#endif -} - -#define XXH_PREFETCH_DIST 384 - -/* - * XXH3_accumulate() - * Loops over XXH3_accumulate_512(). - * Assumption: nbStripes will not overflow the secret size - */ -XXH_FORCE_INLINE void -XXH3_accumulate( xxh_u64* XXH_RESTRICT acc, - const xxh_u8* XXH_RESTRICT input, - const xxh_u8* XXH_RESTRICT secret, - size_t nbStripes, - XXH3_accWidth_e accWidth) -{ - size_t n; - for (n = 0; n < nbStripes; n++ ) { - const xxh_u8* const in = input + n*STRIPE_LEN; - XXH_PREFETCH(in + XXH_PREFETCH_DIST); - XXH3_accumulate_512(acc, - in, - secret + n*XXH_SECRET_CONSUME_RATE, - accWidth); - } -} - -XXH_FORCE_INLINE void -XXH3_hashLong_internal_loop( xxh_u64* XXH_RESTRICT acc, - const xxh_u8* XXH_RESTRICT input, size_t len, - const xxh_u8* XXH_RESTRICT secret, size_t secretSize, - XXH3_accWidth_e accWidth) -{ - size_t const nb_rounds = (secretSize - STRIPE_LEN) / XXH_SECRET_CONSUME_RATE; - size_t const block_len = STRIPE_LEN * nb_rounds; - size_t const nb_blocks = len / block_len; - - size_t n; - - XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); - - for (n = 0; n < nb_blocks; n++) { - XXH3_accumulate(acc, input + n*block_len, secret, nb_rounds, accWidth); - XXH3_scrambleAcc(acc, secret + secretSize - STRIPE_LEN); - } - - /* last partial block */ - XXH_ASSERT(len > STRIPE_LEN); - { size_t const nbStripes = (len - (block_len * nb_blocks)) / STRIPE_LEN; - XXH_ASSERT(nbStripes <= (secretSize / XXH_SECRET_CONSUME_RATE)); - XXH3_accumulate(acc, input + nb_blocks*block_len, secret, nbStripes, accWidth); - - /* last stripe */ - if (len & (STRIPE_LEN - 1)) { - const xxh_u8* const p = input + len - STRIPE_LEN; - /* Do not align on 8, so that the secret is different from the scrambler */ -#define XXH_SECRET_LASTACC_START 7 - XXH3_accumulate_512(acc, p, secret + secretSize - STRIPE_LEN - XXH_SECRET_LASTACC_START, accWidth); - } } -} - -XXH_FORCE_INLINE xxh_u64 -XXH3_mix2Accs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret) -{ - return XXH3_mul128_fold64( - acc[0] ^ XXH_readLE64(secret), - acc[1] ^ XXH_readLE64(secret+8) ); -} - -static XXH64_hash_t -XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 start) -{ - xxh_u64 result64 = start; - - result64 += XXH3_mix2Accs(acc+0, secret + 0); - result64 += XXH3_mix2Accs(acc+2, secret + 16); - result64 += XXH3_mix2Accs(acc+4, secret + 32); - result64 += XXH3_mix2Accs(acc+6, secret + 48); - - return XXH3_avalanche(result64); -} - -#define XXH3_INIT_ACC { PRIME32_3, PRIME64_1, PRIME64_2, PRIME64_3, \ - PRIME64_4, PRIME32_2, PRIME64_5, PRIME32_1 }; - -XXH_FORCE_INLINE XXH64_hash_t -XXH3_hashLong_internal(const xxh_u8* XXH_RESTRICT input, size_t len, - const xxh_u8* XXH_RESTRICT secret, size_t secretSize) -{ - XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[ACC_NB] = XXH3_INIT_ACC; - - XXH3_hashLong_internal_loop(acc, input, len, secret, secretSize, XXH3_acc_64bits); - - /* converge into final hash */ - XXH_STATIC_ASSERT(sizeof(acc) == 64); - /* do not align on 8, so that the secret is different from the accumulator */ -#define XXH_SECRET_MERGEACCS_START 11 - XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); - return XXH3_mergeAccs(acc, secret + XXH_SECRET_MERGEACCS_START, (xxh_u64)len * PRIME64_1); -} - -/* - * It's important for performance that XXH3_hashLong is not inlined. Not sure - * why (uop cache maybe?), but the difference is large and easily measurable. - */ -XXH_NO_INLINE XXH64_hash_t -XXH3_hashLong_64b_defaultSecret(const xxh_u8* XXH_RESTRICT input, size_t len) -{ - return XXH3_hashLong_internal(input, len, kSecret, sizeof(kSecret)); -} - -/* - * It's important for performance that XXH3_hashLong is not inlined. Not sure - * why (uop cache maybe?), but the difference is large and easily measurable. - */ -XXH_NO_INLINE XXH64_hash_t -XXH3_hashLong_64b_withSecret(const xxh_u8* XXH_RESTRICT input, size_t len, - const xxh_u8* XXH_RESTRICT secret, size_t secretSize) -{ - return XXH3_hashLong_internal(input, len, secret, secretSize); -} - - -XXH_FORCE_INLINE void XXH_writeLE64(void* dst, xxh_u64 v64) -{ - if (!XXH_CPU_LITTLE_ENDIAN) v64 = XXH_swap64(v64); - memcpy(dst, &v64, sizeof(v64)); -} - -/* XXH3_initCustomSecret() : - * destination `customSecret` is presumed allocated and same size as `kSecret`. - */ -XXH_FORCE_INLINE void XXH3_initCustomSecret(xxh_u8* customSecret, xxh_u64 seed64) -{ - int const nbRounds = XXH_SECRET_DEFAULT_SIZE / 16; - int i; - - XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0); - - for (i=0; i < nbRounds; i++) { - XXH_writeLE64(customSecret + 16*i, XXH_readLE64(kSecret + 16*i) + seed64); - XXH_writeLE64(customSecret + 16*i + 8, XXH_readLE64(kSecret + 16*i + 8) - seed64); - } -} - - -/* - * XXH3_hashLong_64b_withSeed(): - * Generate a custom key based on alteration of default kSecret with the seed, - * and then use this key for long mode hashing. - * - * This operation is decently fast but nonetheless costs a little bit of time. - * Try to avoid it whenever possible (typically when seed==0). - * - * It's important for performance that XXH3_hashLong is not inlined. Not sure - * why (uop cache maybe?), but the difference is large and easily measurable. - */ -XXH_NO_INLINE XXH64_hash_t -XXH3_hashLong_64b_withSeed(const xxh_u8* input, size_t len, XXH64_hash_t seed) -{ - XXH_ALIGN(8) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE]; - if (seed==0) return XXH3_hashLong_64b_defaultSecret(input, len); - XXH3_initCustomSecret(secret, seed); - return XXH3_hashLong_internal(input, len, secret, sizeof(secret)); -} - -/* === Public entry point === */ - -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* input, size_t len) -{ - if (len <= 16) return XXH3_len_0to16_64b((const xxh_u8*)input, len, kSecret, 0); - if (len <= 128) return XXH3_len_17to128_64b((const xxh_u8*)input, len, kSecret, sizeof(kSecret), 0); - if (len <= XXH3_MIDSIZE_MAX) return XXH3_len_129to240_64b((const xxh_u8*)input, len, kSecret, sizeof(kSecret), 0); - return XXH3_hashLong_64b_defaultSecret((const xxh_u8*)input, len); -} - -XXH_PUBLIC_API XXH64_hash_t -XXH3_64bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize) -{ - XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); - /* - * If an action is to be taken if `secret` conditions are not respected, - * it should be done here. - * For now, it's a contract pre-condition. - * Adding a check and a branch here would cost performance at every hash. - */ - if (len <= 16) return XXH3_len_0to16_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, 0); - if (len <= 128) return XXH3_len_17to128_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretSize, 0); - if (len <= XXH3_MIDSIZE_MAX) return XXH3_len_129to240_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretSize, 0); - return XXH3_hashLong_64b_withSecret((const xxh_u8*)input, len, (const xxh_u8*)secret, secretSize); -} - -XXH_PUBLIC_API XXH64_hash_t -XXH3_64bits_withSeed(const void* input, size_t len, XXH64_hash_t seed) -{ - if (len <= 16) return XXH3_len_0to16_64b((const xxh_u8*)input, len, kSecret, seed); - if (len <= 128) return XXH3_len_17to128_64b((const xxh_u8*)input, len, kSecret, sizeof(kSecret), seed); - if (len <= XXH3_MIDSIZE_MAX) return XXH3_len_129to240_64b((const xxh_u8*)input, len, kSecret, sizeof(kSecret), seed); - return XXH3_hashLong_64b_withSeed((const xxh_u8*)input, len, seed); -} - -/* === XXH3 streaming === */ - -XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void) -{ - return (XXH3_state_t*)XXH_malloc(sizeof(XXH3_state_t)); -} - -XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr) -{ - XXH_free(statePtr); - return XXH_OK; -} - -XXH_PUBLIC_API void -XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state) -{ - memcpy(dst_state, src_state, sizeof(*dst_state)); -} - -static void -XXH3_64bits_reset_internal(XXH3_state_t* statePtr, - XXH64_hash_t seed, - const xxh_u8* secret, size_t secretSize) -{ - XXH_ASSERT(statePtr != NULL); - memset(statePtr, 0, sizeof(*statePtr)); - statePtr->acc[0] = PRIME32_3; - statePtr->acc[1] = PRIME64_1; - statePtr->acc[2] = PRIME64_2; - statePtr->acc[3] = PRIME64_3; - statePtr->acc[4] = PRIME64_4; - statePtr->acc[5] = PRIME32_2; - statePtr->acc[6] = PRIME64_5; - statePtr->acc[7] = PRIME32_1; - statePtr->seed = seed; - XXH_ASSERT(secret != NULL); - statePtr->secret = secret; - XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); - statePtr->secretLimit = (XXH32_hash_t)(secretSize - STRIPE_LEN); - statePtr->nbStripesPerBlock = statePtr->secretLimit / XXH_SECRET_CONSUME_RATE; -} - -XXH_PUBLIC_API XXH_errorcode -XXH3_64bits_reset(XXH3_state_t* statePtr) -{ - if (statePtr == NULL) return XXH_ERROR; - XXH3_64bits_reset_internal(statePtr, 0, kSecret, XXH_SECRET_DEFAULT_SIZE); - return XXH_OK; -} - -XXH_PUBLIC_API XXH_errorcode -XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize) -{ - if (statePtr == NULL) return XXH_ERROR; - XXH3_64bits_reset_internal(statePtr, 0, (const xxh_u8*)secret, secretSize); - if (secret == NULL) return XXH_ERROR; - if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR; - return XXH_OK; -} - -XXH_PUBLIC_API XXH_errorcode -XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed) -{ - if (statePtr == NULL) return XXH_ERROR; - XXH3_64bits_reset_internal(statePtr, seed, kSecret, XXH_SECRET_DEFAULT_SIZE); - XXH3_initCustomSecret(statePtr->customSecret, seed); - statePtr->secret = statePtr->customSecret; - return XXH_OK; -} - -XXH_FORCE_INLINE void -XXH3_consumeStripes( xxh_u64* acc, - XXH32_hash_t* nbStripesSoFarPtr, XXH32_hash_t nbStripesPerBlock, - const xxh_u8* input, size_t totalStripes, - const xxh_u8* secret, size_t secretLimit, - XXH3_accWidth_e accWidth) -{ - XXH_ASSERT(*nbStripesSoFarPtr < nbStripesPerBlock); - if (nbStripesPerBlock - *nbStripesSoFarPtr <= totalStripes) { - /* need a scrambling operation */ - size_t const nbStripes = nbStripesPerBlock - *nbStripesSoFarPtr; - XXH3_accumulate(acc, input, secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, nbStripes, accWidth); - XXH3_scrambleAcc(acc, secret + secretLimit); - XXH3_accumulate(acc, input + nbStripes * STRIPE_LEN, secret, totalStripes - nbStripes, accWidth); - *nbStripesSoFarPtr = (XXH32_hash_t)(totalStripes - nbStripes); - } else { - XXH3_accumulate(acc, input, secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, totalStripes, accWidth); - *nbStripesSoFarPtr += (XXH32_hash_t)totalStripes; - } -} - -/* - * Both XXH3_64bits_update and XXH3_128bits_update use this routine. - */ -XXH_FORCE_INLINE XXH_errorcode -XXH3_update(XXH3_state_t* state, const xxh_u8* input, size_t len, XXH3_accWidth_e accWidth) -{ - if (input==NULL) -#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) - return XXH_OK; -#else - return XXH_ERROR; -#endif - - { const xxh_u8* const bEnd = input + len; - - state->totalLen += len; - - if (state->bufferedSize + len <= XXH3_INTERNALBUFFER_SIZE) { /* fill in tmp buffer */ - XXH_memcpy(state->buffer + state->bufferedSize, input, len); - state->bufferedSize += (XXH32_hash_t)len; - return XXH_OK; - } - /* input is now > XXH3_INTERNALBUFFER_SIZE */ - - #define XXH3_INTERNALBUFFER_STRIPES (XXH3_INTERNALBUFFER_SIZE / STRIPE_LEN) - XXH_STATIC_ASSERT(XXH3_INTERNALBUFFER_SIZE % STRIPE_LEN == 0); /* clean multiple */ - - /* - * There is some input left inside the internal buffer. - * Fill it, then consume it. - */ - if (state->bufferedSize) { - size_t const loadSize = XXH3_INTERNALBUFFER_SIZE - state->bufferedSize; - XXH_memcpy(state->buffer + state->bufferedSize, input, loadSize); - input += loadSize; - XXH3_consumeStripes(state->acc, - &state->nbStripesSoFar, state->nbStripesPerBlock, - state->buffer, XXH3_INTERNALBUFFER_STRIPES, - state->secret, state->secretLimit, - accWidth); - state->bufferedSize = 0; - } - - /* Consume input by full buffer quantities */ - if (input+XXH3_INTERNALBUFFER_SIZE <= bEnd) { - const xxh_u8* const limit = bEnd - XXH3_INTERNALBUFFER_SIZE; - do { - XXH3_consumeStripes(state->acc, - &state->nbStripesSoFar, state->nbStripesPerBlock, - input, XXH3_INTERNALBUFFER_STRIPES, - state->secret, state->secretLimit, - accWidth); - input += XXH3_INTERNALBUFFER_SIZE; - } while (input<=limit); - } - - if (input < bEnd) { /* Some remaining input: buffer it */ - XXH_memcpy(state->buffer, input, (size_t)(bEnd-input)); - state->bufferedSize = (XXH32_hash_t)(bEnd-input); - } - } - - return XXH_OK; -} - -XXH_PUBLIC_API XXH_errorcode -XXH3_64bits_update(XXH3_state_t* state, const void* input, size_t len) -{ - return XXH3_update(state, (const xxh_u8*)input, len, XXH3_acc_64bits); -} - - -XXH_FORCE_INLINE void -XXH3_digest_long (XXH64_hash_t* acc, const XXH3_state_t* state, XXH3_accWidth_e accWidth) -{ - /* - * Digest on a local copy. This way, the state remains unaltered, and it can - * continue ingesting more input afterwards. - */ - memcpy(acc, state->acc, sizeof(state->acc)); - if (state->bufferedSize >= STRIPE_LEN) { - size_t const totalNbStripes = state->bufferedSize / STRIPE_LEN; - XXH32_hash_t nbStripesSoFar = state->nbStripesSoFar; - XXH3_consumeStripes(acc, - &nbStripesSoFar, state->nbStripesPerBlock, - state->buffer, totalNbStripes, - state->secret, state->secretLimit, - accWidth); - if (state->bufferedSize % STRIPE_LEN) { /* one last partial stripe */ - XXH3_accumulate_512(acc, - state->buffer + state->bufferedSize - STRIPE_LEN, - state->secret + state->secretLimit - XXH_SECRET_LASTACC_START, - accWidth); - } - } else { /* bufferedSize < STRIPE_LEN */ - if (state->bufferedSize) { /* one last stripe */ - xxh_u8 lastStripe[STRIPE_LEN]; - size_t const catchupSize = STRIPE_LEN - state->bufferedSize; - memcpy(lastStripe, state->buffer + sizeof(state->buffer) - catchupSize, catchupSize); - memcpy(lastStripe + catchupSize, state->buffer, state->bufferedSize); - XXH3_accumulate_512(acc, - lastStripe, - state->secret + state->secretLimit - XXH_SECRET_LASTACC_START, - accWidth); - } } -} - -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state) -{ - if (state->totalLen > XXH3_MIDSIZE_MAX) { - XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[ACC_NB]; - XXH3_digest_long(acc, state, XXH3_acc_64bits); - return XXH3_mergeAccs(acc, state->secret + XXH_SECRET_MERGEACCS_START, (xxh_u64)state->totalLen * PRIME64_1); - } - /* len <= XXH3_MIDSIZE_MAX : short code */ - if (state->seed) - return XXH3_64bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed); - return XXH3_64bits_withSecret(state->buffer, (size_t)(state->totalLen), state->secret, state->secretLimit + STRIPE_LEN); -} - -/* ========================================== - * XXH3 128 bits (=> XXH128) - * ========================================== */ - -XXH_FORCE_INLINE XXH128_hash_t -XXH3_len_1to3_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) -{ - XXH_ASSERT(input != NULL); - XXH_ASSERT(1 <= len && len <= 3); - XXH_ASSERT(secret != NULL); - /* - * len = 1: combinedl = { input[0], 0x01, input[0], input[0] } - * len = 2: combinedl = { input[1], 0x02, input[0], input[1] } - * len = 3: combinedl = { input[2], 0x03, input[0], input[1] } - */ - { xxh_u8 const c1 = input[0]; - xxh_u8 const c2 = input[len >> 1]; - xxh_u8 const c3 = input[len - 1]; - xxh_u32 const combinedl = ((xxh_u32)c1<<16) | (((xxh_u32)c2) << 24) | (((xxh_u32)c3) << 0) | (((xxh_u32)len) << 8); - xxh_u32 const combinedh = XXH_rotl32(XXH_swap32(combinedl), 13); - xxh_u64 const bitflipl = (XXH_readLE32(secret) ^ XXH_readLE32(secret+4)) + seed; - xxh_u64 const bitfliph = (XXH_readLE32(secret+8) ^ XXH_readLE32(secret+12)) - seed; - xxh_u64 const keyed_lo = (xxh_u64)combinedl ^ bitflipl; - xxh_u64 const keyed_hi = (xxh_u64)combinedh ^ bitfliph; - xxh_u64 const mixedl = keyed_lo * PRIME64_1; - xxh_u64 const mixedh = keyed_hi * PRIME64_5; - XXH128_hash_t const h128 = { XXH3_avalanche(mixedl) /*low64*/, XXH3_avalanche(mixedh) /*high64*/ }; - return h128; - } -} - -XXH_FORCE_INLINE XXH128_hash_t -XXH3_len_4to8_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) -{ - XXH_ASSERT(input != NULL); - XXH_ASSERT(secret != NULL); - XXH_ASSERT(4 <= len && len <= 8); - seed ^= (xxh_u64)XXH_swap32((xxh_u32)seed) << 32; - { xxh_u32 const input_lo = XXH_readLE32(input); - xxh_u32 const input_hi = XXH_readLE32(input + len - 4); - xxh_u64 const input_64 = input_lo + ((xxh_u64)input_hi << 32); - xxh_u64 const bitflip = (XXH_readLE64(secret+16) ^ XXH_readLE64(secret+24)) + seed; - xxh_u64 const keyed = input_64 ^ bitflip; - - /* Shift len to the left to ensure it is even, this avoids even multiplies. */ - XXH128_hash_t m128 = XXH_mult64to128(keyed, PRIME64_1 + (len << 2)); - - m128.high64 += (m128.low64 << 1); - m128.low64 ^= (m128.high64 >> 3); - - m128.low64 = XXH_xorshift64(m128.low64, 35); - m128.low64 *= 0x9FB21C651E98DF25ULL; - m128.low64 = XXH_xorshift64(m128.low64, 28); - m128.high64 = XXH3_avalanche(m128.high64); - return m128; - } -} - -XXH_FORCE_INLINE XXH128_hash_t -XXH3_len_9to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) -{ - XXH_ASSERT(input != NULL); - XXH_ASSERT(secret != NULL); - XXH_ASSERT(9 <= len && len <= 16); - { xxh_u64 const bitflipl = (XXH_readLE64(secret+32) ^ XXH_readLE64(secret+40)) - seed; - xxh_u64 const bitfliph = (XXH_readLE64(secret+48) ^ XXH_readLE64(secret+56)) + seed; - xxh_u64 const input_lo = XXH_readLE64(input); - xxh_u64 input_hi = XXH_readLE64(input + len - 8); - XXH128_hash_t m128 = XXH_mult64to128(input_lo ^ input_hi ^ bitflipl, PRIME64_1); - /* - * Put len in the middle of m128 to ensure that the length gets mixed to - * both the low and high bits in the 128x64 multiply below. - */ - m128.low64 += (xxh_u64)(len - 1) << 54; - input_hi ^= bitfliph; - /* - * Add the high 32 bits of input_hi to the high 32 bits of m128, then - * add the long product of the low 32 bits of input_hi and PRIME32_2 to - * the high 64 bits of m128. - * - * The best approach to this operation is different on 32-bit and 64-bit. - */ - if (sizeof(void *) < sizeof(xxh_u64)) { /* 32-bit */ - /* - * 32-bit optimized version, which is more readable. - * - * On 32-bit, it removes an ADC and delays a dependency between the two - * halves of m128.high64, but it generates an extra mask on 64-bit. - */ - m128.high64 += (input_hi & 0xFFFFFFFF00000000) + XXH_mult32to64((xxh_u32)input_hi, PRIME32_2); - } else { - /* - * 64-bit optimized (albeit more confusing) version. - * - * Uses some properties of addition and multiplication to remove the mask: - * - * Let: - * a = input_hi.lo = (input_hi & 0x00000000FFFFFFFF) - * b = input_hi.hi = (input_hi & 0xFFFFFFFF00000000) - * c = PRIME32_2 - * - * a + (b * c) - * Inverse Property: x + y - x == y - * a + (b * (1 + c - 1)) - * Distributive Property: x * (y + z) == (x * y) + (x * z) - * a + (b * 1) + (b * (c - 1)) - * Identity Property: x * 1 == x - * a + b + (b * (c - 1)) - * - * Substitute a, b, and c: - * input_hi.hi + input_hi.lo + ((xxh_u64)input_hi.lo * (PRIME32_2 - 1)) - * - * Since input_hi.hi + input_hi.lo == input_hi, we get this: - * input_hi + ((xxh_u64)input_hi.lo * (PRIME32_2 - 1)) - */ - m128.high64 += input_hi + XXH_mult32to64((xxh_u32)input_hi, PRIME32_2 - 1); - } - /* m128 ^= XXH_swap64(m128 >> 64); */ - m128.low64 ^= XXH_swap64(m128.high64); - - { /* 128x64 multiply: h128 = m128 * PRIME64_2; */ - XXH128_hash_t h128 = XXH_mult64to128(m128.low64, PRIME64_2); - h128.high64 += m128.high64 * PRIME64_2; - - h128.low64 = XXH3_avalanche(h128.low64); - h128.high64 = XXH3_avalanche(h128.high64); - return h128; - } } -} - -/* Assumption : `secret` size is >= 16 - * Note : it should be >= XXH3_SECRET_SIZE_MIN anyway */ -XXH_FORCE_INLINE XXH128_hash_t -XXH3_len_0to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) -{ - XXH_ASSERT(len <= 16); - { if (len > 8) return XXH3_len_9to16_128b(input, len, secret, seed); - if (len >= 4) return XXH3_len_4to8_128b(input, len, secret, seed); - if (len) return XXH3_len_1to3_128b(input, len, secret, seed); - { XXH128_hash_t h128; - xxh_u64 const bitflipl = XXH_readLE64(secret+64) ^ XXH_readLE64(secret+72); - xxh_u64 const bitfliph = XXH_readLE64(secret+80) ^ XXH_readLE64(secret+88); - h128.low64 = XXH3_avalanche((PRIME64_1 + seed) ^ bitflipl); - h128.high64 = XXH3_avalanche((PRIME64_2 - seed) ^ bitfliph); - return h128; - } } -} - -/* - * A bit slower than XXH3_mix16B, but handles multiply by zero better. - */ -XXH_FORCE_INLINE XXH128_hash_t -XXH128_mix32B(XXH128_hash_t acc, const xxh_u8* input_1, const xxh_u8* input_2, const xxh_u8* secret, XXH64_hash_t seed) -{ - acc.low64 += XXH3_mix16B (input_1, secret+0, seed); - acc.low64 ^= XXH_readLE64(input_2) + XXH_readLE64(input_2 + 8); - acc.high64 += XXH3_mix16B (input_2, secret+16, seed); - acc.high64 ^= XXH_readLE64(input_1) + XXH_readLE64(input_1 + 8); - return acc; -} - - -XXH_FORCE_INLINE XXH128_hash_t -XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len, - const xxh_u8* XXH_RESTRICT secret, size_t secretSize, - XXH64_hash_t seed) -{ - XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize; - XXH_ASSERT(16 < len && len <= 128); - - { XXH128_hash_t acc; - acc.low64 = len * PRIME64_1; - acc.high64 = 0; - if (len > 32) { - if (len > 64) { - if (len > 96) { - acc = XXH128_mix32B(acc, input+48, input+len-64, secret+96, seed); - } - acc = XXH128_mix32B(acc, input+32, input+len-48, secret+64, seed); - } - acc = XXH128_mix32B(acc, input+16, input+len-32, secret+32, seed); - } - acc = XXH128_mix32B(acc, input, input+len-16, secret, seed); - { xxh_u64 const low64 = acc.low64 + acc.high64; - xxh_u64 const high64 = (acc.low64 * PRIME64_1) + (acc.high64 * PRIME64_4) + ((len - seed) * PRIME64_2); - XXH128_hash_t const h128 = { XXH3_avalanche(low64), (XXH64_hash_t)0 - XXH3_avalanche(high64) }; - return h128; - } - } -} - -XXH_NO_INLINE XXH128_hash_t -XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len, - const xxh_u8* XXH_RESTRICT secret, size_t secretSize, - XXH64_hash_t seed) -{ - XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize; - XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX); - - { XXH128_hash_t acc; - int const nbRounds = (int)len / 32; - int i; - acc.low64 = len * PRIME64_1; - acc.high64 = 0; - for (i=0; i<4; i++) { - acc = XXH128_mix32B(acc, input+(32*i), input+(32*i)+16, secret+(32*i), seed); - } - acc.low64 = XXH3_avalanche(acc.low64); - acc.high64 = XXH3_avalanche(acc.high64); - XXH_ASSERT(nbRounds >= 4); - for (i=4 ; i < nbRounds; i++) { - acc = XXH128_mix32B(acc, input+(32*i), input+(32*i)+16, secret+XXH3_MIDSIZE_STARTOFFSET+(32*(i-4)), seed); - } - /* last bytes */ - acc = XXH128_mix32B(acc, input + len - 16, input + len - 32, secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET - 16, 0ULL - seed); - - { xxh_u64 const low64 = acc.low64 + acc.high64; - xxh_u64 const high64 = (acc.low64 * PRIME64_1) + (acc.high64 * PRIME64_4) + ((len - seed) * PRIME64_2); - XXH128_hash_t const h128 = { XXH3_avalanche(low64), (XXH64_hash_t)0 - XXH3_avalanche(high64) }; - return h128; - } - } -} - -XXH_FORCE_INLINE XXH128_hash_t -XXH3_hashLong_128b_internal(const xxh_u8* XXH_RESTRICT input, size_t len, - const xxh_u8* XXH_RESTRICT secret, size_t secretSize) -{ - XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[ACC_NB] = XXH3_INIT_ACC; - - XXH3_hashLong_internal_loop(acc, input, len, secret, secretSize, XXH3_acc_128bits); - - /* converge into final hash */ - XXH_STATIC_ASSERT(sizeof(acc) == 64); - XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); - { xxh_u64 const low64 = XXH3_mergeAccs(acc, secret + XXH_SECRET_MERGEACCS_START, (xxh_u64)len * PRIME64_1); - xxh_u64 const high64 = XXH3_mergeAccs(acc, secret + secretSize - sizeof(acc) - XXH_SECRET_MERGEACCS_START, ~((xxh_u64)len * PRIME64_2)); - XXH128_hash_t const h128 = { low64, high64 }; - return h128; - } -} - -/* - * It's important for performance that XXH3_hashLong is not inlined. Not sure - * why (uop cache maybe?), but the difference is large and easily measurable. - */ -XXH_NO_INLINE XXH128_hash_t -XXH3_hashLong_128b_defaultSecret(const xxh_u8* input, size_t len) -{ - return XXH3_hashLong_128b_internal(input, len, kSecret, sizeof(kSecret)); -} - -/* - * It's important for performance that XXH3_hashLong is not inlined. Not sure - * why (uop cache maybe?), but the difference is large and easily measurable. - */ -XXH_NO_INLINE XXH128_hash_t -XXH3_hashLong_128b_withSecret(const xxh_u8* input, size_t len, - const xxh_u8* secret, size_t secretSize) -{ - return XXH3_hashLong_128b_internal(input, len, secret, secretSize); -} - -/* - * It's important for performance that XXH3_hashLong is not inlined. Not sure - * why (uop cache maybe?), but the difference is large and easily measurable. - */ -XXH_NO_INLINE XXH128_hash_t -XXH3_hashLong_128b_withSeed(const xxh_u8* input, size_t len, XXH64_hash_t seed) -{ - XXH_ALIGN(8) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE]; - if (seed == 0) return XXH3_hashLong_128b_defaultSecret(input, len); - XXH3_initCustomSecret(secret, seed); - return XXH3_hashLong_128b_internal(input, len, secret, sizeof(secret)); -} - - -XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* input, size_t len) -{ - if (len <= 16) return XXH3_len_0to16_128b((const xxh_u8*)input, len, kSecret, 0); - if (len <= 128) return XXH3_len_17to128_128b((const xxh_u8*)input, len, kSecret, sizeof(kSecret), 0); - if (len <= XXH3_MIDSIZE_MAX) return XXH3_len_129to240_128b((const xxh_u8*)input, len, kSecret, sizeof(kSecret), 0); - return XXH3_hashLong_128b_defaultSecret((const xxh_u8*)input, len); -} - -XXH_PUBLIC_API XXH128_hash_t -XXH3_128bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize) -{ - XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); - /* - * If an action is to be taken if `secret` conditions are not respected, - * it should be done here. - * For now, it's a contract pre-condition. - * Adding a check and a branch here would cost performance at every hash. - */ - if (len <= 16) return XXH3_len_0to16_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, 0); - if (len <= 128) return XXH3_len_17to128_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretSize, 0); - if (len <= XXH3_MIDSIZE_MAX) return XXH3_len_129to240_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretSize, 0); - return XXH3_hashLong_128b_withSecret((const xxh_u8*)input, len, (const xxh_u8*)secret, secretSize); -} - -XXH_PUBLIC_API XXH128_hash_t -XXH3_128bits_withSeed(const void* input, size_t len, XXH64_hash_t seed) -{ - if (len <= 16) return XXH3_len_0to16_128b((const xxh_u8*)input, len, kSecret, seed); - if (len <= 128) return XXH3_len_17to128_128b((const xxh_u8*)input, len, kSecret, sizeof(kSecret), seed); - if (len <= XXH3_MIDSIZE_MAX) return XXH3_len_129to240_128b((const xxh_u8*)input, len, kSecret, sizeof(kSecret), seed); - return XXH3_hashLong_128b_withSeed((const xxh_u8*)input, len, seed); -} - -XXH_PUBLIC_API XXH128_hash_t -XXH128(const void* input, size_t len, XXH64_hash_t seed) -{ - return XXH3_128bits_withSeed(input, len, seed); -} - - -/* === XXH3 128-bit streaming === */ - -/* all the functions are actually the same as for 64-bit streaming variant, - just the reset one is different (different initial acc values for 0,5,6,7), - and near the end of the digest function */ - -static void -XXH3_128bits_reset_internal(XXH3_state_t* statePtr, - XXH64_hash_t seed, - const xxh_u8* secret, size_t secretSize) -{ - XXH3_64bits_reset_internal(statePtr, seed, secret, secretSize); -} - -XXH_PUBLIC_API XXH_errorcode -XXH3_128bits_reset(XXH3_state_t* statePtr) -{ - if (statePtr == NULL) return XXH_ERROR; - XXH3_128bits_reset_internal(statePtr, 0, kSecret, XXH_SECRET_DEFAULT_SIZE); - return XXH_OK; -} - -XXH_PUBLIC_API XXH_errorcode -XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize) -{ - if (statePtr == NULL) return XXH_ERROR; - XXH3_128bits_reset_internal(statePtr, 0, (const xxh_u8*)secret, secretSize); - if (secret == NULL) return XXH_ERROR; - if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR; - return XXH_OK; -} - -XXH_PUBLIC_API XXH_errorcode -XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed) -{ - if (statePtr == NULL) return XXH_ERROR; - XXH3_128bits_reset_internal(statePtr, seed, kSecret, XXH_SECRET_DEFAULT_SIZE); - XXH3_initCustomSecret(statePtr->customSecret, seed); - statePtr->secret = statePtr->customSecret; - return XXH_OK; -} - -XXH_PUBLIC_API XXH_errorcode -XXH3_128bits_update(XXH3_state_t* state, const void* input, size_t len) -{ - return XXH3_update(state, (const xxh_u8*)input, len, XXH3_acc_128bits); -} - -XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* state) -{ - if (state->totalLen > XXH3_MIDSIZE_MAX) { - XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[ACC_NB]; - XXH3_digest_long(acc, state, XXH3_acc_128bits); - XXH_ASSERT(state->secretLimit + STRIPE_LEN >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); - { xxh_u64 const low64 = XXH3_mergeAccs(acc, state->secret + XXH_SECRET_MERGEACCS_START, (xxh_u64)state->totalLen * PRIME64_1); - xxh_u64 const high64 = XXH3_mergeAccs(acc, state->secret + state->secretLimit + STRIPE_LEN - sizeof(acc) - XXH_SECRET_MERGEACCS_START, ~((xxh_u64)state->totalLen * PRIME64_2)); - XXH128_hash_t const h128 = { low64, high64 }; - return h128; - } - } - /* len <= XXH3_MIDSIZE_MAX : short code */ - if (state->seed) - return XXH3_128bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed); - return XXH3_128bits_withSecret(state->buffer, (size_t)(state->totalLen), state->secret, state->secretLimit + STRIPE_LEN); -} - -/* 128-bit utility functions */ - -#include <string.h> /* memcmp, memcpy */ - -/* return : 1 is equal, 0 if different */ -XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2) -{ - /* note : XXH128_hash_t is compact, it has no padding byte */ - return !(memcmp(&h1, &h2, sizeof(h1))); -} - -/* This prototype is compatible with stdlib's qsort(). - * return : >0 if *h128_1 > *h128_2 - * <0 if *h128_1 < *h128_2 - * =0 if *h128_1 == *h128_2 */ -XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2) -{ - XXH128_hash_t const h1 = *(const XXH128_hash_t*)h128_1; - XXH128_hash_t const h2 = *(const XXH128_hash_t*)h128_2; - int const hcmp = (h1.high64 > h2.high64) - (h2.high64 > h1.high64); - /* note : bets that, in most cases, hash values are different */ - if (hcmp) return hcmp; - return (h1.low64 > h2.low64) - (h2.low64 > h1.low64); -} - - -/*====== Canonical representation ======*/ -XXH_PUBLIC_API void -XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash) -{ - XXH_STATIC_ASSERT(sizeof(XXH128_canonical_t) == sizeof(XXH128_hash_t)); - if (XXH_CPU_LITTLE_ENDIAN) { - hash.high64 = XXH_swap64(hash.high64); - hash.low64 = XXH_swap64(hash.low64); - } - memcpy(dst, &hash.high64, sizeof(hash.high64)); - memcpy((char*)dst + sizeof(hash.high64), &hash.low64, sizeof(hash.low64)); -} - -XXH_PUBLIC_API XXH128_hash_t -XXH128_hashFromCanonical(const XXH128_canonical_t* src) -{ - XXH128_hash_t h; - h.high64 = XXH_readBE64(src); - h.low64 = XXH_readBE64(src->digest + 8); - return h; -} - -/* Pop our optimization override from above */ -#if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \ - && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \ - && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */ -# pragma GCC pop_options -#endif - -#endif /* XXH3_H_1397135465 */ +#define XXH_INLINE_ALL +#include "xxhash.h" diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/xxHash/xxhash.c b/Build/source/texk/dvisvgm/dvisvgm-src/libs/xxHash/xxhash.c index 3e0da98f3ea..0fae88c5d67 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/xxHash/xxhash.c +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/xxHash/xxhash.c @@ -1,6 +1,6 @@ /* * xxHash - Extremely Fast Hash algorithm - * Copyright (C) 2012-present, Yann Collet + * Copyright (C) 2012-2020 Yann Collet * * BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) * diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/xxHash/xxhash.h b/Build/source/texk/dvisvgm/dvisvgm-src/libs/xxHash/xxhash.h index 3677f8287be..2d56d23c5d0 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/xxHash/xxhash.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/xxHash/xxhash.h @@ -1,7 +1,7 @@ /* * xxHash - Extremely Fast Hash algorithm * Header File - * Copyright (C) 2012-present, Yann Collet. + * Copyright (C) 2012-2020 Yann Collet * * BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) * @@ -195,6 +195,7 @@ extern "C" { # define XXH_CAT(A,B) A##B # define XXH_NAME2(A,B) XXH_CAT(A,B) # define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber) +/* XXH32 */ # define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32) # define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState) # define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState) @@ -204,6 +205,7 @@ extern "C" { # define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState) # define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash) # define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical) +/* XXH64 */ # define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64) # define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState) # define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState) @@ -213,6 +215,33 @@ extern "C" { # define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState) # define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash) # define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical) +/* XXH3_64bits */ +# define XXH3_64bits XXH_NAME2(XXH_NAMESPACE, XXH3_64bits) +# define XXH3_64bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSecret) +# define XXH3_64bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSeed) +# define XXH3_createState XXH_NAME2(XXH_NAMESPACE, XXH3_createState) +# define XXH3_freeState XXH_NAME2(XXH_NAMESPACE, XXH3_freeState) +# define XXH3_copyState XXH_NAME2(XXH_NAMESPACE, XXH3_copyState) +# define XXH3_64bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset) +# define XXH3_64bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSeed) +# define XXH3_64bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSecret) +# define XXH3_64bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_update) +# define XXH3_64bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_digest) +# define XXH3_generateSecret XXH_NAME2(XXH_NAMESPACE, XXH3_generateSecret) +/* XXH3_128bits */ +# define XXH128 XXH_NAME2(XXH_NAMESPACE, XXH128) +# define XXH3_128bits XXH_NAME2(XXH_NAMESPACE, XXH3_128bits) +# define XXH3_128bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSeed) +# define XXH3_128bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSecret) +# define XXH3_128bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset) +# define XXH3_128bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSeed) +# define XXH3_128bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSecret) +# define XXH3_128bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_update) +# define XXH3_128bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_digest) +# define XXH128_isEqual XXH_NAME2(XXH_NAMESPACE, XXH128_isEqual) +# define XXH128_cmp XXH_NAME2(XXH_NAMESPACE, XXH128_cmp) +# define XXH128_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH128_canonicalFromHash) +# define XXH128_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH128_hashFromCanonical) #endif @@ -220,8 +249,8 @@ extern "C" { * Version ***************************************/ #define XXH_VERSION_MAJOR 0 -#define XXH_VERSION_MINOR 7 -#define XXH_VERSION_RELEASE 3 +#define XXH_VERSION_MINOR 8 +#define XXH_VERSION_RELEASE 0 #define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) XXH_PUBLIC_API unsigned XXH_versionNumber (void); @@ -260,6 +289,10 @@ typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; * The memory between input & input+length must be valid (allocated and read-accessible). * "seed" can be used to alter the result predictably. * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark): 5.4 GB/s + * + * Note: XXH3 provides competitive speed for both 32-bit and 64-bit systems, + * and offers true 64/128 bit hash results. It provides a superior level of + * dispersion, and greatly reduces the risks of collisions. */ XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed); @@ -342,8 +375,13 @@ XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src * Returns the 64-bit hash of sequence of length @length stored at memory * address @input. * @seed can be used to alter the result predictably. + * * This function usually runs faster on 64-bit systems, but slower on 32-bit * systems (see benchmark). + * + * Note: XXH3 provides competitive speed for both 32-bit and 64-bit systems, + * and offers true 64/128 bit hash results. It provides a superior level of + * dispersion, and greatly reduces the risks of collisions. */ XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, XXH64_hash_t seed); @@ -358,64 +396,13 @@ XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr); /******* Canonical representation *******/ -typedef struct { unsigned char digest[8]; } XXH64_canonical_t; +typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t; XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash); XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src); -#endif /* XXH_NO_LONG_LONG */ - -#endif /* XXHASH_H_5627135585666179 */ - -#define XXH_STATIC_LINKING_ONLY - -#if defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742) -#define XXHASH_H_STATIC_13879238742 -/* **************************************************************************** - * This section contains declarations which are not guaranteed to remain stable. - * They may change in future versions, becoming incompatible with a different - * version of the library. - * These declarations should only be used with static linking. - * Never use them in association with dynamic linking! - ***************************************************************************** */ - -/* - * These definitions are only present to allow static allocation of an XXH - * state, for example, on the stack or in a struct. - * Never **ever** access members directly. - */ - -struct XXH32_state_s { - XXH32_hash_t total_len_32; - XXH32_hash_t large_len; - XXH32_hash_t v1; - XXH32_hash_t v2; - XXH32_hash_t v3; - XXH32_hash_t v4; - XXH32_hash_t mem32[4]; - XXH32_hash_t memsize; - XXH32_hash_t reserved; /* never read nor write, might be removed in a future version */ -}; /* typedef'd to XXH32_state_t */ - - -#ifndef XXH_NO_LONG_LONG /* defined when there is no 64-bit support */ - -struct XXH64_state_s { - XXH64_hash_t total_len; - XXH64_hash_t v1; - XXH64_hash_t v2; - XXH64_hash_t v3; - XXH64_hash_t v4; - XXH64_hash_t mem64[4]; - XXH32_hash_t memsize; - XXH32_hash_t reserved32; /* required for padding anyway */ - XXH64_hash_t reserved64; /* never read nor write, might be removed in a future version */ -}; /* typedef'd to XXH64_state_t */ - - /*-********************************************************************** -* XXH3 -* New experimental hash +* XXH3 64-bit variant ************************************************************************/ /* ************************************************************************ @@ -439,11 +426,11 @@ struct XXH64_state_s { * It benefits greatly from SIMD and 64-bit arithmetic, but does not require it. * * Almost all 32-bit and 64-bit targets that can run XXH32 smoothly can run - * XXH3 at usable speeds, even if XXH64 runs slowly. Further details are + * XXH3 at competitive speeds, even if XXH64 runs slowly. Further details are * explained in the implementation. * - * Optimized implementations are provided for AVX2, SSE2, NEON, POWER8, ZVector, - * and scalar targets. This can be controlled with the XXH_VECTOR macro. + * Optimized implementations are provided for AVX512, AVX2, SSE2, NEON, POWER8, + * ZVector and scalar targets. This can be controlled with the XXH_VECTOR macro. * * XXH3 offers 2 variants, _64bits and _128bits. * When only 64 bits are needed, prefer calling the _64bits variant, as it @@ -461,116 +448,61 @@ struct XXH64_state_s { * ephemeral data (local sessions). * * Avoid storing values in long-term storage until the algorithm is finalized. + * XXH3's return values will be officially finalized upon reaching v0.8.0. + * + * After which, return values of XXH3 and XXH128 will no longer change in + * future versions. * * The API supports one-shot hashing, streaming mode, and custom secrets. */ -#ifdef XXH_NAMESPACE -# define XXH3_64bits XXH_NAME2(XXH_NAMESPACE, XXH3_64bits) -# define XXH3_64bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSecret) -# define XXH3_64bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSeed) - -# define XXH3_createState XXH_NAME2(XXH_NAMESPACE, XXH3_createState) -# define XXH3_freeState XXH_NAME2(XXH_NAMESPACE, XXH3_freeState) -# define XXH3_copyState XXH_NAME2(XXH_NAMESPACE, XXH3_copyState) - -# define XXH3_64bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset) -# define XXH3_64bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSeed) -# define XXH3_64bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSecret) -# define XXH3_64bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_update) -# define XXH3_64bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_digest) -#endif - /* XXH3_64bits(): * default 64-bit variant, using default secret and default seed of 0. * It's the fastest variant. */ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* data, size_t len); /* - * XXH3_64bits_withSecret(): - * It's possible to provide any blob of bytes as a "secret" to generate the hash. - * This makes it more difficult for an external actor to prepare an intentional - * collision. - * The secret *must* be large enough (>= XXH3_SECRET_SIZE_MIN). - * It should consist of random bytes. - * Avoid trivial sequences, such as repeating sequences and especially '\0', - * as this can cancel out itself. - * Failure to respect these conditions will result in a poor quality hash. - */ -#define XXH3_SECRET_SIZE_MIN 136 -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize); - -/* * XXH3_64bits_withSeed(): - * This variant generates a custom secret on the fly based on the default - * secret, altered using the `seed` value. + * This variant generates a custom secret on the fly + * based on default secret altered using the `seed` value. * While this operation is decently fast, note that it's not completely free. * Note: seed==0 produces the same results as XXH3_64bits(). */ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, XXH64_hash_t seed); +/* + * XXH3_64bits_withSecret(): + * It's possible to provide any blob of bytes as a "secret" to generate the hash. + * This makes it more difficult for an external actor to prepare an intentional collision. + * The main condition is that secretSize *must* be large enough (>= XXH3_SECRET_SIZE_MIN). + * However, the quality of produced hash values depends on secret's entropy. + * Technically, the secret must look like a bunch of random bytes. + * Avoid "trivial" or structured data such as repeated sequences or a text document. + * Whenever unsure about the "randomness" of the blob of bytes, + * consider relabelling it as a "custom seed" instead, + * and employ "XXH3_generateSecret()" (see below) + * to generate a high entropy secret derived from the custom seed. + */ +#define XXH3_SECRET_SIZE_MIN 136 +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize); -/* streaming 64-bit */ - -#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11+ */ -# include <stdalign.h> -# define XXH_ALIGN(n) alignas(n) -#elif defined(__GNUC__) -# define XXH_ALIGN(n) __attribute__ ((aligned(n))) -#elif defined(_MSC_VER) -# define XXH_ALIGN(n) __declspec(align(n)) -#else -# define XXH_ALIGN(n) /* disabled */ -#endif - -/* Old GCC versions only accept the attribute after the type in structures. */ -#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) /* C11+ */ \ - && defined(__GNUC__) -# define XXH_ALIGN_MEMBER(align, type) type XXH_ALIGN(align) -#else -# define XXH_ALIGN_MEMBER(align, type) XXH_ALIGN(align) type -#endif - -typedef struct XXH3_state_s XXH3_state_t; - -#define XXH3_SECRET_DEFAULT_SIZE 192 /* minimum XXH3_SECRET_SIZE_MIN */ -#define XXH3_INTERNALBUFFER_SIZE 256 -struct XXH3_state_s { - XXH_ALIGN_MEMBER(64, XXH64_hash_t acc[8]); - /* used to store a custom secret generated from the seed. Makes state larger. - * Design might change */ - XXH_ALIGN_MEMBER(64, unsigned char customSecret[XXH3_SECRET_DEFAULT_SIZE]); - XXH_ALIGN_MEMBER(64, unsigned char buffer[XXH3_INTERNALBUFFER_SIZE]); - XXH32_hash_t bufferedSize; - XXH32_hash_t nbStripesPerBlock; - XXH32_hash_t nbStripesSoFar; - XXH32_hash_t secretLimit; - XXH32_hash_t reserved32; - XXH32_hash_t reserved32_2; - XXH64_hash_t totalLen; - XXH64_hash_t seed; - XXH64_hash_t reserved64; - /* note: there is some padding after due to alignment on 64 bytes */ - const unsigned char* secret; -}; /* typedef'd to XXH3_state_t */ - -#undef XXH_ALIGN_MEMBER +/******* Streaming *******/ /* * Streaming requires state maintenance. * This operation costs memory and CPU. * As a consequence, streaming is slower than one-shot hashing. - * For better performance, prefer one-shot functions whenever possible. + * For better performance, prefer one-shot functions whenever applicable. */ +typedef struct XXH3_state_s XXH3_state_t; XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void); XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr); XXH_PUBLIC_API void XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state); - /* * XXH3_64bits_reset(): - * Initialize with the default parameters. - * The result will be equivalent to `XXH3_64bits()`. + * Initialize with default parameters. + * digest will be equivalent to `XXH3_64bits()`. */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH3_state_t* statePtr); /* @@ -581,46 +513,48 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH3_state_t* statePtr); XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed); /* * XXH3_64bits_reset_withSecret(): - * `secret` is referenced, and must outlive the hash streaming session, so - * be careful when using stack arrays. - * `secretSize` must be >= `XXH3_SECRET_SIZE_MIN`. + * `secret` is referenced, it _must outlive_ the hash streaming session. + * Similar to one-shot API, `secretSize` must be >= `XXH3_SECRET_SIZE_MIN`, + * and the quality of produced hash values depends on secret's entropy + * (secret's content should look like a bunch of random bytes). + * When in doubt about the randomness of a candidate `secret`, + * consider employing `XXH3_generateSecret()` instead (see below). */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize); XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH3_state_t* statePtr, const void* input, size_t length); XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* statePtr); +/* note : canonical representation of XXH3 is the same as XXH64 + * since they both produce XXH64_hash_t values */ -/* 128-bit */ - -#ifdef XXH_NAMESPACE -# define XXH128 XXH_NAME2(XXH_NAMESPACE, XXH128) -# define XXH3_128bits XXH_NAME2(XXH_NAMESPACE, XXH3_128bits) -# define XXH3_128bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSeed) -# define XXH3_128bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSecret) -# define XXH3_128bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset) -# define XXH3_128bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSeed) -# define XXH3_128bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSecret) -# define XXH3_128bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_update) -# define XXH3_128bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_digest) - -# define XXH128_isEqual XXH_NAME2(XXH_NAMESPACE, XXH128_isEqual) -# define XXH128_cmp XXH_NAME2(XXH_NAMESPACE, XXH128_cmp) -# define XXH128_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH128_canonicalFromHash) -# define XXH128_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH128_hashFromCanonical) -#endif +/*-********************************************************************** +* XXH3 128-bit variant +************************************************************************/ typedef struct { - XXH64_hash_t low64; - XXH64_hash_t high64; + XXH64_hash_t low64; + XXH64_hash_t high64; } XXH128_hash_t; -XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t seed); XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* data, size_t len); -XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSeed(const void* data, size_t len, XXH64_hash_t seed); /* == XXH128() */ +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSeed(const void* data, size_t len, XXH64_hash_t seed); XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize); +/******* Streaming *******/ +/* + * Streaming requires state maintenance. + * This operation costs memory and CPU. + * As a consequence, streaming is slower than one-shot hashing. + * For better performance, prefer one-shot functions whenever applicable. + * + * XXH3_128bits uses the same XXH3_state_t as XXH3_64bits(). + * Use already declared XXH3_createState() and XXH3_freeState(). + * + * All reset and streaming functions have same meaning as their 64-bit counterpart. + */ + XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH3_state_t* statePtr); XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed); XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize); @@ -628,8 +562,9 @@ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH3_state_t* statePt XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH3_state_t* statePtr, const void* input, size_t length); XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* statePtr); - -/* Note: For better performance, these functions can be inlined using XXH_INLINE_ALL */ +/* Following helper functions make it possible to compare XXH128_hast_t values. + * Since XXH128_hash_t is a structure, this capability is not offered by the language. + * Note: For better performance, these functions can be inlined using XXH_INLINE_ALL */ /*! * XXH128_isEqual(): @@ -643,20 +578,161 @@ XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2); * This comparator is compatible with stdlib's `qsort()`/`bsearch()`. * * return: >0 if *h128_1 > *h128_2 - * <0 if *h128_1 < *h128_2 * =0 if *h128_1 == *h128_2 + * <0 if *h128_1 < *h128_2 */ XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2); /******* Canonical representation *******/ -typedef struct { unsigned char digest[16]; } XXH128_canonical_t; +typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical_t; XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash); XXH_PUBLIC_API XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* src); #endif /* XXH_NO_LONG_LONG */ +#endif /* XXHASH_H_5627135585666179 */ + + + +#if defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742) +#define XXHASH_H_STATIC_13879238742 +/* **************************************************************************** + * This section contains declarations which are not guaranteed to remain stable. + * They may change in future versions, becoming incompatible with a different + * version of the library. + * These declarations should only be used with static linking. + * Never use them in association with dynamic linking! + ***************************************************************************** */ + +/* + * These definitions are only present to allow static allocation + * of XXH states, on stack or in a struct, for example. + * Never **ever** access their members directly. + */ + +struct XXH32_state_s { + XXH32_hash_t total_len_32; + XXH32_hash_t large_len; + XXH32_hash_t v1; + XXH32_hash_t v2; + XXH32_hash_t v3; + XXH32_hash_t v4; + XXH32_hash_t mem32[4]; + XXH32_hash_t memsize; + XXH32_hash_t reserved; /* never read nor write, might be removed in a future version */ +}; /* typedef'd to XXH32_state_t */ + + +#ifndef XXH_NO_LONG_LONG /* defined when there is no 64-bit support */ + +struct XXH64_state_s { + XXH64_hash_t total_len; + XXH64_hash_t v1; + XXH64_hash_t v2; + XXH64_hash_t v3; + XXH64_hash_t v4; + XXH64_hash_t mem64[4]; + XXH32_hash_t memsize; + XXH32_hash_t reserved32; /* required for padding anyway */ + XXH64_hash_t reserved64; /* never read nor write, might be removed in a future version */ +}; /* typedef'd to XXH64_state_t */ + +#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11+ */ +# include <stdalign.h> +# define XXH_ALIGN(n) alignas(n) +#elif defined(__GNUC__) +# define XXH_ALIGN(n) __attribute__ ((aligned(n))) +#elif defined(_MSC_VER) +# define XXH_ALIGN(n) __declspec(align(n)) +#else +# define XXH_ALIGN(n) /* disabled */ +#endif + +/* Old GCC versions only accept the attribute after the type in structures. */ +#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) /* C11+ */ \ + && defined(__GNUC__) +# define XXH_ALIGN_MEMBER(align, type) type XXH_ALIGN(align) +#else +# define XXH_ALIGN_MEMBER(align, type) XXH_ALIGN(align) type +#endif + +#define XXH3_INTERNALBUFFER_SIZE 256 +#define XXH3_SECRET_DEFAULT_SIZE 192 +struct XXH3_state_s { + XXH_ALIGN_MEMBER(64, XXH64_hash_t acc[8]); + /* used to store a custom secret generated from a seed */ + XXH_ALIGN_MEMBER(64, unsigned char customSecret[XXH3_SECRET_DEFAULT_SIZE]); + XXH_ALIGN_MEMBER(64, unsigned char buffer[XXH3_INTERNALBUFFER_SIZE]); + XXH32_hash_t bufferedSize; + XXH32_hash_t reserved32; + size_t nbStripesSoFar; + XXH64_hash_t totalLen; + size_t nbStripesPerBlock; + size_t secretLimit; + XXH64_hash_t seed; + XXH64_hash_t reserved64; + const unsigned char* extSecret; /* reference to external secret; + * if == NULL, use .customSecret instead */ + /* note: there may be some padding at the end due to alignment on 64 bytes */ +}; /* typedef'd to XXH3_state_t */ + +#undef XXH_ALIGN_MEMBER + +/* When the XXH3_state_t structure is merely emplaced on stack, + * it should be initialized with XXH3_INITSTATE() or a memset() + * in case its first reset uses XXH3_NNbits_reset_withSeed(). + * This init can be omitted if the first reset uses default or _withSecret mode. + * This operation isn't necessary when the state is created with XXH3_createState(). + * Note that this doesn't prepare the state for a streaming operation, + * it's still necessary to use XXH3_NNbits_reset*() afterwards. + */ +#define XXH3_INITSTATE(XXH3_state_ptr) { (XXH3_state_ptr)->seed = 0; } + + +/* === Experimental API === */ +/* Symbols defined below must be considered tied to a specific library version. */ + +/* + * XXH3_generateSecret(): + * + * Derive a high-entropy secret from any user-defined content, named customSeed. + * The generated secret can be used in combination with `*_withSecret()` functions. + * The `_withSecret()` variants are useful to provide a higher level of protection than 64-bit seed, + * as it becomes much more difficult for an external actor to guess how to impact the calculation logic. + * + * The function accepts as input a custom seed of any length and any content, + * and derives from it a high-entropy secret of length XXH3_SECRET_DEFAULT_SIZE + * into an already allocated buffer secretBuffer. + * The generated secret is _always_ XXH_SECRET_DEFAULT_SIZE bytes long. + * + * The generated secret can then be used with any `*_withSecret()` variant. + * Functions `XXH3_128bits_withSecret()`, `XXH3_64bits_withSecret()`, + * `XXH3_128bits_reset_withSecret()` and `XXH3_64bits_reset_withSecret()` + * are part of this list. They all accept a `secret` parameter + * which must be very long for implementation reasons (>= XXH3_SECRET_SIZE_MIN) + * _and_ feature very high entropy (consist of random-looking bytes). + * These conditions can be a high bar to meet, so + * this function can be used to generate a secret of proper quality. + * + * customSeed can be anything. It can have any size, even small ones, + * and its content can be anything, even stupidly "low entropy" source such as a bunch of zeroes. + * The resulting `secret` will nonetheless provide all expected qualities. + * + * Supplying NULL as the customSeed copies the default secret into `secretBuffer`. + * When customSeedSize > 0, supplying NULL as customSeed is undefined behavior. + */ +XXH_PUBLIC_API void XXH3_generateSecret(void* secretBuffer, const void* customSeed, size_t customSeedSize); + + +/* simple short-cut to pre-selected XXH3_128bits variant */ +XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t seed); + + +#endif /* XXH_NO_LONG_LONG */ + + #if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) # define XXH_IMPLEMENTATION #endif @@ -672,17 +748,23 @@ XXH_PUBLIC_API XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* /*-********************************************************************** * xxHash implementation *-********************************************************************** - * xxHash's implementation used to be found in xxhash.c. + * xxHash's implementation used to be hosted inside xxhash.c. * - * However, code inlining requires the implementation to be visible to the - * compiler, usually within the header. + * However, inlining requires implementation to be visible to the compiler, + * hence be included alongside the header. + * Previously, implementation was hosted inside xxhash.c, + * which was then #included when inlining was activated. + * This construction created issues with a few build and install systems, + * as it required xxhash.c to be stored in /include directory. * - * As a workaround, xxhash.c used to be included within xxhash.h. This caused - * some issues with some build systems, especially ones which treat .c files - * as source files. + * xxHash implementation is now directly integrated within xxhash.h. + * As a consequence, xxhash.c is no longer needed in /include. * - * Therefore, the implementation is now directly integrated within xxhash.h. - * Another small advantage is that xxhash.c is no longer needed in /include. + * xxhash.c is still available and is still useful. + * In a "normal" setup, when xxhash is not inlined, + * xxhash.h only exposes the prototypes and public symbols, + * while xxhash.c can be built into an object file xxhash.o + * which can then be linked into the final binary. ************************************************************************/ #if ( defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) \ @@ -700,10 +782,10 @@ XXH_PUBLIC_API XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* * Unfortunately, on some target/compiler combinations, the generated assembly * is sub-optimal. * - * The below switch allow to select a different access method for improved - * performance. + * The below switch allow selection of a different access method + * in the search for improved performance. * Method 0 (default): - * Use `memcpy()`. Safe and portable. + * Use `memcpy()`. Safe and portable. Default. * Method 1: * `__attribute__((packed))` statement. It depends on compiler extensions * and is therefore not portable. @@ -715,7 +797,7 @@ XXH_PUBLIC_API XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* * It can generate buggy code on targets which do not support unaligned * memory accesses. * But in some circumstances, it's the only known way to get the most - * performance (ie GCC + ARMv6) + * performance (example: GCC + ARMv6) * Method 3: * Byteshift. This can generate the best code on old compilers which don't * inline small `memcpy()` calls, and it might also be faster on big-endian @@ -733,7 +815,7 @@ XXH_PUBLIC_API XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* #endif /*! - *XXH_ACCEPT_NULL_INPUT_POINTER: + * XXH_ACCEPT_NULL_INPUT_POINTER: * If the input pointer is NULL, xxHash's default behavior is to dereference it, * triggering a segfault. * When this macro is enabled, xxHash actively checks the input for a null pointer. @@ -745,16 +827,26 @@ XXH_PUBLIC_API XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* /*! * XXH_FORCE_ALIGN_CHECK: - * This is a minor performance trick, only useful with lots of very small keys. - * It means: check for aligned/unaligned input. - * The check costs one initial branch per hash; - * Set it to 0 when the input is guaranteed to be aligned or when alignment - * doesn't matter for performance. + * This is an important performance trick + * for architectures without decent unaligned memory access performance. + * It checks for input alignment, and when conditions are met, + * uses a "fast path" employing direct 32-bit/64-bit read, + * resulting in _dramatically faster_ read speed. * - * This option does not affect XXH3. + * The check costs one initial branch per hash, which is generally negligible, but not zero. + * Moreover, it's not useful to generate binary for an additional code path + * if memory access uses same instruction for both aligned and unaligned adresses. + * + * In these cases, the alignment check can be removed by setting this macro to 0. + * Then the code will always use unaligned memory access. + * Align check is automatically disabled on x86, x64 & arm64, + * which are platforms known to offer good unaligned memory accesses performance. + * + * This option does not affect XXH3 (only XXH32 and XXH64). */ -#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */ -# if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) +#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */ +# if defined(__i386) || defined(__x86_64__) || defined(__aarch64__) \ + || defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64) /* visual */ # define XXH_FORCE_ALIGN_CHECK 0 # else # define XXH_FORCE_ALIGN_CHECK 1 @@ -809,12 +901,14 @@ XXH_PUBLIC_API XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* * Includes & Memory related functions ***************************************/ /*! - * Modify the local functions below should you wish to use some other memory - * routines for malloc() and free() + * Modify the local functions below should you wish to use + * different memory routines for malloc() and free() */ #include <stdlib.h> + static void* XXH_malloc(size_t s) { return malloc(s); } -static void XXH_free (void* p) { free(p); } +static void XXH_free(void* p) { free(p); } + /*! and for memcpy() */ #include <string.h> static void* XXH_memcpy(void* dest, const void* src, size_t size) @@ -832,26 +926,27 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ #endif -#if XXH_NO_INLINE_HINTS /* disable inlining hints */ -# define XXH_FORCE_INLINE static +#if XXH_NO_INLINE_HINTS /* disable inlining hints */ +# if defined(__GNUC__) +# define XXH_FORCE_INLINE static __attribute__((unused)) +# else +# define XXH_FORCE_INLINE static +# endif # define XXH_NO_INLINE static -#elif defined(_MSC_VER) /* Visual Studio */ +/* enable inlining hints */ +#elif defined(_MSC_VER) /* Visual Studio */ # define XXH_FORCE_INLINE static __forceinline # define XXH_NO_INLINE static __declspec(noinline) +#elif defined(__GNUC__) +# define XXH_FORCE_INLINE static __inline__ __attribute__((always_inline, unused)) +# define XXH_NO_INLINE static __attribute__((noinline)) +#elif defined (__cplusplus) \ + || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) /* C99 */ +# define XXH_FORCE_INLINE static inline +# define XXH_NO_INLINE static #else -# if defined (__cplusplus) \ - || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ -# ifdef __GNUC__ -# define XXH_FORCE_INLINE static inline __attribute__((always_inline)) -# define XXH_NO_INLINE static __attribute__((noinline)) -# else -# define XXH_FORCE_INLINE static inline -# define XXH_NO_INLINE static -# endif -# else -# define XXH_FORCE_INLINE static -# define XXH_NO_INLINE static -# endif /* __STDC_VERSION__ */ +# define XXH_FORCE_INLINE static +# define XXH_NO_INLINE static #endif @@ -860,14 +955,18 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) * Debug ***************************************/ /* - * DEBUGLEVEL is expected to be defined externally, typically via the compiler's - * command line options. The value must be a number. + * XXH_DEBUGLEVEL is expected to be defined externally, typically via the + * compiler's command line options. The value must be a number. */ -#ifndef DEBUGLEVEL -# define DEBUGLEVEL 0 +#ifndef XXH_DEBUGLEVEL +# ifdef DEBUGLEVEL /* backwards compat */ +# define XXH_DEBUGLEVEL DEBUGLEVEL +# else +# define XXH_DEBUGLEVEL 0 +# endif #endif -#if (DEBUGLEVEL>=1) +#if (XXH_DEBUGLEVEL>=1) # include <assert.h> /* note: can still be disabled with NDEBUG */ # define XXH_ASSERT(c) assert(c) #else @@ -875,7 +974,7 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) #endif /* note: use after variable declarations */ -#define XXH_STATIC_ASSERT(c) { enum { XXH_sa = 1/(int)(!!(c)) }; } +#define XXH_STATIC_ASSERT(c) do { enum { XXH_sa = 1/(int)(!!(c)) }; } while (0) /* ************************************* @@ -885,12 +984,17 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) # include <stdint.h> - typedef uint8_t xxh_u8; + typedef uint8_t xxh_u8; #else - typedef unsigned char xxh_u8; + typedef unsigned char xxh_u8; #endif typedef XXH32_hash_t xxh_u32; +#ifdef XXH_OLD_NAMES +# define BYTE xxh_u8 +# define U8 xxh_u8 +# define U32 xxh_u32 +#endif /* *** Memory access *** */ @@ -915,8 +1019,14 @@ static xxh_u32 XXH_read32(const void* memPtr) { return *(const xxh_u32*) memPtr; * * Currently only defined for GCC and ICC. */ +#ifdef XXH_OLD_NAMES typedef union { xxh_u32 u32; } __attribute__((packed)) unalign; -static xxh_u32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } +#endif +static xxh_u32 XXH_read32(const void* ptr) +{ + typedef union { xxh_u32 u32; } __attribute__((packed)) xxh_unalign; + return ((const xxh_unalign*)ptr)->u32; +} #else @@ -958,10 +1068,13 @@ typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess; || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) # define XXH_CPU_LITTLE_ENDIAN 0 # else +/* + * runtime test, presumed to simplify to a constant by compiler + */ static int XXH_isLittleEndian(void) { /* - * Nonstandard, but well-defined behavior in practice. + * Portable and well-defined behavior. * Don't use static: it is detrimental to performance. */ const union { xxh_u32 u; xxh_u8 c[4]; } one = { 1 }; @@ -979,12 +1092,14 @@ static int XXH_isLittleEndian(void) ******************************************/ #define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) -#ifndef __has_builtin -# define __has_builtin(x) 0 +#ifdef __has_builtin +# define XXH_HAS_BUILTIN(x) __has_builtin(x) +#else +# define XXH_HAS_BUILTIN(x) 0 #endif -#if !defined(NO_CLANG_BUILTIN) && __has_builtin(__builtin_rotateleft32) \ - && __has_builtin(__builtin_rotateleft64) +#if !defined(NO_CLANG_BUILTIN) && XXH_HAS_BUILTIN(__builtin_rotateleft32) \ + && XXH_HAS_BUILTIN(__builtin_rotateleft64) # define XXH_rotl32 __builtin_rotateleft32 # define XXH_rotl64 __builtin_rotateleft64 /* Note: although _rotl exists for minGW (GCC under windows), performance seems poor */ @@ -1073,17 +1188,25 @@ XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; } /* ******************************************************************* * 32-bit hash functions *********************************************************************/ -static const xxh_u32 PRIME32_1 = 0x9E3779B1U; /* 0b10011110001101110111100110110001 */ -static const xxh_u32 PRIME32_2 = 0x85EBCA77U; /* 0b10000101111010111100101001110111 */ -static const xxh_u32 PRIME32_3 = 0xC2B2AE3DU; /* 0b11000010101100101010111000111101 */ -static const xxh_u32 PRIME32_4 = 0x27D4EB2FU; /* 0b00100111110101001110101100101111 */ -static const xxh_u32 PRIME32_5 = 0x165667B1U; /* 0b00010110010101100110011110110001 */ +static const xxh_u32 XXH_PRIME32_1 = 0x9E3779B1U; /* 0b10011110001101110111100110110001 */ +static const xxh_u32 XXH_PRIME32_2 = 0x85EBCA77U; /* 0b10000101111010111100101001110111 */ +static const xxh_u32 XXH_PRIME32_3 = 0xC2B2AE3DU; /* 0b11000010101100101010111000111101 */ +static const xxh_u32 XXH_PRIME32_4 = 0x27D4EB2FU; /* 0b00100111110101001110101100101111 */ +static const xxh_u32 XXH_PRIME32_5 = 0x165667B1U; /* 0b00010110010101100110011110110001 */ + +#ifdef XXH_OLD_NAMES +# define PRIME32_1 XXH_PRIME32_1 +# define PRIME32_2 XXH_PRIME32_2 +# define PRIME32_3 XXH_PRIME32_3 +# define PRIME32_4 XXH_PRIME32_4 +# define PRIME32_5 XXH_PRIME32_5 +#endif static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input) { - acc += input * PRIME32_2; + acc += input * XXH_PRIME32_2; acc = XXH_rotl32(acc, 13); - acc *= PRIME32_1; + acc *= XXH_PRIME32_1; #if defined(__GNUC__) && defined(__SSE4_1__) && !defined(XXH_ENABLE_AUTOVECTORIZE) /* * UGLY HACK: @@ -1139,9 +1262,9 @@ static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input) static xxh_u32 XXH32_avalanche(xxh_u32 h32) { h32 ^= h32 >> 15; - h32 *= PRIME32_2; + h32 *= XXH_PRIME32_2; h32 ^= h32 >> 13; - h32 *= PRIME32_3; + h32 *= XXH_PRIME32_3; h32 ^= h32 >> 16; return(h32); } @@ -1151,64 +1274,66 @@ static xxh_u32 XXH32_avalanche(xxh_u32 h32) static xxh_u32 XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align) { -#define PROCESS1 \ - h32 += (*ptr++) * PRIME32_5; \ - h32 = XXH_rotl32(h32, 11) * PRIME32_1 ; +#define XXH_PROCESS1 do { \ + h32 += (*ptr++) * XXH_PRIME32_5; \ + h32 = XXH_rotl32(h32, 11) * XXH_PRIME32_1; \ +} while (0) -#define PROCESS4 \ - h32 += XXH_get32bits(ptr) * PRIME32_3; \ - ptr+=4; \ - h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; +#define XXH_PROCESS4 do { \ + h32 += XXH_get32bits(ptr) * XXH_PRIME32_3; \ + ptr += 4; \ + h32 = XXH_rotl32(h32, 17) * XXH_PRIME32_4; \ +} while (0) /* Compact rerolled version */ if (XXH_REROLL) { len &= 15; while (len >= 4) { - PROCESS4; + XXH_PROCESS4; len -= 4; } while (len > 0) { - PROCESS1; + XXH_PROCESS1; --len; } return XXH32_avalanche(h32); } else { switch(len&15) /* or switch(bEnd - p) */ { - case 12: PROCESS4; + case 12: XXH_PROCESS4; /* fallthrough */ - case 8: PROCESS4; + case 8: XXH_PROCESS4; /* fallthrough */ - case 4: PROCESS4; + case 4: XXH_PROCESS4; return XXH32_avalanche(h32); - case 13: PROCESS4; + case 13: XXH_PROCESS4; /* fallthrough */ - case 9: PROCESS4; + case 9: XXH_PROCESS4; /* fallthrough */ - case 5: PROCESS4; - PROCESS1; + case 5: XXH_PROCESS4; + XXH_PROCESS1; return XXH32_avalanche(h32); - case 14: PROCESS4; + case 14: XXH_PROCESS4; /* fallthrough */ - case 10: PROCESS4; + case 10: XXH_PROCESS4; /* fallthrough */ - case 6: PROCESS4; - PROCESS1; - PROCESS1; + case 6: XXH_PROCESS4; + XXH_PROCESS1; + XXH_PROCESS1; return XXH32_avalanche(h32); - case 15: PROCESS4; + case 15: XXH_PROCESS4; /* fallthrough */ - case 11: PROCESS4; + case 11: XXH_PROCESS4; /* fallthrough */ - case 7: PROCESS4; + case 7: XXH_PROCESS4; /* fallthrough */ - case 3: PROCESS1; + case 3: XXH_PROCESS1; /* fallthrough */ - case 2: PROCESS1; + case 2: XXH_PROCESS1; /* fallthrough */ - case 1: PROCESS1; + case 1: XXH_PROCESS1; /* fallthrough */ case 0: return XXH32_avalanche(h32); } @@ -1217,6 +1342,14 @@ XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align) } } +#ifdef XXH_OLD_NAMES +# define PROCESS1 XXH_PROCESS1 +# define PROCESS4 XXH_PROCESS4 +#else +# undef XXH_PROCESS1 +# undef XXH_PROCESS4 +#endif + XXH_FORCE_INLINE xxh_u32 XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment align) { @@ -1232,10 +1365,10 @@ XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment if (len>=16) { const xxh_u8* const limit = bEnd - 15; - xxh_u32 v1 = seed + PRIME32_1 + PRIME32_2; - xxh_u32 v2 = seed + PRIME32_2; + xxh_u32 v1 = seed + XXH_PRIME32_1 + XXH_PRIME32_2; + xxh_u32 v2 = seed + XXH_PRIME32_2; xxh_u32 v3 = seed + 0; - xxh_u32 v4 = seed - PRIME32_1; + xxh_u32 v4 = seed - XXH_PRIME32_1; do { v1 = XXH32_round(v1, XXH_get32bits(input)); input += 4; @@ -1247,7 +1380,7 @@ XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); } else { - h32 = seed + PRIME32_5; + h32 = seed + XXH_PRIME32_5; } h32 += (xxh_u32)len; @@ -1299,10 +1432,10 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t s { XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ memset(&state, 0, sizeof(state)); - state.v1 = seed + PRIME32_1 + PRIME32_2; - state.v2 = seed + PRIME32_2; + state.v1 = seed + XXH_PRIME32_1 + XXH_PRIME32_2; + state.v2 = seed + XXH_PRIME32_2; state.v3 = seed + 0; - state.v4 = seed - PRIME32_1; + state.v4 = seed - XXH_PRIME32_1; /* do not write into reserved, planned to be removed in a future version */ memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved)); return XXH_OK; @@ -1383,7 +1516,7 @@ XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* state) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18); } else { - h32 = state->v3 /* == seed */ + PRIME32_5; + h32 = state->v3 /* == seed */ + XXH_PRIME32_5; } h32 += state->total_len_32; @@ -1430,6 +1563,9 @@ XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src typedef XXH64_hash_t xxh_u64; +#ifdef XXH_OLD_NAMES +# define U64 xxh_u64 +#endif /*! * XXH_REROLL_XXH64: @@ -1478,8 +1614,14 @@ static xxh_u64 XXH_read64(const void* memPtr) { return *(const xxh_u64*) memPtr; * * Currently only defined for GCC and ICC. */ +#ifdef XXH_OLD_NAMES typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) unalign64; -static xxh_u64 XXH_read64(const void* ptr) { return ((const unalign64*)ptr)->u64; } +#endif +static xxh_u64 XXH_read64(const void* ptr) +{ + typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) xxh_unalign64; + return ((const xxh_unalign64*)ptr)->u64; +} #else @@ -1568,17 +1710,25 @@ XXH_readLE64_align(const void* ptr, XXH_alignment align) /******* xxh64 *******/ -static const xxh_u64 PRIME64_1 = 0x9E3779B185EBCA87ULL; /* 0b1001111000110111011110011011000110000101111010111100101010000111 */ -static const xxh_u64 PRIME64_2 = 0xC2B2AE3D27D4EB4FULL; /* 0b1100001010110010101011100011110100100111110101001110101101001111 */ -static const xxh_u64 PRIME64_3 = 0x165667B19E3779F9ULL; /* 0b0001011001010110011001111011000110011110001101110111100111111001 */ -static const xxh_u64 PRIME64_4 = 0x85EBCA77C2B2AE63ULL; /* 0b1000010111101011110010100111011111000010101100101010111001100011 */ -static const xxh_u64 PRIME64_5 = 0x27D4EB2F165667C5ULL; /* 0b0010011111010100111010110010111100010110010101100110011111000101 */ +static const xxh_u64 XXH_PRIME64_1 = 0x9E3779B185EBCA87ULL; /* 0b1001111000110111011110011011000110000101111010111100101010000111 */ +static const xxh_u64 XXH_PRIME64_2 = 0xC2B2AE3D27D4EB4FULL; /* 0b1100001010110010101011100011110100100111110101001110101101001111 */ +static const xxh_u64 XXH_PRIME64_3 = 0x165667B19E3779F9ULL; /* 0b0001011001010110011001111011000110011110001101110111100111111001 */ +static const xxh_u64 XXH_PRIME64_4 = 0x85EBCA77C2B2AE63ULL; /* 0b1000010111101011110010100111011111000010101100101010111001100011 */ +static const xxh_u64 XXH_PRIME64_5 = 0x27D4EB2F165667C5ULL; /* 0b0010011111010100111010110010111100010110010101100110011111000101 */ + +#ifdef XXH_OLD_NAMES +# define PRIME64_1 XXH_PRIME64_1 +# define PRIME64_2 XXH_PRIME64_2 +# define PRIME64_3 XXH_PRIME64_3 +# define PRIME64_4 XXH_PRIME64_4 +# define PRIME64_5 XXH_PRIME64_5 +#endif static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input) { - acc += input * PRIME64_2; + acc += input * XXH_PRIME64_2; acc = XXH_rotl64(acc, 31); - acc *= PRIME64_1; + acc *= XXH_PRIME64_1; return acc; } @@ -1586,16 +1736,16 @@ static xxh_u64 XXH64_mergeRound(xxh_u64 acc, xxh_u64 val) { val = XXH64_round(0, val); acc ^= val; - acc = acc * PRIME64_1 + PRIME64_4; + acc = acc * XXH_PRIME64_1 + XXH_PRIME64_4; return acc; } static xxh_u64 XXH64_avalanche(xxh_u64 h64) { h64 ^= h64 >> 33; - h64 *= PRIME64_2; + h64 *= XXH_PRIME64_2; h64 ^= h64 >> 29; - h64 *= PRIME64_3; + h64 *= XXH_PRIME64_3; h64 ^= h64 >> 32; return h64; } @@ -1606,117 +1756,119 @@ static xxh_u64 XXH64_avalanche(xxh_u64 h64) static xxh_u64 XXH64_finalize(xxh_u64 h64, const xxh_u8* ptr, size_t len, XXH_alignment align) { -#define PROCESS1_64 \ - h64 ^= (*ptr++) * PRIME64_5; \ - h64 = XXH_rotl64(h64, 11) * PRIME64_1; - -#define PROCESS4_64 \ - h64 ^= (xxh_u64)(XXH_get32bits(ptr)) * PRIME64_1; \ - ptr+=4; \ - h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; - -#define PROCESS8_64 { \ +#define XXH_PROCESS1_64 do { \ + h64 ^= (*ptr++) * XXH_PRIME64_5; \ + h64 = XXH_rotl64(h64, 11) * XXH_PRIME64_1; \ +} while (0) + +#define XXH_PROCESS4_64 do { \ + h64 ^= (xxh_u64)(XXH_get32bits(ptr)) * XXH_PRIME64_1; \ + ptr += 4; \ + h64 = XXH_rotl64(h64, 23) * XXH_PRIME64_2 + XXH_PRIME64_3; \ +} while (0) + +#define XXH_PROCESS8_64 do { \ xxh_u64 const k1 = XXH64_round(0, XXH_get64bits(ptr)); \ - ptr+=8; \ - h64 ^= k1; \ - h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; \ -} + ptr += 8; \ + h64 ^= k1; \ + h64 = XXH_rotl64(h64,27) * XXH_PRIME64_1 + XXH_PRIME64_4; \ +} while (0) /* Rerolled version for 32-bit targets is faster and much smaller. */ if (XXH_REROLL || XXH_REROLL_XXH64) { len &= 31; while (len >= 8) { - PROCESS8_64; + XXH_PROCESS8_64; len -= 8; } if (len >= 4) { - PROCESS4_64; + XXH_PROCESS4_64; len -= 4; } while (len > 0) { - PROCESS1_64; + XXH_PROCESS1_64; --len; } return XXH64_avalanche(h64); } else { switch(len & 31) { - case 24: PROCESS8_64; + case 24: XXH_PROCESS8_64; /* fallthrough */ - case 16: PROCESS8_64; + case 16: XXH_PROCESS8_64; /* fallthrough */ - case 8: PROCESS8_64; + case 8: XXH_PROCESS8_64; return XXH64_avalanche(h64); - case 28: PROCESS8_64; + case 28: XXH_PROCESS8_64; /* fallthrough */ - case 20: PROCESS8_64; + case 20: XXH_PROCESS8_64; /* fallthrough */ - case 12: PROCESS8_64; + case 12: XXH_PROCESS8_64; /* fallthrough */ - case 4: PROCESS4_64; + case 4: XXH_PROCESS4_64; return XXH64_avalanche(h64); - case 25: PROCESS8_64; + case 25: XXH_PROCESS8_64; /* fallthrough */ - case 17: PROCESS8_64; + case 17: XXH_PROCESS8_64; /* fallthrough */ - case 9: PROCESS8_64; - PROCESS1_64; + case 9: XXH_PROCESS8_64; + XXH_PROCESS1_64; return XXH64_avalanche(h64); - case 29: PROCESS8_64; + case 29: XXH_PROCESS8_64; /* fallthrough */ - case 21: PROCESS8_64; + case 21: XXH_PROCESS8_64; /* fallthrough */ - case 13: PROCESS8_64; + case 13: XXH_PROCESS8_64; /* fallthrough */ - case 5: PROCESS4_64; - PROCESS1_64; + case 5: XXH_PROCESS4_64; + XXH_PROCESS1_64; return XXH64_avalanche(h64); - case 26: PROCESS8_64; + case 26: XXH_PROCESS8_64; /* fallthrough */ - case 18: PROCESS8_64; + case 18: XXH_PROCESS8_64; /* fallthrough */ - case 10: PROCESS8_64; - PROCESS1_64; - PROCESS1_64; + case 10: XXH_PROCESS8_64; + XXH_PROCESS1_64; + XXH_PROCESS1_64; return XXH64_avalanche(h64); - case 30: PROCESS8_64; + case 30: XXH_PROCESS8_64; /* fallthrough */ - case 22: PROCESS8_64; + case 22: XXH_PROCESS8_64; /* fallthrough */ - case 14: PROCESS8_64; + case 14: XXH_PROCESS8_64; /* fallthrough */ - case 6: PROCESS4_64; - PROCESS1_64; - PROCESS1_64; + case 6: XXH_PROCESS4_64; + XXH_PROCESS1_64; + XXH_PROCESS1_64; return XXH64_avalanche(h64); - case 27: PROCESS8_64; + case 27: XXH_PROCESS8_64; /* fallthrough */ - case 19: PROCESS8_64; + case 19: XXH_PROCESS8_64; /* fallthrough */ - case 11: PROCESS8_64; - PROCESS1_64; - PROCESS1_64; - PROCESS1_64; + case 11: XXH_PROCESS8_64; + XXH_PROCESS1_64; + XXH_PROCESS1_64; + XXH_PROCESS1_64; return XXH64_avalanche(h64); - case 31: PROCESS8_64; + case 31: XXH_PROCESS8_64; /* fallthrough */ - case 23: PROCESS8_64; + case 23: XXH_PROCESS8_64; /* fallthrough */ - case 15: PROCESS8_64; + case 15: XXH_PROCESS8_64; /* fallthrough */ - case 7: PROCESS4_64; + case 7: XXH_PROCESS4_64; /* fallthrough */ - case 3: PROCESS1_64; + case 3: XXH_PROCESS1_64; /* fallthrough */ - case 2: PROCESS1_64; + case 2: XXH_PROCESS1_64; /* fallthrough */ - case 1: PROCESS1_64; + case 1: XXH_PROCESS1_64; /* fallthrough */ case 0: return XXH64_avalanche(h64); } @@ -1726,6 +1878,16 @@ XXH64_finalize(xxh_u64 h64, const xxh_u8* ptr, size_t len, XXH_alignment align) return 0; /* unreachable, but some compilers complain without it */ } +#ifdef XXH_OLD_NAMES +# define PROCESS1_64 XXH_PROCESS1_64 +# define PROCESS4_64 XXH_PROCESS4_64 +# define PROCESS8_64 XXH_PROCESS8_64 +#else +# undef XXH_PROCESS1_64 +# undef XXH_PROCESS4_64 +# undef XXH_PROCESS8_64 +#endif + XXH_FORCE_INLINE xxh_u64 XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment align) { @@ -1741,10 +1903,10 @@ XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment if (len>=32) { const xxh_u8* const limit = bEnd - 32; - xxh_u64 v1 = seed + PRIME64_1 + PRIME64_2; - xxh_u64 v2 = seed + PRIME64_2; + xxh_u64 v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2; + xxh_u64 v2 = seed + XXH_PRIME64_2; xxh_u64 v3 = seed + 0; - xxh_u64 v4 = seed - PRIME64_1; + xxh_u64 v4 = seed - XXH_PRIME64_1; do { v1 = XXH64_round(v1, XXH_get64bits(input)); input+=8; @@ -1760,7 +1922,7 @@ XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment h64 = XXH64_mergeRound(h64, v4); } else { - h64 = seed + PRIME64_5; + h64 = seed + XXH_PRIME64_5; } h64 += (xxh_u64) len; @@ -1811,10 +1973,10 @@ XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, XXH64_hash_t s { XXH64_state_t state; /* use a local state to memcpy() in order to avoid strict-aliasing warnings */ memset(&state, 0, sizeof(state)); - state.v1 = seed + PRIME64_1 + PRIME64_2; - state.v2 = seed + PRIME64_2; + state.v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2; + state.v2 = seed + XXH_PRIME64_2; state.v3 = seed + 0; - state.v4 = seed - PRIME64_1; + state.v4 = seed - XXH_PRIME64_1; /* do not write into reserved64, might be removed in a future version */ memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved64)); return XXH_OK; @@ -1897,7 +2059,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* state) h64 = XXH64_mergeRound(h64, v3); h64 = XXH64_mergeRound(h64, v4); } else { - h64 = state->v3 /*seed*/ + PRIME64_5; + h64 = state->v3 /*seed*/ + XXH_PRIME64_5; } h64 += (xxh_u64) state->total_len; @@ -1927,8 +2089,2671 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src * New generation hash designed for speed on small keys and vectorization ************************************************************************ */ -#include "xxh3.h" +/* === Compiler specifics === */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */ +# define XXH_RESTRICT restrict +#else +/* Note: it might be useful to define __restrict or __restrict__ for some C++ compilers */ +# define XXH_RESTRICT /* disable */ +#endif + +#if (defined(__GNUC__) && (__GNUC__ >= 3)) \ + || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) \ + || defined(__clang__) +# define XXH_likely(x) __builtin_expect(x, 1) +# define XXH_unlikely(x) __builtin_expect(x, 0) +#else +# define XXH_likely(x) (x) +# define XXH_unlikely(x) (x) +#endif + +#if defined(__GNUC__) +# if defined(__AVX2__) +# include <immintrin.h> +# elif defined(__SSE2__) +# include <emmintrin.h> +# elif defined(__ARM_NEON__) || defined(__ARM_NEON) +# define inline __inline__ /* circumvent a clang bug */ +# include <arm_neon.h> +# undef inline +# endif +#elif defined(_MSC_VER) +# include <intrin.h> +#endif + +/* + * One goal of XXH3 is to make it fast on both 32-bit and 64-bit, while + * remaining a true 64-bit/128-bit hash function. + * + * This is done by prioritizing a subset of 64-bit operations that can be + * emulated without too many steps on the average 32-bit machine. + * + * For example, these two lines seem similar, and run equally fast on 64-bit: + * + * xxh_u64 x; + * x ^= (x >> 47); // good + * x ^= (x >> 13); // bad + * + * However, to a 32-bit machine, there is a major difference. + * + * x ^= (x >> 47) looks like this: + * + * x.lo ^= (x.hi >> (47 - 32)); + * + * while x ^= (x >> 13) looks like this: + * + * // note: funnel shifts are not usually cheap. + * x.lo ^= (x.lo >> 13) | (x.hi << (32 - 13)); + * x.hi ^= (x.hi >> 13); + * + * The first one is significantly faster than the second, simply because the + * shift is larger than 32. This means: + * - All the bits we need are in the upper 32 bits, so we can ignore the lower + * 32 bits in the shift. + * - The shift result will always fit in the lower 32 bits, and therefore, + * we can ignore the upper 32 bits in the xor. + * + * Thanks to this optimization, XXH3 only requires these features to be efficient: + * + * - Usable unaligned access + * - A 32-bit or 64-bit ALU + * - If 32-bit, a decent ADC instruction + * - A 32 or 64-bit multiply with a 64-bit result + * - For the 128-bit variant, a decent byteswap helps short inputs. + * + * The first two are already required by XXH32, and almost all 32-bit and 64-bit + * platforms which can run XXH32 can run XXH3 efficiently. + * + * Thumb-1, the classic 16-bit only subset of ARM's instruction set, is one + * notable exception. + * + * First of all, Thumb-1 lacks support for the UMULL instruction which + * performs the important long multiply. This means numerous __aeabi_lmul + * calls. + * + * Second of all, the 8 functional registers are just not enough. + * Setup for __aeabi_lmul, byteshift loads, pointers, and all arithmetic need + * Lo registers, and this shuffling results in thousands more MOVs than A32. + * + * A32 and T32 don't have this limitation. They can access all 14 registers, + * do a 32->64 multiply with UMULL, and the flexible operand allowing free + * shifts is helpful, too. + * + * Therefore, we do a quick sanity check. + * + * If compiling Thumb-1 for a target which supports ARM instructions, we will + * emit a warning, as it is not a "sane" platform to compile for. + * + * Usually, if this happens, it is because of an accident and you probably need + * to specify -march, as you likely meant to compile for a newer architecture. + * + * Credit: large sections of the vectorial and asm source code paths + * have been contributed by @easyaspi314 + */ +#if defined(__thumb__) && !defined(__thumb2__) && defined(__ARM_ARCH_ISA_ARM) +# warning "XXH3 is highly inefficient without ARM or Thumb-2." +#endif + +/* ========================================== + * Vectorization detection + * ========================================== */ +#define XXH_SCALAR 0 /* Portable scalar version */ +#define XXH_SSE2 1 /* SSE2 for Pentium 4 and all x86_64 */ +#define XXH_AVX2 2 /* AVX2 for Haswell and Bulldozer */ +#define XXH_AVX512 3 /* AVX512 for Skylake and Icelake */ +#define XXH_NEON 4 /* NEON for most ARMv7-A and all AArch64 */ +#define XXH_VSX 5 /* VSX and ZVector for POWER8/z13 */ + +#ifndef XXH_VECTOR /* can be defined on command line */ +# if defined(__AVX512F__) +# define XXH_VECTOR XXH_AVX512 +# elif defined(__AVX2__) +# define XXH_VECTOR XXH_AVX2 +# elif defined(__SSE2__) || defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP == 2)) +# define XXH_VECTOR XXH_SSE2 +# elif defined(__GNUC__) /* msvc support maybe later */ \ + && (defined(__ARM_NEON__) || defined(__ARM_NEON)) \ + && (defined(__LITTLE_ENDIAN__) /* We only support little endian NEON */ \ + || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) +# define XXH_VECTOR XXH_NEON +# elif (defined(__PPC64__) && defined(__POWER8_VECTOR__)) \ + || (defined(__s390x__) && defined(__VEC__)) \ + && defined(__GNUC__) /* TODO: IBM XL */ +# define XXH_VECTOR XXH_VSX +# else +# define XXH_VECTOR XXH_SCALAR +# endif +#endif + +/* + * Controls the alignment of the accumulator, + * for compatibility with aligned vector loads, which are usually faster. + */ +#ifndef XXH_ACC_ALIGN +# if defined(XXH_X86DISPATCH) +# define XXH_ACC_ALIGN 64 /* for compatibility with avx512 */ +# elif XXH_VECTOR == XXH_SCALAR /* scalar */ +# define XXH_ACC_ALIGN 8 +# elif XXH_VECTOR == XXH_SSE2 /* sse2 */ +# define XXH_ACC_ALIGN 16 +# elif XXH_VECTOR == XXH_AVX2 /* avx2 */ +# define XXH_ACC_ALIGN 32 +# elif XXH_VECTOR == XXH_NEON /* neon */ +# define XXH_ACC_ALIGN 16 +# elif XXH_VECTOR == XXH_VSX /* vsx */ +# define XXH_ACC_ALIGN 16 +# elif XXH_VECTOR == XXH_AVX512 /* avx512 */ +# define XXH_ACC_ALIGN 64 +# endif +#endif + +#if defined(XXH_X86DISPATCH) || XXH_VECTOR == XXH_SSE2 \ + || XXH_VECTOR == XXH_AVX2 || XXH_VECTOR == XXH_AVX512 +# define XXH_SEC_ALIGN XXH_ACC_ALIGN +#else +# define XXH_SEC_ALIGN 8 +#endif + +/* + * UGLY HACK: + * GCC usually generates the best code with -O3 for xxHash. + * + * However, when targeting AVX2, it is overzealous in its unrolling resulting + * in code roughly 3/4 the speed of Clang. + * + * There are other issues, such as GCC splitting _mm256_loadu_si256 into + * _mm_loadu_si128 + _mm256_inserti128_si256. This is an optimization which + * only applies to Sandy and Ivy Bridge... which don't even support AVX2. + * + * That is why when compiling the AVX2 version, it is recommended to use either + * -O2 -mavx2 -march=haswell + * or + * -O2 -mavx2 -mno-avx256-split-unaligned-load + * for decent performance, or to use Clang instead. + * + * Fortunately, we can control the first one with a pragma that forces GCC into + * -O2, but the other one we can't control without "failed to inline always + * inline function due to target mismatch" warnings. + */ +#if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \ + && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \ + && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */ +# pragma GCC push_options +# pragma GCC optimize("-O2") +#endif + + +#if XXH_VECTOR == XXH_NEON +/* + * NEON's setup for vmlal_u32 is a little more complicated than it is on + * SSE2, AVX2, and VSX. + * + * While PMULUDQ and VMULEUW both perform a mask, VMLAL.U32 performs an upcast. + * + * To do the same operation, the 128-bit 'Q' register needs to be split into + * two 64-bit 'D' registers, performing this operation:: + * + * [ a | b ] + * | '---------. .--------' | + * | x | + * | .---------' '--------. | + * [ a & 0xFFFFFFFF | b & 0xFFFFFFFF ],[ a >> 32 | b >> 32 ] + * + * Due to significant changes in aarch64, the fastest method for aarch64 is + * completely different than the fastest method for ARMv7-A. + * + * ARMv7-A treats D registers as unions overlaying Q registers, so modifying + * D11 will modify the high half of Q5. This is similar to how modifying AH + * will only affect bits 8-15 of AX on x86. + * + * VZIP takes two registers, and puts even lanes in one register and odd lanes + * in the other. + * + * On ARMv7-A, this strangely modifies both parameters in place instead of + * taking the usual 3-operand form. + * + * Therefore, if we want to do this, we can simply use a D-form VZIP.32 on the + * lower and upper halves of the Q register to end up with the high and low + * halves where we want - all in one instruction. + * + * vzip.32 d10, d11 @ d10 = { d10[0], d11[0] }; d11 = { d10[1], d11[1] } + * + * Unfortunately we need inline assembly for this: Instructions modifying two + * registers at once is not possible in GCC or Clang's IR, and they have to + * create a copy. + * + * aarch64 requires a different approach. + * + * In order to make it easier to write a decent compiler for aarch64, many + * quirks were removed, such as conditional execution. + * + * NEON was also affected by this. + * + * aarch64 cannot access the high bits of a Q-form register, and writes to a + * D-form register zero the high bits, similar to how writes to W-form scalar + * registers (or DWORD registers on x86_64) work. + * + * The formerly free vget_high intrinsics now require a vext (with a few + * exceptions) + * + * Additionally, VZIP was replaced by ZIP1 and ZIP2, which are the equivalent + * of PUNPCKL* and PUNPCKH* in SSE, respectively, in order to only modify one + * operand. + * + * The equivalent of the VZIP.32 on the lower and upper halves would be this + * mess: + * + * ext v2.4s, v0.4s, v0.4s, #2 // v2 = { v0[2], v0[3], v0[0], v0[1] } + * zip1 v1.2s, v0.2s, v2.2s // v1 = { v0[0], v2[0] } + * zip2 v0.2s, v0.2s, v1.2s // v0 = { v0[1], v2[1] } + * + * Instead, we use a literal downcast, vmovn_u64 (XTN), and vshrn_n_u64 (SHRN): + * + * shrn v1.2s, v0.2d, #32 // v1 = (uint32x2_t)(v0 >> 32); + * xtn v0.2s, v0.2d // v0 = (uint32x2_t)(v0 & 0xFFFFFFFF); + * + * This is available on ARMv7-A, but is less efficient than a single VZIP.32. + */ + +/* + * Function-like macro: + * void XXH_SPLIT_IN_PLACE(uint64x2_t &in, uint32x2_t &outLo, uint32x2_t &outHi) + * { + * outLo = (uint32x2_t)(in & 0xFFFFFFFF); + * outHi = (uint32x2_t)(in >> 32); + * in = UNDEFINED; + * } + */ +# if !defined(XXH_NO_VZIP_HACK) /* define to disable */ \ + && defined(__GNUC__) \ + && !defined(__aarch64__) && !defined(__arm64__) +# define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \ + do { \ + /* Undocumented GCC/Clang operand modifier: %e0 = lower D half, %f0 = upper D half */ \ + /* https://github.com/gcc-mirror/gcc/blob/38cf91e5/gcc/config/arm/arm.c#L22486 */ \ + /* https://github.com/llvm-mirror/llvm/blob/2c4ca683/lib/Target/ARM/ARMAsmPrinter.cpp#L399 */ \ + __asm__("vzip.32 %e0, %f0" : "+w" (in)); \ + (outLo) = vget_low_u32 (vreinterpretq_u32_u64(in)); \ + (outHi) = vget_high_u32(vreinterpretq_u32_u64(in)); \ + } while (0) +# else +# define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \ + do { \ + (outLo) = vmovn_u64 (in); \ + (outHi) = vshrn_n_u64 ((in), 32); \ + } while (0) +# endif +#endif /* XXH_VECTOR == XXH_NEON */ + +/* + * VSX and Z Vector helpers. + * + * This is very messy, and any pull requests to clean this up are welcome. + * + * There are a lot of problems with supporting VSX and s390x, due to + * inconsistent intrinsics, spotty coverage, and multiple endiannesses. + */ +#if XXH_VECTOR == XXH_VSX +# if defined(__s390x__) +# include <s390intrin.h> +# else +/* gcc's altivec.h can have the unwanted consequence to unconditionally + * #define bool, vector, and pixel keywords, + * with bad consequences for programs already using these keywords for other purposes. + * The paragraph defining these macros is skipped when __APPLE_ALTIVEC__ is defined. + * __APPLE_ALTIVEC__ is _generally_ defined automatically by the compiler, + * but it seems that, in some cases, it isn't. + * Force the build macro to be defined, so that keywords are not altered. + */ +# if defined(__GNUC__) && !defined(__APPLE_ALTIVEC__) +# define __APPLE_ALTIVEC__ +# endif +# include <altivec.h> +# endif + +typedef __vector unsigned long long xxh_u64x2; +typedef __vector unsigned char xxh_u8x16; +typedef __vector unsigned xxh_u32x4; + +# ifndef XXH_VSX_BE +# if defined(__BIG_ENDIAN__) \ + || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +# define XXH_VSX_BE 1 +# elif defined(__VEC_ELEMENT_REG_ORDER__) && __VEC_ELEMENT_REG_ORDER__ == __ORDER_BIG_ENDIAN__ +# warning "-maltivec=be is not recommended. Please use native endianness." +# define XXH_VSX_BE 1 +# else +# define XXH_VSX_BE 0 +# endif +# endif /* !defined(XXH_VSX_BE) */ + +# if XXH_VSX_BE +/* A wrapper for POWER9's vec_revb. */ +# if defined(__POWER9_VECTOR__) || (defined(__clang__) && defined(__s390x__)) +# define XXH_vec_revb vec_revb +# else +XXH_FORCE_INLINE xxh_u64x2 XXH_vec_revb(xxh_u64x2 val) +{ + xxh_u8x16 const vByteSwap = { 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, + 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08 }; + return vec_perm(val, val, vByteSwap); +} +# endif +# endif /* XXH_VSX_BE */ + +/* + * Performs an unaligned load and byte swaps it on big endian. + */ +XXH_FORCE_INLINE xxh_u64x2 XXH_vec_loadu(const void *ptr) +{ + xxh_u64x2 ret; + memcpy(&ret, ptr, sizeof(xxh_u64x2)); +# if XXH_VSX_BE + ret = XXH_vec_revb(ret); +# endif + return ret; +} + +/* + * vec_mulo and vec_mule are very problematic intrinsics on PowerPC + * + * These intrinsics weren't added until GCC 8, despite existing for a while, + * and they are endian dependent. Also, their meaning swap depending on version. + * */ +# if defined(__s390x__) + /* s390x is always big endian, no issue on this platform */ +# define XXH_vec_mulo vec_mulo +# define XXH_vec_mule vec_mule +# elif defined(__clang__) && XXH_HAS_BUILTIN(__builtin_altivec_vmuleuw) +/* Clang has a better way to control this, we can just use the builtin which doesn't swap. */ +# define XXH_vec_mulo __builtin_altivec_vmulouw +# define XXH_vec_mule __builtin_altivec_vmuleuw +# else +/* gcc needs inline assembly */ +/* Adapted from https://github.com/google/highwayhash/blob/master/highwayhash/hh_vsx.h. */ +XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mulo(xxh_u32x4 a, xxh_u32x4 b) +{ + xxh_u64x2 result; + __asm__("vmulouw %0, %1, %2" : "=v" (result) : "v" (a), "v" (b)); + return result; +} +XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mule(xxh_u32x4 a, xxh_u32x4 b) +{ + xxh_u64x2 result; + __asm__("vmuleuw %0, %1, %2" : "=v" (result) : "v" (a), "v" (b)); + return result; +} +# endif /* XXH_vec_mulo, XXH_vec_mule */ +#endif /* XXH_VECTOR == XXH_VSX */ + + +/* prefetch + * can be disabled, by declaring XXH_NO_PREFETCH build macro */ +#if defined(XXH_NO_PREFETCH) +# define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */ +#else +# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) /* _mm_prefetch() is not defined outside of x86/x64 */ +# include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ +# define XXH_PREFETCH(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0) +# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) ) +# define XXH_PREFETCH(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */) +# else +# define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */ +# endif +#endif /* XXH_NO_PREFETCH */ + + +/* ========================================== + * XXH3 default settings + * ========================================== */ + +#define XXH_SECRET_DEFAULT_SIZE 192 /* minimum XXH3_SECRET_SIZE_MIN */ + +#if (XXH_SECRET_DEFAULT_SIZE < XXH3_SECRET_SIZE_MIN) +# error "default keyset is not large enough" +#endif + +/* Pseudorandom secret taken directly from FARSH */ +XXH_ALIGN(64) static const xxh_u8 XXH3_kSecret[XXH_SECRET_DEFAULT_SIZE] = { + 0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c, + 0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f, + 0xcb, 0x79, 0xe6, 0x4e, 0xcc, 0xc0, 0xe5, 0x78, 0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21, + 0xb8, 0x08, 0x46, 0x74, 0xf7, 0x43, 0x24, 0x8e, 0xe0, 0x35, 0x90, 0xe6, 0x81, 0x3a, 0x26, 0x4c, + 0x3c, 0x28, 0x52, 0xbb, 0x91, 0xc3, 0x00, 0xcb, 0x88, 0xd0, 0x65, 0x8b, 0x1b, 0x53, 0x2e, 0xa3, + 0x71, 0x64, 0x48, 0x97, 0xa2, 0x0d, 0xf9, 0x4e, 0x38, 0x19, 0xef, 0x46, 0xa9, 0xde, 0xac, 0xd8, + 0xa8, 0xfa, 0x76, 0x3f, 0xe3, 0x9c, 0x34, 0x3f, 0xf9, 0xdc, 0xbb, 0xc7, 0xc7, 0x0b, 0x4f, 0x1d, + 0x8a, 0x51, 0xe0, 0x4b, 0xcd, 0xb4, 0x59, 0x31, 0xc8, 0x9f, 0x7e, 0xc9, 0xd9, 0x78, 0x73, 0x64, + 0xea, 0xc5, 0xac, 0x83, 0x34, 0xd3, 0xeb, 0xc3, 0xc5, 0x81, 0xa0, 0xff, 0xfa, 0x13, 0x63, 0xeb, + 0x17, 0x0d, 0xdd, 0x51, 0xb7, 0xf0, 0xda, 0x49, 0xd3, 0x16, 0x55, 0x26, 0x29, 0xd4, 0x68, 0x9e, + 0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc, 0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce, + 0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e, +}; + + +#ifdef XXH_OLD_NAMES +# define kSecret XXH3_kSecret +#endif + +/* + * Calculates a 32-bit to 64-bit long multiply. + * + * Wraps __emulu on MSVC x86 because it tends to call __allmul when it doesn't + * need to (but it shouldn't need to anyways, it is about 7 instructions to do + * a 64x64 multiply...). Since we know that this will _always_ emit MULL, we + * use that instead of the normal method. + * + * If you are compiling for platforms like Thumb-1 and don't have a better option, + * you may also want to write your own long multiply routine here. + * + * XXH_FORCE_INLINE xxh_u64 XXH_mult32to64(xxh_u64 x, xxh_u64 y) + * { + * return (x & 0xFFFFFFFF) * (y & 0xFFFFFFFF); + * } + */ +#if defined(_MSC_VER) && defined(_M_IX86) +# include <intrin.h> +# define XXH_mult32to64(x, y) __emulu((unsigned)(x), (unsigned)(y)) +#else +/* + * Downcast + upcast is usually better than masking on older compilers like + * GCC 4.2 (especially 32-bit ones), all without affecting newer compilers. + * + * The other method, (x & 0xFFFFFFFF) * (y & 0xFFFFFFFF), will AND both operands + * and perform a full 64x64 multiply -- entirely redundant on 32-bit. + */ +# define XXH_mult32to64(x, y) ((xxh_u64)(xxh_u32)(x) * (xxh_u64)(xxh_u32)(y)) +#endif + +/* + * Calculates a 64->128-bit long multiply. + * + * Uses __uint128_t and _umul128 if available, otherwise uses a scalar version. + */ +static XXH128_hash_t +XXH_mult64to128(xxh_u64 lhs, xxh_u64 rhs) +{ + /* + * GCC/Clang __uint128_t method. + * + * On most 64-bit targets, GCC and Clang define a __uint128_t type. + * This is usually the best way as it usually uses a native long 64-bit + * multiply, such as MULQ on x86_64 or MUL + UMULH on aarch64. + * + * Usually. + * + * Despite being a 32-bit platform, Clang (and emscripten) define this type + * despite not having the arithmetic for it. This results in a laggy + * compiler builtin call which calculates a full 128-bit multiply. + * In that case it is best to use the portable one. + * https://github.com/Cyan4973/xxHash/issues/211#issuecomment-515575677 + */ +#if defined(__GNUC__) && !defined(__wasm__) \ + && defined(__SIZEOF_INT128__) \ + || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 128) + + __uint128_t const product = (__uint128_t)lhs * (__uint128_t)rhs; + XXH128_hash_t r128; + r128.low64 = (xxh_u64)(product); + r128.high64 = (xxh_u64)(product >> 64); + return r128; + + /* + * MSVC for x64's _umul128 method. + * + * xxh_u64 _umul128(xxh_u64 Multiplier, xxh_u64 Multiplicand, xxh_u64 *HighProduct); + * + * This compiles to single operand MUL on x64. + */ +#elif defined(_M_X64) || defined(_M_IA64) + +#ifndef _MSC_VER +# pragma intrinsic(_umul128) +#endif + xxh_u64 product_high; + xxh_u64 const product_low = _umul128(lhs, rhs, &product_high); + XXH128_hash_t r128; + r128.low64 = product_low; + r128.high64 = product_high; + return r128; + +#else + /* + * Portable scalar method. Optimized for 32-bit and 64-bit ALUs. + * + * This is a fast and simple grade school multiply, which is shown below + * with base 10 arithmetic instead of base 0x100000000. + * + * 9 3 // D2 lhs = 93 + * x 7 5 // D2 rhs = 75 + * ---------- + * 1 5 // D2 lo_lo = (93 % 10) * (75 % 10) = 15 + * 4 5 | // D2 hi_lo = (93 / 10) * (75 % 10) = 45 + * 2 1 | // D2 lo_hi = (93 % 10) * (75 / 10) = 21 + * + 6 3 | | // D2 hi_hi = (93 / 10) * (75 / 10) = 63 + * --------- + * 2 7 | // D2 cross = (15 / 10) + (45 % 10) + 21 = 27 + * + 6 7 | | // D2 upper = (27 / 10) + (45 / 10) + 63 = 67 + * --------- + * 6 9 7 5 // D4 res = (27 * 10) + (15 % 10) + (67 * 100) = 6975 + * + * The reasons for adding the products like this are: + * 1. It avoids manual carry tracking. Just like how + * (9 * 9) + 9 + 9 = 99, the same applies with this for UINT64_MAX. + * This avoids a lot of complexity. + * + * 2. It hints for, and on Clang, compiles to, the powerful UMAAL + * instruction available in ARM's Digital Signal Processing extension + * in 32-bit ARMv6 and later, which is shown below: + * + * void UMAAL(xxh_u32 *RdLo, xxh_u32 *RdHi, xxh_u32 Rn, xxh_u32 Rm) + * { + * xxh_u64 product = (xxh_u64)*RdLo * (xxh_u64)*RdHi + Rn + Rm; + * *RdLo = (xxh_u32)(product & 0xFFFFFFFF); + * *RdHi = (xxh_u32)(product >> 32); + * } + * + * This instruction was designed for efficient long multiplication, and + * allows this to be calculated in only 4 instructions at speeds + * comparable to some 64-bit ALUs. + * + * 3. It isn't terrible on other platforms. Usually this will be a couple + * of 32-bit ADD/ADCs. + */ + + /* First calculate all of the cross products. */ + xxh_u64 const lo_lo = XXH_mult32to64(lhs & 0xFFFFFFFF, rhs & 0xFFFFFFFF); + xxh_u64 const hi_lo = XXH_mult32to64(lhs >> 32, rhs & 0xFFFFFFFF); + xxh_u64 const lo_hi = XXH_mult32to64(lhs & 0xFFFFFFFF, rhs >> 32); + xxh_u64 const hi_hi = XXH_mult32to64(lhs >> 32, rhs >> 32); + + /* Now add the products together. These will never overflow. */ + xxh_u64 const cross = (lo_lo >> 32) + (hi_lo & 0xFFFFFFFF) + lo_hi; + xxh_u64 const upper = (hi_lo >> 32) + (cross >> 32) + hi_hi; + xxh_u64 const lower = (cross << 32) | (lo_lo & 0xFFFFFFFF); + + XXH128_hash_t r128; + r128.low64 = lower; + r128.high64 = upper; + return r128; +#endif +} + +/* + * Does a 64-bit to 128-bit multiply, then XOR folds it. + * + * The reason for the separate function is to prevent passing too many structs + * around by value. This will hopefully inline the multiply, but we don't force it. + */ +static xxh_u64 +XXH3_mul128_fold64(xxh_u64 lhs, xxh_u64 rhs) +{ + XXH128_hash_t product = XXH_mult64to128(lhs, rhs); + return product.low64 ^ product.high64; +} + +/* Seems to produce slightly better code on GCC for some reason. */ +XXH_FORCE_INLINE xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift) +{ + XXH_ASSERT(0 <= shift && shift < 64); + return v64 ^ (v64 >> shift); +} + +/* + * This is a fast avalanche stage, + * suitable when input bits are already partially mixed + */ +static XXH64_hash_t XXH3_avalanche(xxh_u64 h64) +{ + h64 = XXH_xorshift64(h64, 37); + h64 *= 0x165667919E3779F9ULL; + h64 = XXH_xorshift64(h64, 32); + return h64; +} + +/* + * This is a stronger avalanche, + * inspired by Pelle Evensen's rrmxmx + * preferable when input has not been previously mixed + */ +static XXH64_hash_t XXH3_rrmxmx(xxh_u64 h64, xxh_u64 len) +{ + /* this mix is inspired by Pelle Evensen's rrmxmx */ + h64 ^= XXH_rotl64(h64, 49) ^ XXH_rotl64(h64, 24); + h64 *= 0x9FB21C651E98DF25ULL; + h64 ^= (h64 >> 35) + len ; + h64 *= 0x9FB21C651E98DF25ULL; + return XXH_xorshift64(h64, 28); +} + + +/* ========================================== + * Short keys + * ========================================== + * One of the shortcomings of XXH32 and XXH64 was that their performance was + * sub-optimal on short lengths. It used an iterative algorithm which strongly + * favored lengths that were a multiple of 4 or 8. + * + * Instead of iterating over individual inputs, we use a set of single shot + * functions which piece together a range of lengths and operate in constant time. + * + * Additionally, the number of multiplies has been significantly reduced. This + * reduces latency, especially when emulating 64-bit multiplies on 32-bit. + * + * Depending on the platform, this may or may not be faster than XXH32, but it + * is almost guaranteed to be faster than XXH64. + */ + +/* + * At very short lengths, there isn't enough input to fully hide secrets, or use + * the entire secret. + * + * There is also only a limited amount of mixing we can do before significantly + * impacting performance. + * + * Therefore, we use different sections of the secret and always mix two secret + * samples with an XOR. This should have no effect on performance on the + * seedless or withSeed variants because everything _should_ be constant folded + * by modern compilers. + * + * The XOR mixing hides individual parts of the secret and increases entropy. + * + * This adds an extra layer of strength for custom secrets. + */ +XXH_FORCE_INLINE XXH64_hash_t +XXH3_len_1to3_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(input != NULL); + XXH_ASSERT(1 <= len && len <= 3); + XXH_ASSERT(secret != NULL); + /* + * len = 1: combined = { input[0], 0x01, input[0], input[0] } + * len = 2: combined = { input[1], 0x02, input[0], input[1] } + * len = 3: combined = { input[2], 0x03, input[0], input[1] } + */ + { xxh_u8 const c1 = input[0]; + xxh_u8 const c2 = input[len >> 1]; + xxh_u8 const c3 = input[len - 1]; + xxh_u32 const combined = ((xxh_u32)c1 << 16) | ((xxh_u32)c2 << 24) + | ((xxh_u32)c3 << 0) | ((xxh_u32)len << 8); + xxh_u64 const bitflip = (XXH_readLE32(secret) ^ XXH_readLE32(secret+4)) + seed; + xxh_u64 const keyed = (xxh_u64)combined ^ bitflip; + return XXH64_avalanche(keyed); + } +} + +XXH_FORCE_INLINE XXH64_hash_t +XXH3_len_4to8_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(input != NULL); + XXH_ASSERT(secret != NULL); + XXH_ASSERT(4 <= len && len < 8); + seed ^= (xxh_u64)XXH_swap32((xxh_u32)seed) << 32; + { xxh_u32 const input1 = XXH_readLE32(input); + xxh_u32 const input2 = XXH_readLE32(input + len - 4); + xxh_u64 const bitflip = (XXH_readLE64(secret+8) ^ XXH_readLE64(secret+16)) - seed; + xxh_u64 const input64 = input2 + (((xxh_u64)input1) << 32); + xxh_u64 const keyed = input64 ^ bitflip; + return XXH3_rrmxmx(keyed, len); + } +} + +XXH_FORCE_INLINE XXH64_hash_t +XXH3_len_9to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(input != NULL); + XXH_ASSERT(secret != NULL); + XXH_ASSERT(8 <= len && len <= 16); + { xxh_u64 const bitflip1 = (XXH_readLE64(secret+24) ^ XXH_readLE64(secret+32)) + seed; + xxh_u64 const bitflip2 = (XXH_readLE64(secret+40) ^ XXH_readLE64(secret+48)) - seed; + xxh_u64 const input_lo = XXH_readLE64(input) ^ bitflip1; + xxh_u64 const input_hi = XXH_readLE64(input + len - 8) ^ bitflip2; + xxh_u64 const acc = len + + XXH_swap64(input_lo) + input_hi + + XXH3_mul128_fold64(input_lo, input_hi); + return XXH3_avalanche(acc); + } +} + +XXH_FORCE_INLINE XXH64_hash_t +XXH3_len_0to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(len <= 16); + { if (XXH_likely(len > 8)) return XXH3_len_9to16_64b(input, len, secret, seed); + if (XXH_likely(len >= 4)) return XXH3_len_4to8_64b(input, len, secret, seed); + if (len) return XXH3_len_1to3_64b(input, len, secret, seed); + return XXH64_avalanche(seed ^ (XXH_readLE64(secret+56) ^ XXH_readLE64(secret+64))); + } +} + +/* + * DISCLAIMER: There are known *seed-dependent* multicollisions here due to + * multiplication by zero, affecting hashes of lengths 17 to 240. + * + * However, they are very unlikely. + * + * Keep this in mind when using the unseeded XXH3_64bits() variant: As with all + * unseeded non-cryptographic hashes, it does not attempt to defend itself + * against specially crafted inputs, only random inputs. + * + * Compared to classic UMAC where a 1 in 2^31 chance of 4 consecutive bytes + * cancelling out the secret is taken an arbitrary number of times (addressed + * in XXH3_accumulate_512), this collision is very unlikely with random inputs + * and/or proper seeding: + * + * This only has a 1 in 2^63 chance of 8 consecutive bytes cancelling out, in a + * function that is only called up to 16 times per hash with up to 240 bytes of + * input. + * + * This is not too bad for a non-cryptographic hash function, especially with + * only 64 bit outputs. + * + * The 128-bit variant (which trades some speed for strength) is NOT affected + * by this, although it is always a good idea to use a proper seed if you care + * about strength. + */ +XXH_FORCE_INLINE xxh_u64 XXH3_mix16B(const xxh_u8* XXH_RESTRICT input, + const xxh_u8* XXH_RESTRICT secret, xxh_u64 seed64) +{ +#if defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \ + && defined(__i386__) && defined(__SSE2__) /* x86 + SSE2 */ \ + && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable like XXH32 hack */ + /* + * UGLY HACK: + * GCC for x86 tends to autovectorize the 128-bit multiply, resulting in + * slower code. + * + * By forcing seed64 into a register, we disrupt the cost model and + * cause it to scalarize. See `XXH32_round()` + * + * FIXME: Clang's output is still _much_ faster -- On an AMD Ryzen 3600, + * XXH3_64bits @ len=240 runs at 4.6 GB/s with Clang 9, but 3.3 GB/s on + * GCC 9.2, despite both emitting scalar code. + * + * GCC generates much better scalar code than Clang for the rest of XXH3, + * which is why finding a more optimal codepath is an interest. + */ + __asm__ ("" : "+r" (seed64)); +#endif + { xxh_u64 const input_lo = XXH_readLE64(input); + xxh_u64 const input_hi = XXH_readLE64(input+8); + return XXH3_mul128_fold64( + input_lo ^ (XXH_readLE64(secret) + seed64), + input_hi ^ (XXH_readLE64(secret+8) - seed64) + ); + } +} + +/* For mid range keys, XXH3 uses a Mum-hash variant. */ +XXH_FORCE_INLINE XXH64_hash_t +XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH64_hash_t seed) +{ + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize; + XXH_ASSERT(16 < len && len <= 128); + + { xxh_u64 acc = len * XXH_PRIME64_1; + if (len > 32) { + if (len > 64) { + if (len > 96) { + acc += XXH3_mix16B(input+48, secret+96, seed); + acc += XXH3_mix16B(input+len-64, secret+112, seed); + } + acc += XXH3_mix16B(input+32, secret+64, seed); + acc += XXH3_mix16B(input+len-48, secret+80, seed); + } + acc += XXH3_mix16B(input+16, secret+32, seed); + acc += XXH3_mix16B(input+len-32, secret+48, seed); + } + acc += XXH3_mix16B(input+0, secret+0, seed); + acc += XXH3_mix16B(input+len-16, secret+16, seed); + + return XXH3_avalanche(acc); + } +} + +#define XXH3_MIDSIZE_MAX 240 + +XXH_NO_INLINE XXH64_hash_t +XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH64_hash_t seed) +{ + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize; + XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX); + + #define XXH3_MIDSIZE_STARTOFFSET 3 + #define XXH3_MIDSIZE_LASTOFFSET 17 + + { xxh_u64 acc = len * XXH_PRIME64_1; + int const nbRounds = (int)len / 16; + int i; + for (i=0; i<8; i++) { + acc += XXH3_mix16B(input+(16*i), secret+(16*i), seed); + } + acc = XXH3_avalanche(acc); + XXH_ASSERT(nbRounds >= 8); +#if defined(__clang__) /* Clang */ \ + && (defined(__ARM_NEON) || defined(__ARM_NEON__)) /* NEON */ \ + && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable */ + /* + * UGLY HACK: + * Clang for ARMv7-A tries to vectorize this loop, similar to GCC x86. + * In everywhere else, it uses scalar code. + * + * For 64->128-bit multiplies, even if the NEON was 100% optimal, it + * would still be slower than UMAAL (see XXH_mult64to128). + * + * Unfortunately, Clang doesn't handle the long multiplies properly and + * converts them to the nonexistent "vmulq_u64" intrinsic, which is then + * scalarized into an ugly mess of VMOV.32 instructions. + * + * This mess is difficult to avoid without turning autovectorization + * off completely, but they are usually relatively minor and/or not + * worth it to fix. + * + * This loop is the easiest to fix, as unlike XXH32, this pragma + * _actually works_ because it is a loop vectorization instead of an + * SLP vectorization. + */ + #pragma clang loop vectorize(disable) +#endif + for (i=8 ; i < nbRounds; i++) { + acc += XXH3_mix16B(input+(16*i), secret+(16*(i-8)) + XXH3_MIDSIZE_STARTOFFSET, seed); + } + /* last bytes */ + acc += XXH3_mix16B(input + len - 16, secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET, seed); + return XXH3_avalanche(acc); + } +} + + +/* ======= Long Keys ======= */ + +#define XXH_STRIPE_LEN 64 +#define XXH_SECRET_CONSUME_RATE 8 /* nb of secret bytes consumed at each accumulation */ +#define XXH_ACC_NB (XXH_STRIPE_LEN / sizeof(xxh_u64)) + +#ifdef XXH_OLD_NAMES +# define STRIPE_LEN XXH_STRIPE_LEN +# define ACC_NB XXH_ACC_NB +#endif + +XXH_FORCE_INLINE void XXH_writeLE64(void* dst, xxh_u64 v64) +{ + if (!XXH_CPU_LITTLE_ENDIAN) v64 = XXH_swap64(v64); + memcpy(dst, &v64, sizeof(v64)); +} + +/* Several intrinsic functions below are supposed to accept __int64 as argument, + * as documented in https://software.intel.com/sites/landingpage/IntrinsicsGuide/ . + * However, several environments do not define __int64 type, + * requiring a workaround. + */ +#if !defined (__VMS) \ + && (defined (__cplusplus) \ + || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) + typedef int64_t xxh_i64; +#else + /* the following type must have a width of 64-bit */ + typedef long long xxh_i64; +#endif + +/* + * XXH3_accumulate_512 is the tightest loop for long inputs, and it is the most optimized. + * + * It is a hardened version of UMAC, based off of FARSH's implementation. + * + * This was chosen because it adapts quite well to 32-bit, 64-bit, and SIMD + * implementations, and it is ridiculously fast. + * + * We harden it by mixing the original input to the accumulators as well as the product. + * + * This means that in the (relatively likely) case of a multiply by zero, the + * original input is preserved. + * + * On 128-bit inputs, we swap 64-bit pairs when we add the input to improve + * cross-pollination, as otherwise the upper and lower halves would be + * essentially independent. + * + * This doesn't matter on 64-bit hashes since they all get merged together in + * the end, so we skip the extra step. + * + * Both XXH3_64bits and XXH3_128bits use this subroutine. + */ + +#if (XXH_VECTOR == XXH_AVX512) || defined(XXH_X86DISPATCH) + +#ifndef XXH_TARGET_AVX512 +# define XXH_TARGET_AVX512 /* disable attribute target */ +#endif + +XXH_FORCE_INLINE XXH_TARGET_AVX512 void +XXH3_accumulate_512_avx512(void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + XXH_ALIGN(64) __m512i* const xacc = (__m512i *) acc; + XXH_ASSERT((((size_t)acc) & 63) == 0); + XXH_STATIC_ASSERT(XXH_STRIPE_LEN == sizeof(__m512i)); + + { + /* data_vec = input[0]; */ + __m512i const data_vec = _mm512_loadu_si512 (input); + /* key_vec = secret[0]; */ + __m512i const key_vec = _mm512_loadu_si512 (secret); + /* data_key = data_vec ^ key_vec; */ + __m512i const data_key = _mm512_xor_si512 (data_vec, key_vec); + /* data_key_lo = data_key >> 32; */ + __m512i const data_key_lo = _mm512_shuffle_epi32 (data_key, (_MM_PERM_ENUM)_MM_SHUFFLE(0, 3, 0, 1)); + /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ + __m512i const product = _mm512_mul_epu32 (data_key, data_key_lo); + /* xacc[0] += swap(data_vec); */ + __m512i const data_swap = _mm512_shuffle_epi32(data_vec, (_MM_PERM_ENUM)_MM_SHUFFLE(1, 0, 3, 2)); + __m512i const sum = _mm512_add_epi64(*xacc, data_swap); + /* xacc[0] += product; */ + *xacc = _mm512_add_epi64(product, sum); + } +} + +/* + * XXH3_scrambleAcc: Scrambles the accumulators to improve mixing. + * + * Multiplication isn't perfect, as explained by Google in HighwayHash: + * + * // Multiplication mixes/scrambles bytes 0-7 of the 64-bit result to + * // varying degrees. In descending order of goodness, bytes + * // 3 4 2 5 1 6 0 7 have quality 228 224 164 160 100 96 36 32. + * // As expected, the upper and lower bytes are much worse. + * + * Source: https://github.com/google/highwayhash/blob/0aaf66b/highwayhash/hh_avx2.h#L291 + * + * Since our algorithm uses a pseudorandom secret to add some variance into the + * mix, we don't need to (or want to) mix as often or as much as HighwayHash does. + * + * This isn't as tight as XXH3_accumulate, but still written in SIMD to avoid + * extraction. + * + * Both XXH3_64bits and XXH3_128bits use this subroutine. + */ + +XXH_FORCE_INLINE XXH_TARGET_AVX512 void +XXH3_scrambleAcc_avx512(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 63) == 0); + XXH_STATIC_ASSERT(XXH_STRIPE_LEN == sizeof(__m512i)); + { XXH_ALIGN(64) __m512i* const xacc = (__m512i*) acc; + const __m512i prime32 = _mm512_set1_epi32((int)XXH_PRIME32_1); + + /* xacc[0] ^= (xacc[0] >> 47) */ + __m512i const acc_vec = *xacc; + __m512i const shifted = _mm512_srli_epi64 (acc_vec, 47); + __m512i const data_vec = _mm512_xor_si512 (acc_vec, shifted); + /* xacc[0] ^= secret; */ + __m512i const key_vec = _mm512_loadu_si512 (secret); + __m512i const data_key = _mm512_xor_si512 (data_vec, key_vec); + + /* xacc[0] *= XXH_PRIME32_1; */ + __m512i const data_key_hi = _mm512_shuffle_epi32 (data_key, (_MM_PERM_ENUM)_MM_SHUFFLE(0, 3, 0, 1)); + __m512i const prod_lo = _mm512_mul_epu32 (data_key, prime32); + __m512i const prod_hi = _mm512_mul_epu32 (data_key_hi, prime32); + *xacc = _mm512_add_epi64(prod_lo, _mm512_slli_epi64(prod_hi, 32)); + } +} + +XXH_FORCE_INLINE XXH_TARGET_AVX512 void +XXH3_initCustomSecret_avx512(void* XXH_RESTRICT customSecret, xxh_u64 seed64) +{ + XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 63) == 0); + XXH_STATIC_ASSERT(XXH_SEC_ALIGN == 64); + XXH_ASSERT(((size_t)customSecret & 63) == 0); + (void)(&XXH_writeLE64); + { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / sizeof(__m512i); + __m512i const seed = _mm512_mask_set1_epi64(_mm512_set1_epi64((xxh_i64)seed64), 0xAA, -(xxh_i64)seed64); + + XXH_ALIGN(64) const __m512i* const src = (const __m512i*) XXH3_kSecret; + XXH_ALIGN(64) __m512i* const dest = ( __m512i*) customSecret; + int i; + for (i=0; i < nbRounds; ++i) { + /* GCC has a bug, _mm512_stream_load_si512 accepts 'void*', not 'void const*', + * this will warn "discards ‘const’ qualifier". */ + union { + XXH_ALIGN(64) const __m512i* cp; + XXH_ALIGN(64) void* p; + } remote_const_void; + remote_const_void.cp = src + i; + dest[i] = _mm512_add_epi64(_mm512_stream_load_si512(remote_const_void.p), seed); + } } +} + +#endif + +#if (XXH_VECTOR == XXH_AVX2) || defined(XXH_X86DISPATCH) + +#ifndef XXH_TARGET_AVX2 +# define XXH_TARGET_AVX2 /* disable attribute target */ +#endif + +XXH_FORCE_INLINE XXH_TARGET_AVX2 void +XXH3_accumulate_512_avx2( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 31) == 0); + { XXH_ALIGN(32) __m256i* const xacc = (__m256i *) acc; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */ + const __m256i* const xinput = (const __m256i *) input; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */ + const __m256i* const xsecret = (const __m256i *) secret; + + size_t i; + for (i=0; i < XXH_STRIPE_LEN/sizeof(__m256i); i++) { + /* data_vec = xinput[i]; */ + __m256i const data_vec = _mm256_loadu_si256 (xinput+i); + /* key_vec = xsecret[i]; */ + __m256i const key_vec = _mm256_loadu_si256 (xsecret+i); + /* data_key = data_vec ^ key_vec; */ + __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec); + /* data_key_lo = data_key >> 32; */ + __m256i const data_key_lo = _mm256_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); + /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ + __m256i const product = _mm256_mul_epu32 (data_key, data_key_lo); + /* xacc[i] += swap(data_vec); */ + __m256i const data_swap = _mm256_shuffle_epi32(data_vec, _MM_SHUFFLE(1, 0, 3, 2)); + __m256i const sum = _mm256_add_epi64(xacc[i], data_swap); + /* xacc[i] += product; */ + xacc[i] = _mm256_add_epi64(product, sum); + } } +} + +XXH_FORCE_INLINE XXH_TARGET_AVX2 void +XXH3_scrambleAcc_avx2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 31) == 0); + { XXH_ALIGN(32) __m256i* const xacc = (__m256i*) acc; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */ + const __m256i* const xsecret = (const __m256i *) secret; + const __m256i prime32 = _mm256_set1_epi32((int)XXH_PRIME32_1); + + size_t i; + for (i=0; i < XXH_STRIPE_LEN/sizeof(__m256i); i++) { + /* xacc[i] ^= (xacc[i] >> 47) */ + __m256i const acc_vec = xacc[i]; + __m256i const shifted = _mm256_srli_epi64 (acc_vec, 47); + __m256i const data_vec = _mm256_xor_si256 (acc_vec, shifted); + /* xacc[i] ^= xsecret; */ + __m256i const key_vec = _mm256_loadu_si256 (xsecret+i); + __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec); + + /* xacc[i] *= XXH_PRIME32_1; */ + __m256i const data_key_hi = _mm256_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); + __m256i const prod_lo = _mm256_mul_epu32 (data_key, prime32); + __m256i const prod_hi = _mm256_mul_epu32 (data_key_hi, prime32); + xacc[i] = _mm256_add_epi64(prod_lo, _mm256_slli_epi64(prod_hi, 32)); + } + } +} + +XXH_FORCE_INLINE XXH_TARGET_AVX2 void XXH3_initCustomSecret_avx2(void* XXH_RESTRICT customSecret, xxh_u64 seed64) +{ + XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 31) == 0); + XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE / sizeof(__m256i)) == 6); + XXH_STATIC_ASSERT(XXH_SEC_ALIGN <= 64); + (void)(&XXH_writeLE64); + XXH_PREFETCH(customSecret); + { __m256i const seed = _mm256_set_epi64x(-(xxh_i64)seed64, (xxh_i64)seed64, -(xxh_i64)seed64, (xxh_i64)seed64); + + XXH_ALIGN(64) const __m256i* const src = (const __m256i*) XXH3_kSecret; + XXH_ALIGN(64) __m256i* dest = ( __m256i*) customSecret; + +# if defined(__GNUC__) || defined(__clang__) + /* + * On GCC & Clang, marking 'dest' as modified will cause the compiler: + * - do not extract the secret from sse registers in the internal loop + * - use less common registers, and avoid pushing these reg into stack + * The asm hack causes Clang to assume that XXH3_kSecretPtr aliases with + * customSecret, and on aarch64, this prevented LDP from merging two + * loads together for free. Putting the loads together before the stores + * properly generates LDP. + */ + __asm__("" : "+r" (dest)); +# endif + + /* GCC -O2 need unroll loop manually */ + dest[0] = _mm256_add_epi64(_mm256_stream_load_si256(src+0), seed); + dest[1] = _mm256_add_epi64(_mm256_stream_load_si256(src+1), seed); + dest[2] = _mm256_add_epi64(_mm256_stream_load_si256(src+2), seed); + dest[3] = _mm256_add_epi64(_mm256_stream_load_si256(src+3), seed); + dest[4] = _mm256_add_epi64(_mm256_stream_load_si256(src+4), seed); + dest[5] = _mm256_add_epi64(_mm256_stream_load_si256(src+5), seed); + } +} + +#endif + +#if (XXH_VECTOR == XXH_SSE2) || defined(XXH_X86DISPATCH) + +#ifndef XXH_TARGET_SSE2 +# define XXH_TARGET_SSE2 /* disable attribute target */ +#endif + +XXH_FORCE_INLINE XXH_TARGET_SSE2 void +XXH3_accumulate_512_sse2( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + /* SSE2 is just a half-scale version of the AVX2 version. */ + XXH_ASSERT((((size_t)acc) & 15) == 0); + { XXH_ALIGN(16) __m128i* const xacc = (__m128i *) acc; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */ + const __m128i* const xinput = (const __m128i *) input; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */ + const __m128i* const xsecret = (const __m128i *) secret; + + size_t i; + for (i=0; i < XXH_STRIPE_LEN/sizeof(__m128i); i++) { + /* data_vec = xinput[i]; */ + __m128i const data_vec = _mm_loadu_si128 (xinput+i); + /* key_vec = xsecret[i]; */ + __m128i const key_vec = _mm_loadu_si128 (xsecret+i); + /* data_key = data_vec ^ key_vec; */ + __m128i const data_key = _mm_xor_si128 (data_vec, key_vec); + /* data_key_lo = data_key >> 32; */ + __m128i const data_key_lo = _mm_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); + /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ + __m128i const product = _mm_mul_epu32 (data_key, data_key_lo); + /* xacc[i] += swap(data_vec); */ + __m128i const data_swap = _mm_shuffle_epi32(data_vec, _MM_SHUFFLE(1,0,3,2)); + __m128i const sum = _mm_add_epi64(xacc[i], data_swap); + /* xacc[i] += product; */ + xacc[i] = _mm_add_epi64(product, sum); + } } +} + +XXH_FORCE_INLINE XXH_TARGET_SSE2 void +XXH3_scrambleAcc_sse2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + { XXH_ALIGN(16) __m128i* const xacc = (__m128i*) acc; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */ + const __m128i* const xsecret = (const __m128i *) secret; + const __m128i prime32 = _mm_set1_epi32((int)XXH_PRIME32_1); + + size_t i; + for (i=0; i < XXH_STRIPE_LEN/sizeof(__m128i); i++) { + /* xacc[i] ^= (xacc[i] >> 47) */ + __m128i const acc_vec = xacc[i]; + __m128i const shifted = _mm_srli_epi64 (acc_vec, 47); + __m128i const data_vec = _mm_xor_si128 (acc_vec, shifted); + /* xacc[i] ^= xsecret[i]; */ + __m128i const key_vec = _mm_loadu_si128 (xsecret+i); + __m128i const data_key = _mm_xor_si128 (data_vec, key_vec); + + /* xacc[i] *= XXH_PRIME32_1; */ + __m128i const data_key_hi = _mm_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); + __m128i const prod_lo = _mm_mul_epu32 (data_key, prime32); + __m128i const prod_hi = _mm_mul_epu32 (data_key_hi, prime32); + xacc[i] = _mm_add_epi64(prod_lo, _mm_slli_epi64(prod_hi, 32)); + } + } +} + +XXH_FORCE_INLINE XXH_TARGET_SSE2 void XXH3_initCustomSecret_sse2(void* XXH_RESTRICT customSecret, xxh_u64 seed64) +{ + XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0); + (void)(&XXH_writeLE64); + { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / sizeof(__m128i); + +# if defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER < 1900 + // MSVC 32bit mode does not support _mm_set_epi64x before 2015 + XXH_ALIGN(16) const xxh_i64 seed64x2[2] = { (xxh_i64)seed64, -(xxh_i64)seed64 }; + __m128i const seed = _mm_load_si128((__m128i const*)seed64x2); +# else + __m128i const seed = _mm_set_epi64x(-(xxh_i64)seed64, (xxh_i64)seed64); +# endif + int i; + + XXH_ALIGN(64) const float* const src = (float const*) XXH3_kSecret; + XXH_ALIGN(XXH_SEC_ALIGN) __m128i* dest = (__m128i*) customSecret; +# if defined(__GNUC__) || defined(__clang__) + /* + * On GCC & Clang, marking 'dest' as modified will cause the compiler: + * - do not extract the secret from sse registers in the internal loop + * - use less common registers, and avoid pushing these reg into stack + */ + __asm__("" : "+r" (dest)); +# endif + + for (i=0; i < nbRounds; ++i) { + dest[i] = _mm_add_epi64(_mm_castps_si128(_mm_load_ps(src+i*4)), seed); + } } +} + +#endif + +#if (XXH_VECTOR == XXH_NEON) + +XXH_FORCE_INLINE void +XXH3_accumulate_512_neon( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + { + XXH_ALIGN(16) uint64x2_t* const xacc = (uint64x2_t *) acc; + /* We don't use a uint32x4_t pointer because it causes bus errors on ARMv7. */ + uint8_t const* const xinput = (const uint8_t *) input; + uint8_t const* const xsecret = (const uint8_t *) secret; + + size_t i; + for (i=0; i < XXH_STRIPE_LEN / sizeof(uint64x2_t); i++) { + /* data_vec = xinput[i]; */ + uint8x16_t data_vec = vld1q_u8(xinput + (i * 16)); + /* key_vec = xsecret[i]; */ + uint8x16_t key_vec = vld1q_u8(xsecret + (i * 16)); + uint64x2_t data_key; + uint32x2_t data_key_lo, data_key_hi; + /* xacc[i] += swap(data_vec); */ + uint64x2_t const data64 = vreinterpretq_u64_u8(data_vec); + uint64x2_t const swapped = vextq_u64(data64, data64, 1); + xacc[i] = vaddq_u64 (xacc[i], swapped); + /* data_key = data_vec ^ key_vec; */ + data_key = vreinterpretq_u64_u8(veorq_u8(data_vec, key_vec)); + /* data_key_lo = (uint32x2_t) (data_key & 0xFFFFFFFF); + * data_key_hi = (uint32x2_t) (data_key >> 32); + * data_key = UNDEFINED; */ + XXH_SPLIT_IN_PLACE(data_key, data_key_lo, data_key_hi); + /* xacc[i] += (uint64x2_t) data_key_lo * (uint64x2_t) data_key_hi; */ + xacc[i] = vmlal_u32 (xacc[i], data_key_lo, data_key_hi); + + } + } +} + +XXH_FORCE_INLINE void +XXH3_scrambleAcc_neon(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + + { uint64x2_t* xacc = (uint64x2_t*) acc; + uint8_t const* xsecret = (uint8_t const*) secret; + uint32x2_t prime = vdup_n_u32 (XXH_PRIME32_1); + + size_t i; + for (i=0; i < XXH_STRIPE_LEN/sizeof(uint64x2_t); i++) { + /* xacc[i] ^= (xacc[i] >> 47); */ + uint64x2_t acc_vec = xacc[i]; + uint64x2_t shifted = vshrq_n_u64 (acc_vec, 47); + uint64x2_t data_vec = veorq_u64 (acc_vec, shifted); + + /* xacc[i] ^= xsecret[i]; */ + uint8x16_t key_vec = vld1q_u8(xsecret + (i * 16)); + uint64x2_t data_key = veorq_u64(data_vec, vreinterpretq_u64_u8(key_vec)); + + /* xacc[i] *= XXH_PRIME32_1 */ + uint32x2_t data_key_lo, data_key_hi; + /* data_key_lo = (uint32x2_t) (xacc[i] & 0xFFFFFFFF); + * data_key_hi = (uint32x2_t) (xacc[i] >> 32); + * xacc[i] = UNDEFINED; */ + XXH_SPLIT_IN_PLACE(data_key, data_key_lo, data_key_hi); + { /* + * prod_hi = (data_key >> 32) * XXH_PRIME32_1; + * + * Avoid vmul_u32 + vshll_n_u32 since Clang 6 and 7 will + * incorrectly "optimize" this: + * tmp = vmul_u32(vmovn_u64(a), vmovn_u64(b)); + * shifted = vshll_n_u32(tmp, 32); + * to this: + * tmp = "vmulq_u64"(a, b); // no such thing! + * shifted = vshlq_n_u64(tmp, 32); + * + * However, unlike SSE, Clang lacks a 64-bit multiply routine + * for NEON, and it scalarizes two 64-bit multiplies instead. + * + * vmull_u32 has the same timing as vmul_u32, and it avoids + * this bug completely. + * See https://bugs.llvm.org/show_bug.cgi?id=39967 + */ + uint64x2_t prod_hi = vmull_u32 (data_key_hi, prime); + /* xacc[i] = prod_hi << 32; */ + xacc[i] = vshlq_n_u64(prod_hi, 32); + /* xacc[i] += (prod_hi & 0xFFFFFFFF) * XXH_PRIME32_1; */ + xacc[i] = vmlal_u32(xacc[i], data_key_lo, prime); + } + } } +} + +#endif + +#if (XXH_VECTOR == XXH_VSX) + +XXH_FORCE_INLINE void +XXH3_accumulate_512_vsx( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + xxh_u64x2* const xacc = (xxh_u64x2*) acc; /* presumed aligned */ + xxh_u64x2 const* const xinput = (xxh_u64x2 const*) input; /* no alignment restriction */ + xxh_u64x2 const* const xsecret = (xxh_u64x2 const*) secret; /* no alignment restriction */ + xxh_u64x2 const v32 = { 32, 32 }; + size_t i; + for (i = 0; i < XXH_STRIPE_LEN / sizeof(xxh_u64x2); i++) { + /* data_vec = xinput[i]; */ + xxh_u64x2 const data_vec = XXH_vec_loadu(xinput + i); + /* key_vec = xsecret[i]; */ + xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + i); + xxh_u64x2 const data_key = data_vec ^ key_vec; + /* shuffled = (data_key << 32) | (data_key >> 32); */ + xxh_u32x4 const shuffled = (xxh_u32x4)vec_rl(data_key, v32); + /* product = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)shuffled & 0xFFFFFFFF); */ + xxh_u64x2 const product = XXH_vec_mulo((xxh_u32x4)data_key, shuffled); + xacc[i] += product; + + /* swap high and low halves */ +#ifdef __s390x__ + xacc[i] += vec_permi(data_vec, data_vec, 2); +#else + xacc[i] += vec_xxpermdi(data_vec, data_vec, 2); +#endif + } +} + +XXH_FORCE_INLINE void +XXH3_scrambleAcc_vsx(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + + { xxh_u64x2* const xacc = (xxh_u64x2*) acc; + const xxh_u64x2* const xsecret = (const xxh_u64x2*) secret; + /* constants */ + xxh_u64x2 const v32 = { 32, 32 }; + xxh_u64x2 const v47 = { 47, 47 }; + xxh_u32x4 const prime = { XXH_PRIME32_1, XXH_PRIME32_1, XXH_PRIME32_1, XXH_PRIME32_1 }; + size_t i; + for (i = 0; i < XXH_STRIPE_LEN / sizeof(xxh_u64x2); i++) { + /* xacc[i] ^= (xacc[i] >> 47); */ + xxh_u64x2 const acc_vec = xacc[i]; + xxh_u64x2 const data_vec = acc_vec ^ (acc_vec >> v47); + + /* xacc[i] ^= xsecret[i]; */ + xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + i); + xxh_u64x2 const data_key = data_vec ^ key_vec; + + /* xacc[i] *= XXH_PRIME32_1 */ + /* prod_lo = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)prime & 0xFFFFFFFF); */ + xxh_u64x2 const prod_even = XXH_vec_mule((xxh_u32x4)data_key, prime); + /* prod_hi = ((xxh_u64x2)data_key >> 32) * ((xxh_u64x2)prime >> 32); */ + xxh_u64x2 const prod_odd = XXH_vec_mulo((xxh_u32x4)data_key, prime); + xacc[i] = prod_odd + (prod_even << v32); + } } +} + +#endif + +/* scalar variants - universal */ + +XXH_FORCE_INLINE void +XXH3_accumulate_512_scalar(void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64* const xacc = (xxh_u64*) acc; /* presumed aligned */ + const xxh_u8* const xinput = (const xxh_u8*) input; /* no alignment restriction */ + const xxh_u8* const xsecret = (const xxh_u8*) secret; /* no alignment restriction */ + size_t i; + XXH_ASSERT(((size_t)acc & (XXH_ACC_ALIGN-1)) == 0); + for (i=0; i < XXH_ACC_NB; i++) { + xxh_u64 const data_val = XXH_readLE64(xinput + 8*i); + xxh_u64 const data_key = data_val ^ XXH_readLE64(xsecret + i*8); + xacc[i ^ 1] += data_val; /* swap adjacent lanes */ + xacc[i] += XXH_mult32to64(data_key & 0xFFFFFFFF, data_key >> 32); + } +} + +XXH_FORCE_INLINE void +XXH3_scrambleAcc_scalar(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64* const xacc = (xxh_u64*) acc; /* presumed aligned */ + const xxh_u8* const xsecret = (const xxh_u8*) secret; /* no alignment restriction */ + size_t i; + XXH_ASSERT((((size_t)acc) & (XXH_ACC_ALIGN-1)) == 0); + for (i=0; i < XXH_ACC_NB; i++) { + xxh_u64 const key64 = XXH_readLE64(xsecret + 8*i); + xxh_u64 acc64 = xacc[i]; + acc64 = XXH_xorshift64(acc64, 47); + acc64 ^= key64; + acc64 *= XXH_PRIME32_1; + xacc[i] = acc64; + } +} + +XXH_FORCE_INLINE void +XXH3_initCustomSecret_scalar(void* XXH_RESTRICT customSecret, xxh_u64 seed64) +{ + /* + * We need a separate pointer for the hack below, + * which requires a non-const pointer. + * Any decent compiler will optimize this out otherwise. + */ + const xxh_u8* kSecretPtr = XXH3_kSecret; + XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0); + +#if defined(__clang__) && defined(__aarch64__) + /* + * UGLY HACK: + * Clang generates a bunch of MOV/MOVK pairs for aarch64, and they are + * placed sequentially, in order, at the top of the unrolled loop. + * + * While MOVK is great for generating constants (2 cycles for a 64-bit + * constant compared to 4 cycles for LDR), long MOVK chains stall the + * integer pipelines: + * I L S + * MOVK + * MOVK + * MOVK + * MOVK + * ADD + * SUB STR + * STR + * By forcing loads from memory (as the asm line causes Clang to assume + * that XXH3_kSecretPtr has been changed), the pipelines are used more + * efficiently: + * I L S + * LDR + * ADD LDR + * SUB STR + * STR + * XXH3_64bits_withSeed, len == 256, Snapdragon 835 + * without hack: 2654.4 MB/s + * with hack: 3202.9 MB/s + */ + __asm__("" : "+r" (kSecretPtr)); +#endif + /* + * Note: in debug mode, this overrides the asm optimization + * and Clang will emit MOVK chains again. + */ + XXH_ASSERT(kSecretPtr == XXH3_kSecret); + + { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / 16; + int i; + for (i=0; i < nbRounds; i++) { + /* + * The asm hack causes Clang to assume that kSecretPtr aliases with + * customSecret, and on aarch64, this prevented LDP from merging two + * loads together for free. Putting the loads together before the stores + * properly generates LDP. + */ + xxh_u64 lo = XXH_readLE64(kSecretPtr + 16*i) + seed64; + xxh_u64 hi = XXH_readLE64(kSecretPtr + 16*i + 8) - seed64; + XXH_writeLE64((xxh_u8*)customSecret + 16*i, lo); + XXH_writeLE64((xxh_u8*)customSecret + 16*i + 8, hi); + } } +} + + +typedef void (*XXH3_f_accumulate_512)(void* XXH_RESTRICT, const void*, const void*); +typedef void (*XXH3_f_scrambleAcc)(void* XXH_RESTRICT, const void*); +typedef void (*XXH3_f_initCustomSecret)(void* XXH_RESTRICT, xxh_u64); + + +#if (XXH_VECTOR == XXH_AVX512) + +#define XXH3_accumulate_512 XXH3_accumulate_512_avx512 +#define XXH3_scrambleAcc XXH3_scrambleAcc_avx512 +#define XXH3_initCustomSecret XXH3_initCustomSecret_avx512 + +#elif (XXH_VECTOR == XXH_AVX2) + +#define XXH3_accumulate_512 XXH3_accumulate_512_avx2 +#define XXH3_scrambleAcc XXH3_scrambleAcc_avx2 +#define XXH3_initCustomSecret XXH3_initCustomSecret_avx2 + +#elif (XXH_VECTOR == XXH_SSE2) + +#define XXH3_accumulate_512 XXH3_accumulate_512_sse2 +#define XXH3_scrambleAcc XXH3_scrambleAcc_sse2 +#define XXH3_initCustomSecret XXH3_initCustomSecret_sse2 + +#elif (XXH_VECTOR == XXH_NEON) + +#define XXH3_accumulate_512 XXH3_accumulate_512_neon +#define XXH3_scrambleAcc XXH3_scrambleAcc_neon +#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar + +#elif (XXH_VECTOR == XXH_VSX) + +#define XXH3_accumulate_512 XXH3_accumulate_512_vsx +#define XXH3_scrambleAcc XXH3_scrambleAcc_vsx +#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar + +#else /* scalar */ + +#define XXH3_accumulate_512 XXH3_accumulate_512_scalar +#define XXH3_scrambleAcc XXH3_scrambleAcc_scalar +#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar + +#endif + + + +#ifndef XXH_PREFETCH_DIST +# ifdef __clang__ +# define XXH_PREFETCH_DIST 320 +# else +# if (XXH_VECTOR == XXH_AVX512) +# define XXH_PREFETCH_DIST 512 +# else +# define XXH_PREFETCH_DIST 384 +# endif +# endif /* __clang__ */ +#endif /* XXH_PREFETCH_DIST */ + +/* + * XXH3_accumulate() + * Loops over XXH3_accumulate_512(). + * Assumption: nbStripes will not overflow the secret size + */ +XXH_FORCE_INLINE void +XXH3_accumulate( xxh_u64* XXH_RESTRICT acc, + const xxh_u8* XXH_RESTRICT input, + const xxh_u8* XXH_RESTRICT secret, + size_t nbStripes, + XXH3_f_accumulate_512 f_acc512) +{ + size_t n; + for (n = 0; n < nbStripes; n++ ) { + const xxh_u8* const in = input + n*XXH_STRIPE_LEN; + XXH_PREFETCH(in + XXH_PREFETCH_DIST); + f_acc512(acc, + in, + secret + n*XXH_SECRET_CONSUME_RATE); + } +} + +XXH_FORCE_INLINE void +XXH3_hashLong_internal_loop(xxh_u64* XXH_RESTRICT acc, + const xxh_u8* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble) +{ + size_t const nbStripesPerBlock = (secretSize - XXH_STRIPE_LEN) / XXH_SECRET_CONSUME_RATE; + size_t const block_len = XXH_STRIPE_LEN * nbStripesPerBlock; + size_t const nb_blocks = (len - 1) / block_len; + + size_t n; + + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); + + for (n = 0; n < nb_blocks; n++) { + XXH3_accumulate(acc, input + n*block_len, secret, nbStripesPerBlock, f_acc512); + f_scramble(acc, secret + secretSize - XXH_STRIPE_LEN); + } + + /* last partial block */ + XXH_ASSERT(len > XXH_STRIPE_LEN); + { size_t const nbStripes = ((len - 1) - (block_len * nb_blocks)) / XXH_STRIPE_LEN; + XXH_ASSERT(nbStripes <= (secretSize / XXH_SECRET_CONSUME_RATE)); + XXH3_accumulate(acc, input + nb_blocks*block_len, secret, nbStripes, f_acc512); + + /* last stripe */ + { const xxh_u8* const p = input + len - XXH_STRIPE_LEN; +#define XXH_SECRET_LASTACC_START 7 /* not aligned on 8, last secret is different from acc & scrambler */ + f_acc512(acc, p, secret + secretSize - XXH_STRIPE_LEN - XXH_SECRET_LASTACC_START); + } } +} + +XXH_FORCE_INLINE xxh_u64 +XXH3_mix2Accs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret) +{ + return XXH3_mul128_fold64( + acc[0] ^ XXH_readLE64(secret), + acc[1] ^ XXH_readLE64(secret+8) ); +} + +static XXH64_hash_t +XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 start) +{ + xxh_u64 result64 = start; + size_t i = 0; + + for (i = 0; i < 4; i++) { + result64 += XXH3_mix2Accs(acc+2*i, secret + 16*i); +#if defined(__clang__) /* Clang */ \ + && (defined(__arm__) || defined(__thumb__)) /* ARMv7 */ \ + && (defined(__ARM_NEON) || defined(__ARM_NEON__)) /* NEON */ \ + && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable */ + /* + * UGLY HACK: + * Prevent autovectorization on Clang ARMv7-a. Exact same problem as + * the one in XXH3_len_129to240_64b. Speeds up shorter keys > 240b. + * XXH3_64bits, len == 256, Snapdragon 835: + * without hack: 2063.7 MB/s + * with hack: 2560.7 MB/s + */ + __asm__("" : "+r" (result64)); +#endif + } + + return XXH3_avalanche(result64); +} + +#define XXH3_INIT_ACC { XXH_PRIME32_3, XXH_PRIME64_1, XXH_PRIME64_2, XXH_PRIME64_3, \ + XXH_PRIME64_4, XXH_PRIME32_2, XXH_PRIME64_5, XXH_PRIME32_1 } + +XXH_FORCE_INLINE XXH64_hash_t +XXH3_hashLong_64b_internal(const void* XXH_RESTRICT input, size_t len, + const void* XXH_RESTRICT secret, size_t secretSize, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble) +{ + XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC; + + XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, (const xxh_u8*)secret, secretSize, f_acc512, f_scramble); + + /* converge into final hash */ + XXH_STATIC_ASSERT(sizeof(acc) == 64); + /* do not align on 8, so that the secret is different from the accumulator */ +#define XXH_SECRET_MERGEACCS_START 11 + XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); + return XXH3_mergeAccs(acc, (const xxh_u8*)secret + XXH_SECRET_MERGEACCS_START, (xxh_u64)len * XXH_PRIME64_1); +} + +/* + * It's important for performance that XXH3_hashLong is not inlined. + */ +XXH_NO_INLINE XXH64_hash_t +XXH3_hashLong_64b_withSecret(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen) +{ + (void)seed64; + return XXH3_hashLong_64b_internal(input, len, secret, secretLen, XXH3_accumulate_512, XXH3_scrambleAcc); +} + +/* + * It's important for performance that XXH3_hashLong is not inlined. + * Since the function is not inlined, the compiler may not be able to understand that, + * in some scenarios, its `secret` argument is actually a compile time constant. + * This variant enforces that the compiler can detect that, + * and uses this opportunity to streamline the generated code for better performance. + */ +XXH_NO_INLINE XXH64_hash_t +XXH3_hashLong_64b_default(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen) +{ + (void)seed64; (void)secret; (void)secretLen; + return XXH3_hashLong_64b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_accumulate_512, XXH3_scrambleAcc); +} + +/* + * XXH3_hashLong_64b_withSeed(): + * Generate a custom key based on alteration of default XXH3_kSecret with the seed, + * and then use this key for long mode hashing. + * + * This operation is decently fast but nonetheless costs a little bit of time. + * Try to avoid it whenever possible (typically when seed==0). + * + * It's important for performance that XXH3_hashLong is not inlined. Not sure + * why (uop cache maybe?), but the difference is large and easily measurable. + */ +XXH_FORCE_INLINE XXH64_hash_t +XXH3_hashLong_64b_withSeed_internal(const void* input, size_t len, + XXH64_hash_t seed, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble, + XXH3_f_initCustomSecret f_initSec) +{ + if (seed == 0) + return XXH3_hashLong_64b_internal(input, len, + XXH3_kSecret, sizeof(XXH3_kSecret), + f_acc512, f_scramble); + { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE]; + f_initSec(secret, seed); + return XXH3_hashLong_64b_internal(input, len, secret, sizeof(secret), + f_acc512, f_scramble); + } +} + +/* + * It's important for performance that XXH3_hashLong is not inlined. + */ +XXH_NO_INLINE XXH64_hash_t +XXH3_hashLong_64b_withSeed(const void* input, size_t len, + XXH64_hash_t seed, const xxh_u8* secret, size_t secretLen) +{ + (void)secret; (void)secretLen; + return XXH3_hashLong_64b_withSeed_internal(input, len, seed, + XXH3_accumulate_512, XXH3_scrambleAcc, XXH3_initCustomSecret); +} + + +typedef XXH64_hash_t (*XXH3_hashLong64_f)(const void* XXH_RESTRICT, size_t, + XXH64_hash_t, const xxh_u8* XXH_RESTRICT, size_t); + +XXH_FORCE_INLINE XXH64_hash_t +XXH3_64bits_internal(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen, + XXH3_hashLong64_f f_hashLong) +{ + XXH_ASSERT(secretLen >= XXH3_SECRET_SIZE_MIN); + /* + * If an action is to be taken if `secretLen` condition is not respected, + * it should be done here. + * For now, it's a contract pre-condition. + * Adding a check and a branch here would cost performance at every hash. + * Also, note that function signature doesn't offer room to return an error. + */ + if (len <= 16) + return XXH3_len_0to16_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, seed64); + if (len <= 128) + return XXH3_len_17to128_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64); + if (len <= XXH3_MIDSIZE_MAX) + return XXH3_len_129to240_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64); + return f_hashLong(input, len, seed64, (const xxh_u8*)secret, secretLen); +} + + +/* === Public entry point === */ + +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* input, size_t len) +{ + return XXH3_64bits_internal(input, len, 0, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_default); +} + +XXH_PUBLIC_API XXH64_hash_t +XXH3_64bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize) +{ + return XXH3_64bits_internal(input, len, 0, secret, secretSize, XXH3_hashLong_64b_withSecret); +} + +XXH_PUBLIC_API XXH64_hash_t +XXH3_64bits_withSeed(const void* input, size_t len, XXH64_hash_t seed) +{ + return XXH3_64bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_withSeed); +} + + +/* === XXH3 streaming === */ + +/* + * Malloc's a pointer that is always aligned to align. + * + * This must be freed with `XXH_alignedFree()`. + * + * malloc typically guarantees 16 byte alignment on 64-bit systems and 8 byte + * alignment on 32-bit. This isn't enough for the 32 byte aligned loads in AVX2 + * or on 32-bit, the 16 byte aligned loads in SSE2 and NEON. + * + * This underalignment previously caused a rather obvious crash which went + * completely unnoticed due to XXH3_createState() not actually being tested. + * Credit to RedSpah for noticing this bug. + * + * The alignment is done manually: Functions like posix_memalign or _mm_malloc + * are avoided: To maintain portability, we would have to write a fallback + * like this anyways, and besides, testing for the existence of library + * functions without relying on external build tools is impossible. + * + * The method is simple: Overallocate, manually align, and store the offset + * to the original behind the returned pointer. + * + * Align must be a power of 2 and 8 <= align <= 128. + */ +static void* XXH_alignedMalloc(size_t s, size_t align) +{ + XXH_ASSERT(align <= 128 && align >= 8); /* range check */ + XXH_ASSERT((align & (align-1)) == 0); /* power of 2 */ + XXH_ASSERT(s != 0 && s < (s + align)); /* empty/overflow */ + { /* Overallocate to make room for manual realignment and an offset byte */ + xxh_u8* base = (xxh_u8*)XXH_malloc(s + align); + if (base != NULL) { + /* + * Get the offset needed to align this pointer. + * + * Even if the returned pointer is aligned, there will always be + * at least one byte to store the offset to the original pointer. + */ + size_t offset = align - ((size_t)base & (align - 1)); /* base % align */ + /* Add the offset for the now-aligned pointer */ + xxh_u8* ptr = base + offset; + + XXH_ASSERT((size_t)ptr % align == 0); + + /* Store the offset immediately before the returned pointer. */ + ptr[-1] = (xxh_u8)offset; + return ptr; + } + return NULL; + } +} +/* + * Frees an aligned pointer allocated by XXH_alignedMalloc(). Don't pass + * normal malloc'd pointers, XXH_alignedMalloc has a specific data layout. + */ +static void XXH_alignedFree(void* p) +{ + if (p != NULL) { + xxh_u8* ptr = (xxh_u8*)p; + /* Get the offset byte we added in XXH_malloc. */ + xxh_u8 offset = ptr[-1]; + /* Free the original malloc'd pointer */ + xxh_u8* base = ptr - offset; + XXH_free(base); + } +} +XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void) +{ + XXH3_state_t* const state = (XXH3_state_t*)XXH_alignedMalloc(sizeof(XXH3_state_t), 64); + if (state==NULL) return NULL; + XXH3_INITSTATE(state); + return state; +} + +XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr) +{ + XXH_alignedFree(statePtr); + return XXH_OK; +} + +XXH_PUBLIC_API void +XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state) +{ + memcpy(dst_state, src_state, sizeof(*dst_state)); +} + +static void +XXH3_64bits_reset_internal(XXH3_state_t* statePtr, + XXH64_hash_t seed, + const void* secret, size_t secretSize) +{ + size_t const initStart = offsetof(XXH3_state_t, bufferedSize); + size_t const initLength = offsetof(XXH3_state_t, nbStripesPerBlock) - initStart; + XXH_ASSERT(offsetof(XXH3_state_t, nbStripesPerBlock) > initStart); + XXH_ASSERT(statePtr != NULL); + /* set members from bufferedSize to nbStripesPerBlock (excluded) to 0 */ + memset((char*)statePtr + initStart, 0, initLength); + statePtr->acc[0] = XXH_PRIME32_3; + statePtr->acc[1] = XXH_PRIME64_1; + statePtr->acc[2] = XXH_PRIME64_2; + statePtr->acc[3] = XXH_PRIME64_3; + statePtr->acc[4] = XXH_PRIME64_4; + statePtr->acc[5] = XXH_PRIME32_2; + statePtr->acc[6] = XXH_PRIME64_5; + statePtr->acc[7] = XXH_PRIME32_1; + statePtr->seed = seed; + statePtr->extSecret = (const unsigned char*)secret; + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); + statePtr->secretLimit = secretSize - XXH_STRIPE_LEN; + statePtr->nbStripesPerBlock = statePtr->secretLimit / XXH_SECRET_CONSUME_RATE; +} + +XXH_PUBLIC_API XXH_errorcode +XXH3_64bits_reset(XXH3_state_t* statePtr) +{ + if (statePtr == NULL) return XXH_ERROR; + XXH3_64bits_reset_internal(statePtr, 0, XXH3_kSecret, XXH_SECRET_DEFAULT_SIZE); + return XXH_OK; +} + +XXH_PUBLIC_API XXH_errorcode +XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize) +{ + if (statePtr == NULL) return XXH_ERROR; + XXH3_64bits_reset_internal(statePtr, 0, secret, secretSize); + if (secret == NULL) return XXH_ERROR; + if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR; + return XXH_OK; +} + +XXH_PUBLIC_API XXH_errorcode +XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed) +{ + if (statePtr == NULL) return XXH_ERROR; + if (seed==0) return XXH3_64bits_reset(statePtr); + if (seed != statePtr->seed) XXH3_initCustomSecret(statePtr->customSecret, seed); + XXH3_64bits_reset_internal(statePtr, seed, NULL, XXH_SECRET_DEFAULT_SIZE); + return XXH_OK; +} + +/* Note : when XXH3_consumeStripes() is invoked, + * there must be a guarantee that at least one more byte must be consumed from input + * so that the function can blindly consume all stripes using the "normal" secret segment */ +XXH_FORCE_INLINE void +XXH3_consumeStripes(xxh_u64* XXH_RESTRICT acc, + size_t* XXH_RESTRICT nbStripesSoFarPtr, size_t nbStripesPerBlock, + const xxh_u8* XXH_RESTRICT input, size_t nbStripes, + const xxh_u8* XXH_RESTRICT secret, size_t secretLimit, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble) +{ + XXH_ASSERT(nbStripes <= nbStripesPerBlock); /* can handle max 1 scramble per invocation */ + XXH_ASSERT(*nbStripesSoFarPtr < nbStripesPerBlock); + if (nbStripesPerBlock - *nbStripesSoFarPtr <= nbStripes) { + /* need a scrambling operation */ + size_t const nbStripesToEndofBlock = nbStripesPerBlock - *nbStripesSoFarPtr; + size_t const nbStripesAfterBlock = nbStripes - nbStripesToEndofBlock; + XXH3_accumulate(acc, input, secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, nbStripesToEndofBlock, f_acc512); + f_scramble(acc, secret + secretLimit); + XXH3_accumulate(acc, input + nbStripesToEndofBlock * XXH_STRIPE_LEN, secret, nbStripesAfterBlock, f_acc512); + *nbStripesSoFarPtr = nbStripesAfterBlock; + } else { + XXH3_accumulate(acc, input, secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, nbStripes, f_acc512); + *nbStripesSoFarPtr += nbStripes; + } +} + +/* + * Both XXH3_64bits_update and XXH3_128bits_update use this routine. + */ +XXH_FORCE_INLINE XXH_errorcode +XXH3_update(XXH3_state_t* state, + const xxh_u8* input, size_t len, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble) +{ + if (input==NULL) +#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) + return XXH_OK; +#else + return XXH_ERROR; +#endif + + { const xxh_u8* const bEnd = input + len; + const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret; + state->totalLen += len; + + if (state->bufferedSize + len <= XXH3_INTERNALBUFFER_SIZE) { /* fill in tmp buffer */ + XXH_memcpy(state->buffer + state->bufferedSize, input, len); + state->bufferedSize += (XXH32_hash_t)len; + return XXH_OK; + } + /* total input is now > XXH3_INTERNALBUFFER_SIZE */ + + #define XXH3_INTERNALBUFFER_STRIPES (XXH3_INTERNALBUFFER_SIZE / XXH_STRIPE_LEN) + XXH_STATIC_ASSERT(XXH3_INTERNALBUFFER_SIZE % XXH_STRIPE_LEN == 0); /* clean multiple */ + + /* + * Internal buffer is partially filled (always, except at beginning) + * Complete it, then consume it. + */ + if (state->bufferedSize) { + size_t const loadSize = XXH3_INTERNALBUFFER_SIZE - state->bufferedSize; + XXH_memcpy(state->buffer + state->bufferedSize, input, loadSize); + input += loadSize; + XXH3_consumeStripes(state->acc, + &state->nbStripesSoFar, state->nbStripesPerBlock, + state->buffer, XXH3_INTERNALBUFFER_STRIPES, + secret, state->secretLimit, + f_acc512, f_scramble); + state->bufferedSize = 0; + } + XXH_ASSERT(input < bEnd); + + /* Consume input by a multiple of internal buffer size */ + if (input+XXH3_INTERNALBUFFER_SIZE < bEnd) { + const xxh_u8* const limit = bEnd - XXH3_INTERNALBUFFER_SIZE; + do { + XXH3_consumeStripes(state->acc, + &state->nbStripesSoFar, state->nbStripesPerBlock, + input, XXH3_INTERNALBUFFER_STRIPES, + secret, state->secretLimit, + f_acc512, f_scramble); + input += XXH3_INTERNALBUFFER_SIZE; + } while (input<limit); + /* for last partial stripe */ + memcpy(state->buffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN); + } + XXH_ASSERT(input < bEnd); + + /* Some remaining input (always) : buffer it */ + XXH_memcpy(state->buffer, input, (size_t)(bEnd-input)); + state->bufferedSize = (XXH32_hash_t)(bEnd-input); + } + + return XXH_OK; +} + +XXH_PUBLIC_API XXH_errorcode +XXH3_64bits_update(XXH3_state_t* state, const void* input, size_t len) +{ + return XXH3_update(state, (const xxh_u8*)input, len, + XXH3_accumulate_512, XXH3_scrambleAcc); +} + + +XXH_FORCE_INLINE void +XXH3_digest_long (XXH64_hash_t* acc, + const XXH3_state_t* state, + const unsigned char* secret) +{ + /* + * Digest on a local copy. This way, the state remains unaltered, and it can + * continue ingesting more input afterwards. + */ + memcpy(acc, state->acc, sizeof(state->acc)); + if (state->bufferedSize >= XXH_STRIPE_LEN) { + size_t const nbStripes = (state->bufferedSize - 1) / XXH_STRIPE_LEN; + size_t nbStripesSoFar = state->nbStripesSoFar; + XXH3_consumeStripes(acc, + &nbStripesSoFar, state->nbStripesPerBlock, + state->buffer, nbStripes, + secret, state->secretLimit, + XXH3_accumulate_512, XXH3_scrambleAcc); + /* last stripe */ + XXH3_accumulate_512(acc, + state->buffer + state->bufferedSize - XXH_STRIPE_LEN, + secret + state->secretLimit - XXH_SECRET_LASTACC_START); + } else { /* bufferedSize < XXH_STRIPE_LEN */ + xxh_u8 lastStripe[XXH_STRIPE_LEN]; + size_t const catchupSize = XXH_STRIPE_LEN - state->bufferedSize; + XXH_ASSERT(state->bufferedSize > 0); /* there is always some input buffered */ + memcpy(lastStripe, state->buffer + sizeof(state->buffer) - catchupSize, catchupSize); + memcpy(lastStripe + catchupSize, state->buffer, state->bufferedSize); + XXH3_accumulate_512(acc, + lastStripe, + secret + state->secretLimit - XXH_SECRET_LASTACC_START); + } +} + +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state) +{ + const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret; + if (state->totalLen > XXH3_MIDSIZE_MAX) { + XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB]; + XXH3_digest_long(acc, state, secret); + return XXH3_mergeAccs(acc, + secret + XXH_SECRET_MERGEACCS_START, + (xxh_u64)state->totalLen * XXH_PRIME64_1); + } + /* totalLen <= XXH3_MIDSIZE_MAX: digesting a short input */ + if (state->seed) + return XXH3_64bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed); + return XXH3_64bits_withSecret(state->buffer, (size_t)(state->totalLen), + secret, state->secretLimit + XXH_STRIPE_LEN); +} + + +#define XXH_MIN(x, y) (((x) > (y)) ? (y) : (x)) + +XXH_PUBLIC_API void +XXH3_generateSecret(void* secretBuffer, const void* customSeed, size_t customSeedSize) +{ + XXH_ASSERT(secretBuffer != NULL); + if (customSeedSize == 0) { + memcpy(secretBuffer, XXH3_kSecret, XXH_SECRET_DEFAULT_SIZE); + return; + } + XXH_ASSERT(customSeed != NULL); + + { size_t const segmentSize = sizeof(XXH128_hash_t); + size_t const nbSegments = XXH_SECRET_DEFAULT_SIZE / segmentSize; + XXH128_canonical_t scrambler; + XXH64_hash_t seeds[12]; + size_t segnb; + XXH_ASSERT(nbSegments == 12); + XXH_ASSERT(segmentSize * nbSegments == XXH_SECRET_DEFAULT_SIZE); /* exact multiple */ + XXH128_canonicalFromHash(&scrambler, XXH128(customSeed, customSeedSize, 0)); + + /* + * Copy customSeed to seeds[], truncating or repeating as necessary. + */ + { size_t toFill = XXH_MIN(customSeedSize, sizeof(seeds)); + size_t filled = toFill; + memcpy(seeds, customSeed, toFill); + while (filled < sizeof(seeds)) { + toFill = XXH_MIN(filled, sizeof(seeds) - filled); + memcpy((char*)seeds + filled, seeds, toFill); + filled += toFill; + } } + + /* generate secret */ + memcpy(secretBuffer, &scrambler, sizeof(scrambler)); + for (segnb=1; segnb < nbSegments; segnb++) { + size_t const segmentStart = segnb * segmentSize; + XXH128_canonical_t segment; + XXH128_canonicalFromHash(&segment, + XXH128(&scrambler, sizeof(scrambler), XXH_readLE64(seeds + segnb) + segnb) ); + memcpy((char*)secretBuffer + segmentStart, &segment, sizeof(segment)); + } } +} + + +/* ========================================== + * XXH3 128 bits (a.k.a XXH128) + * ========================================== + * XXH3's 128-bit variant has better mixing and strength than the 64-bit variant, + * even without counting the significantly larger output size. + * + * For example, extra steps are taken to avoid the seed-dependent collisions + * in 17-240 byte inputs (See XXH3_mix16B and XXH128_mix32B). + * + * This strength naturally comes at the cost of some speed, especially on short + * lengths. Note that longer hashes are about as fast as the 64-bit version + * due to it using only a slight modification of the 64-bit loop. + * + * XXH128 is also more oriented towards 64-bit machines. It is still extremely + * fast for a _128-bit_ hash on 32-bit (it usually clears XXH64). + */ + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_len_1to3_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + /* A doubled version of 1to3_64b with different constants. */ + XXH_ASSERT(input != NULL); + XXH_ASSERT(1 <= len && len <= 3); + XXH_ASSERT(secret != NULL); + /* + * len = 1: combinedl = { input[0], 0x01, input[0], input[0] } + * len = 2: combinedl = { input[1], 0x02, input[0], input[1] } + * len = 3: combinedl = { input[2], 0x03, input[0], input[1] } + */ + { xxh_u8 const c1 = input[0]; + xxh_u8 const c2 = input[len >> 1]; + xxh_u8 const c3 = input[len - 1]; + xxh_u32 const combinedl = ((xxh_u32)c1 <<16) | ((xxh_u32)c2 << 24) + | ((xxh_u32)c3 << 0) | ((xxh_u32)len << 8); + xxh_u32 const combinedh = XXH_rotl32(XXH_swap32(combinedl), 13); + xxh_u64 const bitflipl = (XXH_readLE32(secret) ^ XXH_readLE32(secret+4)) + seed; + xxh_u64 const bitfliph = (XXH_readLE32(secret+8) ^ XXH_readLE32(secret+12)) - seed; + xxh_u64 const keyed_lo = (xxh_u64)combinedl ^ bitflipl; + xxh_u64 const keyed_hi = (xxh_u64)combinedh ^ bitfliph; + XXH128_hash_t h128; + h128.low64 = XXH64_avalanche(keyed_lo); + h128.high64 = XXH64_avalanche(keyed_hi); + return h128; + } +} + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_len_4to8_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(input != NULL); + XXH_ASSERT(secret != NULL); + XXH_ASSERT(4 <= len && len <= 8); + seed ^= (xxh_u64)XXH_swap32((xxh_u32)seed) << 32; + { xxh_u32 const input_lo = XXH_readLE32(input); + xxh_u32 const input_hi = XXH_readLE32(input + len - 4); + xxh_u64 const input_64 = input_lo + ((xxh_u64)input_hi << 32); + xxh_u64 const bitflip = (XXH_readLE64(secret+16) ^ XXH_readLE64(secret+24)) + seed; + xxh_u64 const keyed = input_64 ^ bitflip; + + /* Shift len to the left to ensure it is even, this avoids even multiplies. */ + XXH128_hash_t m128 = XXH_mult64to128(keyed, XXH_PRIME64_1 + (len << 2)); + + m128.high64 += (m128.low64 << 1); + m128.low64 ^= (m128.high64 >> 3); + + m128.low64 = XXH_xorshift64(m128.low64, 35); + m128.low64 *= 0x9FB21C651E98DF25ULL; + m128.low64 = XXH_xorshift64(m128.low64, 28); + m128.high64 = XXH3_avalanche(m128.high64); + return m128; + } +} + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_len_9to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(input != NULL); + XXH_ASSERT(secret != NULL); + XXH_ASSERT(9 <= len && len <= 16); + { xxh_u64 const bitflipl = (XXH_readLE64(secret+32) ^ XXH_readLE64(secret+40)) - seed; + xxh_u64 const bitfliph = (XXH_readLE64(secret+48) ^ XXH_readLE64(secret+56)) + seed; + xxh_u64 const input_lo = XXH_readLE64(input); + xxh_u64 input_hi = XXH_readLE64(input + len - 8); + XXH128_hash_t m128 = XXH_mult64to128(input_lo ^ input_hi ^ bitflipl, XXH_PRIME64_1); + /* + * Put len in the middle of m128 to ensure that the length gets mixed to + * both the low and high bits in the 128x64 multiply below. + */ + m128.low64 += (xxh_u64)(len - 1) << 54; + input_hi ^= bitfliph; + /* + * Add the high 32 bits of input_hi to the high 32 bits of m128, then + * add the long product of the low 32 bits of input_hi and XXH_PRIME32_2 to + * the high 64 bits of m128. + * + * The best approach to this operation is different on 32-bit and 64-bit. + */ + if (sizeof(void *) < sizeof(xxh_u64)) { /* 32-bit */ + /* + * 32-bit optimized version, which is more readable. + * + * On 32-bit, it removes an ADC and delays a dependency between the two + * halves of m128.high64, but it generates an extra mask on 64-bit. + */ + m128.high64 += (input_hi & 0xFFFFFFFF00000000ULL) + XXH_mult32to64((xxh_u32)input_hi, XXH_PRIME32_2); + } else { + /* + * 64-bit optimized (albeit more confusing) version. + * + * Uses some properties of addition and multiplication to remove the mask: + * + * Let: + * a = input_hi.lo = (input_hi & 0x00000000FFFFFFFF) + * b = input_hi.hi = (input_hi & 0xFFFFFFFF00000000) + * c = XXH_PRIME32_2 + * + * a + (b * c) + * Inverse Property: x + y - x == y + * a + (b * (1 + c - 1)) + * Distributive Property: x * (y + z) == (x * y) + (x * z) + * a + (b * 1) + (b * (c - 1)) + * Identity Property: x * 1 == x + * a + b + (b * (c - 1)) + * + * Substitute a, b, and c: + * input_hi.hi + input_hi.lo + ((xxh_u64)input_hi.lo * (XXH_PRIME32_2 - 1)) + * + * Since input_hi.hi + input_hi.lo == input_hi, we get this: + * input_hi + ((xxh_u64)input_hi.lo * (XXH_PRIME32_2 - 1)) + */ + m128.high64 += input_hi + XXH_mult32to64((xxh_u32)input_hi, XXH_PRIME32_2 - 1); + } + /* m128 ^= XXH_swap64(m128 >> 64); */ + m128.low64 ^= XXH_swap64(m128.high64); + + { /* 128x64 multiply: h128 = m128 * XXH_PRIME64_2; */ + XXH128_hash_t h128 = XXH_mult64to128(m128.low64, XXH_PRIME64_2); + h128.high64 += m128.high64 * XXH_PRIME64_2; + + h128.low64 = XXH3_avalanche(h128.low64); + h128.high64 = XXH3_avalanche(h128.high64); + return h128; + } } +} + +/* + * Assumption: `secret` size is >= XXH3_SECRET_SIZE_MIN + */ +XXH_FORCE_INLINE XXH128_hash_t +XXH3_len_0to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(len <= 16); + { if (len > 8) return XXH3_len_9to16_128b(input, len, secret, seed); + if (len >= 4) return XXH3_len_4to8_128b(input, len, secret, seed); + if (len) return XXH3_len_1to3_128b(input, len, secret, seed); + { XXH128_hash_t h128; + xxh_u64 const bitflipl = XXH_readLE64(secret+64) ^ XXH_readLE64(secret+72); + xxh_u64 const bitfliph = XXH_readLE64(secret+80) ^ XXH_readLE64(secret+88); + h128.low64 = XXH64_avalanche(seed ^ bitflipl); + h128.high64 = XXH64_avalanche( seed ^ bitfliph); + return h128; + } } +} + +/* + * A bit slower than XXH3_mix16B, but handles multiply by zero better. + */ +XXH_FORCE_INLINE XXH128_hash_t +XXH128_mix32B(XXH128_hash_t acc, const xxh_u8* input_1, const xxh_u8* input_2, + const xxh_u8* secret, XXH64_hash_t seed) +{ + acc.low64 += XXH3_mix16B (input_1, secret+0, seed); + acc.low64 ^= XXH_readLE64(input_2) + XXH_readLE64(input_2 + 8); + acc.high64 += XXH3_mix16B (input_2, secret+16, seed); + acc.high64 ^= XXH_readLE64(input_1) + XXH_readLE64(input_1 + 8); + return acc; +} + + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH64_hash_t seed) +{ + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize; + XXH_ASSERT(16 < len && len <= 128); + + { XXH128_hash_t acc; + acc.low64 = len * XXH_PRIME64_1; + acc.high64 = 0; + if (len > 32) { + if (len > 64) { + if (len > 96) { + acc = XXH128_mix32B(acc, input+48, input+len-64, secret+96, seed); + } + acc = XXH128_mix32B(acc, input+32, input+len-48, secret+64, seed); + } + acc = XXH128_mix32B(acc, input+16, input+len-32, secret+32, seed); + } + acc = XXH128_mix32B(acc, input, input+len-16, secret, seed); + { XXH128_hash_t h128; + h128.low64 = acc.low64 + acc.high64; + h128.high64 = (acc.low64 * XXH_PRIME64_1) + + (acc.high64 * XXH_PRIME64_4) + + ((len - seed) * XXH_PRIME64_2); + h128.low64 = XXH3_avalanche(h128.low64); + h128.high64 = (XXH64_hash_t)0 - XXH3_avalanche(h128.high64); + return h128; + } + } +} + +XXH_NO_INLINE XXH128_hash_t +XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH64_hash_t seed) +{ + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize; + XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX); + + { XXH128_hash_t acc; + int const nbRounds = (int)len / 32; + int i; + acc.low64 = len * XXH_PRIME64_1; + acc.high64 = 0; + for (i=0; i<4; i++) { + acc = XXH128_mix32B(acc, + input + (32 * i), + input + (32 * i) + 16, + secret + (32 * i), + seed); + } + acc.low64 = XXH3_avalanche(acc.low64); + acc.high64 = XXH3_avalanche(acc.high64); + XXH_ASSERT(nbRounds >= 4); + for (i=4 ; i < nbRounds; i++) { + acc = XXH128_mix32B(acc, + input + (32 * i), + input + (32 * i) + 16, + secret + XXH3_MIDSIZE_STARTOFFSET + (32 * (i - 4)), + seed); + } + /* last bytes */ + acc = XXH128_mix32B(acc, + input + len - 16, + input + len - 32, + secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET - 16, + 0ULL - seed); + + { XXH128_hash_t h128; + h128.low64 = acc.low64 + acc.high64; + h128.high64 = (acc.low64 * XXH_PRIME64_1) + + (acc.high64 * XXH_PRIME64_4) + + ((len - seed) * XXH_PRIME64_2); + h128.low64 = XXH3_avalanche(h128.low64); + h128.high64 = (XXH64_hash_t)0 - XXH3_avalanche(h128.high64); + return h128; + } + } +} + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble) +{ + XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC; + + XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, secret, secretSize, f_acc512, f_scramble); + + /* converge into final hash */ + XXH_STATIC_ASSERT(sizeof(acc) == 64); + XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); + { XXH128_hash_t h128; + h128.low64 = XXH3_mergeAccs(acc, + secret + XXH_SECRET_MERGEACCS_START, + (xxh_u64)len * XXH_PRIME64_1); + h128.high64 = XXH3_mergeAccs(acc, + secret + secretSize + - sizeof(acc) - XXH_SECRET_MERGEACCS_START, + ~((xxh_u64)len * XXH_PRIME64_2)); + return h128; + } +} + +/* + * It's important for performance that XXH3_hashLong is not inlined. + */ +XXH_NO_INLINE XXH128_hash_t +XXH3_hashLong_128b_default(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, + const void* XXH_RESTRICT secret, size_t secretLen) +{ + (void)seed64; (void)secret; (void)secretLen; + return XXH3_hashLong_128b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), + XXH3_accumulate_512, XXH3_scrambleAcc); +} + +/* + * It's important for performance that XXH3_hashLong is not inlined. + */ +XXH_NO_INLINE XXH128_hash_t +XXH3_hashLong_128b_withSecret(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, + const void* XXH_RESTRICT secret, size_t secretLen) +{ + (void)seed64; + return XXH3_hashLong_128b_internal(input, len, (const xxh_u8*)secret, secretLen, + XXH3_accumulate_512, XXH3_scrambleAcc); +} + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_hashLong_128b_withSeed_internal(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble, + XXH3_f_initCustomSecret f_initSec) +{ + if (seed64 == 0) + return XXH3_hashLong_128b_internal(input, len, + XXH3_kSecret, sizeof(XXH3_kSecret), + f_acc512, f_scramble); + { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE]; + f_initSec(secret, seed64); + return XXH3_hashLong_128b_internal(input, len, (const xxh_u8*)secret, sizeof(secret), + f_acc512, f_scramble); + } +} + +/* + * It's important for performance that XXH3_hashLong is not inlined. + */ +XXH_NO_INLINE XXH128_hash_t +XXH3_hashLong_128b_withSeed(const void* input, size_t len, + XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen) +{ + (void)secret; (void)secretLen; + return XXH3_hashLong_128b_withSeed_internal(input, len, seed64, + XXH3_accumulate_512, XXH3_scrambleAcc, XXH3_initCustomSecret); +} + +typedef XXH128_hash_t (*XXH3_hashLong128_f)(const void* XXH_RESTRICT, size_t, + XXH64_hash_t, const void* XXH_RESTRICT, size_t); + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_128bits_internal(const void* input, size_t len, + XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen, + XXH3_hashLong128_f f_hl128) +{ + XXH_ASSERT(secretLen >= XXH3_SECRET_SIZE_MIN); + /* + * If an action is to be taken if `secret` conditions are not respected, + * it should be done here. + * For now, it's a contract pre-condition. + * Adding a check and a branch here would cost performance at every hash. + */ + if (len <= 16) + return XXH3_len_0to16_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, seed64); + if (len <= 128) + return XXH3_len_17to128_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64); + if (len <= XXH3_MIDSIZE_MAX) + return XXH3_len_129to240_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64); + return f_hl128(input, len, seed64, secret, secretLen); +} + + +/* === Public XXH128 API === */ + +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* input, size_t len) +{ + return XXH3_128bits_internal(input, len, 0, + XXH3_kSecret, sizeof(XXH3_kSecret), + XXH3_hashLong_128b_default); +} + +XXH_PUBLIC_API XXH128_hash_t +XXH3_128bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize) +{ + return XXH3_128bits_internal(input, len, 0, + (const xxh_u8*)secret, secretSize, + XXH3_hashLong_128b_withSecret); +} + +XXH_PUBLIC_API XXH128_hash_t +XXH3_128bits_withSeed(const void* input, size_t len, XXH64_hash_t seed) +{ + return XXH3_128bits_internal(input, len, seed, + XXH3_kSecret, sizeof(XXH3_kSecret), + XXH3_hashLong_128b_withSeed); +} + +XXH_PUBLIC_API XXH128_hash_t +XXH128(const void* input, size_t len, XXH64_hash_t seed) +{ + return XXH3_128bits_withSeed(input, len, seed); +} + + +/* === XXH3 128-bit streaming === */ + +/* + * All the functions are actually the same as for 64-bit streaming variant. + * The only difference is the finalizatiom routine. + */ + +static void +XXH3_128bits_reset_internal(XXH3_state_t* statePtr, + XXH64_hash_t seed, + const void* secret, size_t secretSize) +{ + XXH3_64bits_reset_internal(statePtr, seed, secret, secretSize); +} + +XXH_PUBLIC_API XXH_errorcode +XXH3_128bits_reset(XXH3_state_t* statePtr) +{ + if (statePtr == NULL) return XXH_ERROR; + XXH3_128bits_reset_internal(statePtr, 0, XXH3_kSecret, XXH_SECRET_DEFAULT_SIZE); + return XXH_OK; +} + +XXH_PUBLIC_API XXH_errorcode +XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize) +{ + if (statePtr == NULL) return XXH_ERROR; + XXH3_128bits_reset_internal(statePtr, 0, secret, secretSize); + if (secret == NULL) return XXH_ERROR; + if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR; + return XXH_OK; +} + +XXH_PUBLIC_API XXH_errorcode +XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed) +{ + if (statePtr == NULL) return XXH_ERROR; + if (seed==0) return XXH3_128bits_reset(statePtr); + if (seed != statePtr->seed) XXH3_initCustomSecret(statePtr->customSecret, seed); + XXH3_128bits_reset_internal(statePtr, seed, NULL, XXH_SECRET_DEFAULT_SIZE); + return XXH_OK; +} + +XXH_PUBLIC_API XXH_errorcode +XXH3_128bits_update(XXH3_state_t* state, const void* input, size_t len) +{ + return XXH3_update(state, (const xxh_u8*)input, len, + XXH3_accumulate_512, XXH3_scrambleAcc); +} + +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* state) +{ + const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret; + if (state->totalLen > XXH3_MIDSIZE_MAX) { + XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB]; + XXH3_digest_long(acc, state, secret); + XXH_ASSERT(state->secretLimit + XXH_STRIPE_LEN >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); + { XXH128_hash_t h128; + h128.low64 = XXH3_mergeAccs(acc, + secret + XXH_SECRET_MERGEACCS_START, + (xxh_u64)state->totalLen * XXH_PRIME64_1); + h128.high64 = XXH3_mergeAccs(acc, + secret + state->secretLimit + XXH_STRIPE_LEN + - sizeof(acc) - XXH_SECRET_MERGEACCS_START, + ~((xxh_u64)state->totalLen * XXH_PRIME64_2)); + return h128; + } + } + /* len <= XXH3_MIDSIZE_MAX : short code */ + if (state->seed) + return XXH3_128bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed); + return XXH3_128bits_withSecret(state->buffer, (size_t)(state->totalLen), + secret, state->secretLimit + XXH_STRIPE_LEN); +} + +/* 128-bit utility functions */ + +#include <string.h> /* memcmp, memcpy */ + +/* return : 1 is equal, 0 if different */ +XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2) +{ + /* note : XXH128_hash_t is compact, it has no padding byte */ + return !(memcmp(&h1, &h2, sizeof(h1))); +} + +/* This prototype is compatible with stdlib's qsort(). + * return : >0 if *h128_1 > *h128_2 + * <0 if *h128_1 < *h128_2 + * =0 if *h128_1 == *h128_2 */ +XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2) +{ + XXH128_hash_t const h1 = *(const XXH128_hash_t*)h128_1; + XXH128_hash_t const h2 = *(const XXH128_hash_t*)h128_2; + int const hcmp = (h1.high64 > h2.high64) - (h2.high64 > h1.high64); + /* note : bets that, in most cases, hash values are different */ + if (hcmp) return hcmp; + return (h1.low64 > h2.low64) - (h2.low64 > h1.low64); +} + + +/*====== Canonical representation ======*/ +XXH_PUBLIC_API void +XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash) +{ + XXH_STATIC_ASSERT(sizeof(XXH128_canonical_t) == sizeof(XXH128_hash_t)); + if (XXH_CPU_LITTLE_ENDIAN) { + hash.high64 = XXH_swap64(hash.high64); + hash.low64 = XXH_swap64(hash.low64); + } + memcpy(dst, &hash.high64, sizeof(hash.high64)); + memcpy((char*)dst + sizeof(hash.high64), &hash.low64, sizeof(hash.low64)); +} + +XXH_PUBLIC_API XXH128_hash_t +XXH128_hashFromCanonical(const XXH128_canonical_t* src) +{ + XXH128_hash_t h; + h.high64 = XXH_readBE64(src); + h.low64 = XXH_readBE64(src->digest + 8); + return h; +} + +/* Pop our optimization override from above */ +#if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \ + && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \ + && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */ +# pragma GCC pop_options +#endif #endif /* XXH_NO_LONG_LONG */ diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/AGLTable.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/AGLTable.hpp index c1d460273a5..67c6dbcea16 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/AGLTable.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/AGLTable.hpp @@ -2,7 +2,7 @@ ** AGLTable.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.cpp index bb30154e7ba..d37a89c20cc 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.cpp @@ -2,7 +2,7 @@ ** BasicDVIReader.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -154,6 +154,47 @@ int BasicDVIReader::executeCommand () { } +void BasicDVIReader::executePreamble () { + clearStream(); + if (isStreamValid()) { + seek(0); + if (readByte() == OP_PRE) { + cmdPre(0); + return; + } + } + throw DVIException("invalid DVI file"); +} + + +/** Moves stream pointer to begin of postamble */ +void BasicDVIReader::goToPostamble () { + clearStream(); + if (!isStreamValid()) + throw DVIException("invalid DVI file"); + + seek(-1, ios::end); // stream pointer to last byte + int count=0; + while (peek() == DVI_FILL) { // skip fill bytes + seek(-1, ios::cur); + count++; + } + if (count < 4) // the standard requires at least 4 trailing fill bytes + throw DVIException("missing fill bytes at end of file"); + + seek(-4, ios::cur); // now at first byte of q (pointer to begin of postamble) + uint32_t q = readUnsigned(4); // pointer to begin of postamble + seek(q); // now at begin of postamble +} + + +/** Reads and executes the commands of the postamble. */ +void BasicDVIReader::executePostamble () { + goToPostamble(); + while (executeCommand() != OP_POSTPOST); // executes all commands until post_post (= 249) is reached +} + + void BasicDVIReader::executePostPost () { clearStream(); // reset all status bits if (!isStreamValid()) @@ -172,6 +213,37 @@ void BasicDVIReader::executePostPost () { } +void BasicDVIReader::executeFontDefs () { + goToPostamble(); + seek(1+28, ios::cur); // now on first fontdef or postpost + if (peek() != OP_POSTPOST) + while (executeCommand() != OP_POSTPOST); +} + + +/** Collects and records the file offsets of all bop commands. */ +vector<uint32_t> BasicDVIReader::collectBopOffsets () { + std::vector<uint32_t> bopOffsets; + goToPostamble(); + bopOffsets.push_back(tell()); // also add offset of postamble + readByte(); // skip post command + uint32_t offset = readUnsigned(4); // offset of final bop + while (int32_t(offset) != -1) { // not yet on first bop? + bopOffsets.push_back(offset); // record offset + seek(offset); // now on previous bop + if (readByte() != OP_BOP) + throw DVIException("bop offset at "+to_string(offset)+" doesn't point to bop command" ); + seek(40, ios::cur); // skip the 10 \count values => now on offset of previous bop + uint32_t prevOffset = readUnsigned(4); + if ((prevOffset >= offset && int32_t(prevOffset) != -1)) + throw DVIException("invalid bop offset at "+to_string(tell()-static_cast<streamoff>(4))); + offset = prevOffset; + } + reverse(bopOffsets.begin(), bopOffsets.end()); + return bopOffsets; +} + + void BasicDVIReader::executeAllPages () { if (_dviVersion == DVI_NONE) executePostPost(); // get version ID from post_post diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.hpp index 7ce1f989e2a..a71c547fa55 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.hpp @@ -2,7 +2,7 @@ ** BasicDVIReader.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -52,6 +52,7 @@ class BasicDVIReader : public StreamReader { public: explicit BasicDVIReader (std::istream &is); virtual void executeAllPages (); + virtual void executeFontDefs (); virtual double getXPos () const {return 0;} virtual double getYPos () const {return 0;} virtual void finishLine () {} @@ -66,7 +67,11 @@ class BasicDVIReader : public StreamReader { DVIVersion getDVIVersion () const {return _dviVersion;} virtual int evalCommand (CommandHandler &handler, int ¶m); virtual int executeCommand (); + void executePreamble (); + void executePostamble (); void executePostPost (); + void goToPostamble (); + std::vector<uint32_t> collectBopOffsets (); bool evalXDVOpcode (int op, CommandHandler &handler) const; // The following template methods represent the single DVI commands. They diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Bezier.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Bezier.cpp index 87a0070621d..b26ed711494 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Bezier.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Bezier.cpp @@ -2,7 +2,7 @@ ** Bezier.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Bezier.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Bezier.hpp index 322dd4e72d3..18050ca8578 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Bezier.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Bezier.hpp @@ -2,7 +2,7 @@ ** Bezier.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.cpp index 3b315b50a32..acf2c40a80f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.cpp @@ -2,7 +2,7 @@ ** BgColorSpecialHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.hpp index 9334a5c5417..07c13437e57 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.hpp @@ -2,7 +2,7 @@ ** BgColorSpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Bitmap.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Bitmap.cpp index 64ebd6195e1..c59e4446086 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Bitmap.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Bitmap.cpp @@ -2,7 +2,7 @@ ** Bitmap.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Bitmap.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Bitmap.hpp index 0d04aa2a694..f0bba3b41ea 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Bitmap.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Bitmap.hpp @@ -2,7 +2,7 @@ ** Bitmap.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp index 2dbcc2ebcda..78f3a19ee58 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp @@ -2,7 +2,7 @@ ** BoundingBox.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.hpp index c52312a24a4..e3b59ebf5de 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.hpp @@ -2,7 +2,7 @@ ** BoundingBox.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.cpp index 1f6bb4475e7..ae245699c57 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.cpp @@ -2,7 +2,7 @@ ** CLCommandLine.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.hpp index 257ff4160f8..9f9814368bc 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.hpp @@ -2,7 +2,7 @@ ** CLCommandLine.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CLOption.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CLOption.hpp index d9da7ae008f..594610b896f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CLOption.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CLOption.hpp @@ -2,7 +2,7 @@ ** CLOption.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMap.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMap.cpp index 747fb5ad50e..6c9b10ed10c 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMap.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMap.cpp @@ -2,7 +2,7 @@ ** CMap.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -23,6 +23,7 @@ #include "CMap.hpp" #include "CMapManager.hpp" #include "FileFinder.hpp" +#include "Unicode.hpp" using namespace std; @@ -38,6 +39,22 @@ const FontEncoding* CMap::findCompatibleBaseFontMap (const PhysicalFont *font, C ////////////////////////////////////////////////////////////////////// +void SegmentedCMap::addCIDRange (uint32_t first, uint32_t last, uint32_t cid) { + if (uint32_t cp = Unicode::fromSurrogate(first)) // is 'first' a surrogate? + first = cp; + if (uint32_t cp = Unicode::fromSurrogate(last)) // is 'last' a surrogate? + last = cp; + _cidranges.addRange(first, last, cid); +} + + +void SegmentedCMap::addBFRange (uint32_t first, uint32_t last, uint32_t chrcode) { + if (uint32_t cp = Unicode::fromSurrogate(chrcode)) // is 'chrcode' a surrogate? + chrcode = cp; + _bfranges.addRange(first, last, chrcode); +} + + /** Returns the RO (Registry-Ordering) string of the CMap. */ string SegmentedCMap::getROString() const { if (_registry.empty() || _ordering.empty()) @@ -46,6 +63,17 @@ string SegmentedCMap::getROString() const { } +bool SegmentedCMap::mapsToUnicode () const { + vector<string> encstrings = {"UTF8", "UTF16", "UCS2", "UCS4", "UCS32"}; + for (const string &encstr : encstrings) { + size_t pos = _filename.find(encstr); + if (pos != string::npos && (pos == 0 || _filename[pos-1] == '-')) + return true; + } + return false; +} + + /** Returns the CID for a given character code. */ uint32_t SegmentedCMap::cid (uint32_t c) const { if (_cidranges.valueExists(c)) diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMap.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMap.hpp index 63761ff2ff9..606a401ff72 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMap.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMap.hpp @@ -2,7 +2,7 @@ ** CMap.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -74,6 +74,7 @@ struct UnicodeCMap : public CMap { uint32_t cid (uint32_t c) const override {return c;} uint32_t bfcode (uint32_t cid) const override {return cid;} std::string getROString () const override {return "";} + bool mapsToUnicode () const override {return true;} }; @@ -85,19 +86,21 @@ class SegmentedCMap : public CMap { const char* name () const override {return _filename.c_str();} uint32_t cid (uint32_t c) const override; uint32_t bfcode (uint32_t cid) const override; - void addCIDRange (uint32_t first, uint32_t last, uint32_t cid) {_cidranges.addRange(first, last, cid);} - void addBFRange (uint32_t first, uint32_t last, uint32_t chrcode) {_bfranges.addRange(first, last, chrcode);} + void addCIDRange (uint32_t first, uint32_t last, uint32_t cid); + void addBFRange (uint32_t first, uint32_t last, uint32_t chrcode); void write (std::ostream &os) const; bool vertical () const override {return _vertical;} bool mapsToCID () const override {return _mapsToCID;} size_t numCIDRanges () const {return _cidranges.numRanges();} size_t numBFRanges () const {return _bfranges.numRanges();} std::string getROString () const override; + bool mapsToUnicode () const override; private: std::string _filename; std::string _registry; std::string _ordering; + std::string _cmaptype; CMap *_basemap = nullptr; bool _vertical = false; bool _mapsToCID = true; // true: chrcode->CID, false: CID->charcode diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.cpp index 52b323ebc62..dfc564f7f2b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.cpp @@ -2,7 +2,7 @@ ** CMapManager.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.hpp index aeb9156e847..eab32e76466 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapManager.hpp @@ -2,7 +2,7 @@ ** CMapManager.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapReader.cpp index 51ba52b95da..c56d3bd463a 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapReader.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapReader.cpp @@ -2,7 +2,7 @@ ** CMapReader.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -114,6 +114,8 @@ void CMapReader::op_def (InputReader&) { else throw CMapReaderException("invalid WMode (0 or 1 expected)"); } + else if (name == "CMapType") + _cmap->_cmaptype = val; else if (name == "Registry") _cmap->_registry = val; else if (name == "Ordering") diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapReader.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapReader.hpp index 04ce5740c00..6e9a03ce980 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapReader.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CMapReader.hpp @@ -2,7 +2,7 @@ ** CMapReader.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Calculator.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Calculator.cpp index 0fdcf0f2fa3..00490efa045 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Calculator.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Calculator.cpp @@ -2,7 +2,7 @@ ** Calculator.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -25,20 +25,19 @@ using namespace std; -// token types -const char END = 0; -const char NUMBER = 1; -const char NAME = 2; - - /** Evaluates a given arithmetic expression and returns its value. * The evaluator is implemented as a recursive descent parser. * @param[in] is reads expression from this stream * @return expression value */ -double Calculator::eval (istream &is) { +double Calculator::eval (istream &is) const { double ret = expr(is, false); - if (lookAhead(is) > 0) + try { + // check if expression has been fully evaluated (next token is of type bool) + mpark::get<bool>(lookAhead(is)); + } + catch (mpark::bad_variant_access &e) { throw CalculatorException("expression syntax error"); + } return ret; } @@ -46,7 +45,7 @@ double Calculator::eval (istream &is) { /** Evaluates a given arithmetic expression and returns its value. * @param[in] expr expression to evaluate * @return expression value */ -double Calculator::eval (const string &expr) { +double Calculator::eval (const string &expr) const { istringstream iss; iss.str(expr); return eval(iss); @@ -54,133 +53,150 @@ double Calculator::eval (const string &expr) { /** Evaluates the root rule of the expression grammar. */ -double Calculator::expr (istream &is, bool skip) { // expr: +double Calculator::expr (istream &is, bool skip) const { // expr: double left = term(is, skip); - for (;;) { - switch (lookAhead(is)) { - case '+': left += term(is, true); break; // term '+' term => $1 + $3 - case '-': left -= term(is, true); break; // term '-' term => $1 - $3 - default : return left; // term => $1 + bool ready=false; + while (!ready) { + Token token = lookAhead(is); + char *op = mpark::get_if<char>(&token); + if (!op) + ready = true; + else { + switch (*op) { + case '+': left += term(is, true); break; // term '+' term => $1 + $3 + case '-': left -= term(is, true); break; // term '-' term => $1 - $3 + default : ready = true; + } } } + return left; // term => $1 } -double Calculator::term (istream &is, bool skip) { // term: +double Calculator::term (istream &is, bool skip) const { // term: double left = prim(is, skip); - for (;;) - switch (lookAhead(is)) { - case '*': left *= prim(is, true); break; // prim '*' prim => $1 * $3 - case '(': left *= prim(is, false); break; // prim '*' prim => $1 * $3 - case '/': { // prim '/' prim => $1 / $3 - double denom = prim(is, true); - if (denom == 0) - throw CalculatorException("division by zero"); - left /= denom; - break; + bool ready=false; + while (!ready) { + Token token = lookAhead(is); + char *op = mpark::get_if<char>(&token); + if (!op) + ready = true; + else { + switch (*op) { + case '*': left *= prim(is, true); break; // prim '*' prim => $1 * $3 + case '(': left *= prim(is, false); break; // prim '(' prim => $1 * $3 + case '/': { // prim '/' prim => $1 / $3 + double denom = prim(is, true); + if (denom == 0) + throw CalculatorException("division by zero"); + left /= denom; + break; + } + case '%': { // prim '%' prim => $1 mod $3 + double denom = prim(is, true); + if (denom == 0) + throw CalculatorException("division by zero"); + left -= denom * floor(left / denom); + break; + } + default: + ready = true; } - case '%': { // prim '%' prim => $1 mod $3 - double denom = prim(is, true); - if (denom == 0) - throw CalculatorException("division by zero"); - left -= denom*floor(left/denom); - break; - } - default: // prim => $1 - return left; } + } + return left; } -double Calculator::prim (istream &is, bool skip) { // prim: +/** Evaluates a primary expression of the grammar which doesn't contain any binary operators. */ +double Calculator::prim (istream &is, bool skip) const { // prim: if (skip) lex(is); - switch (lookAhead(is)) { - case NUMBER: { // NUMBER => $1 - lex(is); - double ret = _numValue; - if (lookAhead(is) == NAME) { // NUMBER NAME => $1 * $2 - lex(is); - ret *= getVariable(_strValue); + Token token = lookAhead(is); + if (mpark::get_if<double>(&token)) { // NUMBER => $1 + double ret = mpark::get<double>(lex(is)); + token = lookAhead(is); + if (mpark::get_if<string>(&token)) // NUMBER STRING => $1 * $2 + ret *= getVariable(mpark::get<string>(lex(is))); + return ret; + } + if (mpark::get_if<string>(&token)) // STRING => getVariable($1) + return getVariable(mpark::get<string>(lex(is))); + if (char *op = mpark::get_if<char>(&token)) { + switch (*op) { + case '-': // '-' prim => -$2 + return -prim(is, true); + case '(': { // '(' expr ')' => $2 + double e = expr(is, true); + try { + if (mpark::get<char>(lookAhead(is)) != ')') + throw CalculatorException("')' expected"); + } + catch (mpark::bad_variant_access &e) { + throw CalculatorException("')' expected"); + } + is.get(); // skip processed char + return e; } - return ret; - } - case NAME: { // NAME => getVariable($1) - lex(is); - return getVariable(_strValue); - } - case '-': // '-' prim => -$2 - return -prim(is, true); - case '(': { // '(' expr ')' => $2 - double e = expr(is, true); - if (lookAhead(is) != ')') - throw CalculatorException("')' expected"); - lex(is); - return e; } - default: - throw CalculatorException("primary expression expected"); } + throw CalculatorException("primary expression expected"); +} + + +/** Returns the value of a previously defined variable. If there + * is no variable of the given name, a CalculatorException is thrown. + * @param[in] name name of variable + * @return assigned value */ +double Calculator::getVariable (const string &name) const { + auto it = _variables.find(name); + if (it == _variables.end()) + throw CalculatorException("undefined variable '" + name + "'"); + return it->second; } -/** Determines type of next token without swallowing it. That means - * the same token will be read again next time. */ -char Calculator::lookAhead (istream &is) { +/** Determines the type of the next token without swallowing it. That means + * the same token will be read again next time. The value of the returned token + * object is only set for character tokens and should be considered undefined + * for the other types. */ +Calculator::Token Calculator::lookAhead (istream &is) { is >> ws; int c = is.peek(); if (is.eof()) - return END; + return false; if (isdigit(c) || c == '.') - return NUMBER; + return double(0); if (isalpha(c)) - return NAME; + return string(); return char(c); } -/** Reads next token and returns its type. The token value is either assigned - * to the object members numValue or strValue depending on the type. The token - * type is represented by a unique integer. In contrast to method 'lookAhead' - * lex consumes the read token. +/** Reads and swallows the next token. The returned Token object is represented by + * a variant and thus contains both its type and value. * @param[in] is next token is read from this stream - * @return token type */ -char Calculator::lex (istream &is) { - int tokenType = lookAhead(is); - switch (tokenType) { - case NUMBER: { - string str; - while (isdigit(is.peek()) || is.peek() == '.') - str += char(is.get()); - try { - _numValue = stod(str); - } - catch (const exception&) { - throw CalculatorException("invalid number: "+str); - } - break; + * @return the read token */ +Calculator::Token Calculator::lex (istream &is) { + Token token = lookAhead(is); + if (mpark::get_if<char>(&token)) + is.get(); // token already contains the value from look ahead + else if (mpark::get_if<double>(&token)) { + string str; + while (isdigit(is.peek()) || is.peek() == '.') + str += char(is.get()); + try { + token.emplace<double>(stod(str)); } - case NAME: { - _strValue.clear(); - while (isalpha(is.peek())) - _strValue += char(is.get()); - break; + catch (const exception&) { + throw CalculatorException("invalid number: "+str); } - default: - tokenType = is.get(); } - return char(tokenType); -} - - -/** Returns the value of a previously defined variable. If there - * is no variable of the given name, a CalculatorException is thrown. - * @param[in] name name of variable - * @return assigned value */ -double Calculator::getVariable (const string &name) const { - auto it = _variables.find(name); - if (it == _variables.end()) - throw CalculatorException("undefined variable '" + name + "'"); - return it->second; + else if (mpark::get_if<string>(&token)) { + string name; + while (isalpha(is.peek())) + name += char(is.get()); + token.emplace<string>(name); + } + return token; } - diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Calculator.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Calculator.hpp index 92ec4e40b1e..50f8fb959cc 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Calculator.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Calculator.hpp @@ -2,7 +2,7 @@ ** Calculator.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -24,31 +24,31 @@ #include <istream> #include <map> #include <string> +#include <mpark/variant.hpp> #include "MessageException.hpp" - struct CalculatorException : public MessageException { explicit CalculatorException (const std::string &msg) : MessageException(msg) {} }; class Calculator { public: - double eval (std::istream &is); - double eval (const std::string &expr); + double eval (std::istream &is) const; + double eval (const std::string &expr) const; void setVariable (const std::string &name, double value) {_variables[name] = value;} double getVariable (const std::string &name) const; protected: - double expr (std::istream &is, bool skip); - double term (std::istream &is, bool skip); - double prim (std::istream &is, bool skip); - char lex (std::istream &is); - char lookAhead (std::istream &is); + double expr (std::istream &is, bool skip) const; + double term (std::istream &is, bool skip) const; + double prim (std::istream &is, bool skip) const; + + using Token = mpark::variant<bool, char, double, std::string>; + static Token lex (std::istream &is); + static Token lookAhead (std::istream &is); private: std::map<std::string,double> _variables; - double _numValue=0; - std::string _strValue; }; #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CharMapID.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CharMapID.cpp index 9c56afc73aa..0020b38d047 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CharMapID.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CharMapID.cpp @@ -2,7 +2,7 @@ ** CharMapID.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CharMapID.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CharMapID.hpp index ed044a9cf37..8b8890bc3ab 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CharMapID.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CharMapID.hpp @@ -2,7 +2,7 @@ ** CharMapID.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Character.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Character.hpp index 667a583100d..1e381f93111 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Character.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Character.hpp @@ -2,7 +2,7 @@ ** Character.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Color.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Color.cpp index bf9a05d7a30..60107be9de4 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Color.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Color.cpp @@ -2,7 +2,7 @@ ** Color.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Color.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Color.hpp index 6f6f812207f..061e3e1236a 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Color.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Color.hpp @@ -2,7 +2,7 @@ ** Color.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.cpp index 2cacf829922..fed3a985f47 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.cpp @@ -2,7 +2,7 @@ ** ColorSpecialHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.hpp index eeab300f470..0d90283503d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.hpp @@ -2,7 +2,7 @@ ** ColorSpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.hpp index 7ea6ddd76e2..c4a215b301d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.hpp @@ -2,7 +2,7 @@ // It is part of the dvisvgm package and published under the terms // of the GNU General Public License version 3, or (at your option) any later version. // See file COPYING for further details. -// Copyright (C) 2016-2020 Martin Gieseking <martin.gieseking@uos.de> +// Copyright (C) 2016-2021 Martin Gieseking <martin.gieseking@uos.de> #ifndef COMMANDLINE_HPP #define COMMANDLINE_HPP @@ -20,7 +20,7 @@ class CommandLine : public CL::CommandLine { CommandLine () : CL::CommandLine( "This program converts DVI files, as created by TeX/LaTeX, as well as\nEPS and PDF files to the XML-based scalable vector graphics format SVG.", "[options] dvifile\n--eps [options] epsfile\n--pdf [options] pdffile", - "Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de>" + "Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de>" ) {} CommandLine (int argc, char **argv) : CommandLine() { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.cpp index 9a974e89d99..064368c24a7 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.cpp @@ -2,7 +2,7 @@ ** DLLoader.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.hpp index 469fd1c4aa0..558c27d0c3f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DLLoader.hpp @@ -2,7 +2,7 @@ ** DLLoader.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIActions.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIActions.hpp index 31ea693477e..f51120ab772 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIActions.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIActions.hpp @@ -2,7 +2,7 @@ ** DVIActions.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp index 417efe9304d..05d87b89086 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp @@ -2,7 +2,7 @@ ** DVIReader.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -19,8 +19,6 @@ *************************************************************************/ #include <algorithm> -#include <cstdarg> -#include <fstream> #include <sstream> #include "Color.hpp" #include "DVIActions.hpp" @@ -28,27 +26,20 @@ #include "Font.hpp" #include "FontManager.hpp" #include "HashFunction.hpp" +#include "JFM.hpp" +#include "utility.hpp" #include "VectorStream.hpp" using namespace std; DVIReader::DVIReader (istream &is) : BasicDVIReader(is) { - _inPage = false; - _dvi2bp = 0.0; - _inPostamble = false; - _currFontNum = 0; - _currPageNum = 0; - _mag = 1; executePreamble(); - collectBopOffsets(); - executePostamble(); -} - - -int DVIReader::executeCommand () { - int opcode = BasicDVIReader::executeCommand(); - return opcode; + _bopOffsets = collectBopOffsets(); + // read data from postamble but don't process font definitions + goToPostamble(); + executeCommand(); + executePostPost(); } @@ -79,75 +70,12 @@ bool DVIReader::executePage (unsigned n) { return false; seek(_bopOffsets[n-1]); // goto bop of n-th page - _inPostamble = false; // not in postamble _currPageNum = n; while (executeCommand() != OP_EOP); return true; } -void DVIReader::executePreamble () { - clearStream(); - if (isStreamValid()) { - seek(0); - if (readByte() == OP_PRE) { - cmdPre(0); - return; - } - } - throw DVIException("invalid DVI file"); -} - - -/** Moves stream pointer to begin of postamble */ -void DVIReader::goToPostamble () { - clearStream(); - if (!isStreamValid()) - throw DVIException("invalid DVI file"); - - seek(-1, ios::end); // stream pointer to last byte - int count=0; - while (peek() == DVI_FILL) { // skip fill bytes - seek(-1, ios::cur); - count++; - } - if (count < 4) // the standard requires at least 4 trailing fill bytes - throw DVIException("missing fill bytes at end of file"); - - seek(-4, ios::cur); // now at first byte of q (pointer to begin of postamble) - uint32_t q = readUnsigned(4); // pointer to begin of postamble - seek(q); // now at begin of postamble -} - - -/** Reads and executes the commands of the postamble. */ -void DVIReader::executePostamble () { - goToPostamble(); - while (executeCommand() != OP_POSTPOST); // executes all commands until post_post (= 249) is reached -} - - -/** Collects and records the file offsets of all bop commands. */ -void DVIReader::collectBopOffsets () { - goToPostamble(); - _bopOffsets.push_back(tell()); // also add offset of postamble - readByte(); // skip post command - uint32_t offset = readUnsigned(4); // offset of final bop - while (int32_t(offset) != -1) { // not yet on first bop? - _bopOffsets.push_back(offset); // record offset - seek(offset); // now on previous bop - if (readByte() != OP_BOP) - throw DVIException("bop offset at "+to_string(offset)+" doesn't point to bop command" ); - seek(40, ios::cur); // skip the 10 \count values => now on offset of previous bop - uint32_t prevOffset = readUnsigned(4); - if ((prevOffset >= offset && int32_t(prevOffset) != -1)) - throw DVIException("invalid bop offset at "+to_string(tell()-static_cast<streamoff>(4))); - offset = prevOffset; - } - reverse(_bopOffsets.begin(), _bopOffsets.end()); -} - - /** Computes a hash value for a given page. The hash algorithm is selected by * a HashFunction object which will also contain the resulting hash value if * this function returns true. @@ -213,7 +141,6 @@ void DVIReader::cmdPost (int) { // 1 dviunit * num/den == multiples of 0.0000001m // 1 dviunit * _dvi2bp: length of 1 dviunit in PS points * _mag/1000 _dvi2bp = numer/254000.0*72.0/denom*_mag/1000.0; - _inPostamble = true; dviPost(stackDepth, numPages, pageWidth*_dvi2bp, pageHeight*_dvi2bp, _mag, numer, denom, prevBopOffset); } @@ -221,7 +148,6 @@ void DVIReader::cmdPost (int) { /** Reads and executes DVI post_post command. * Format: post_post q[4] i[1] 223[>=4] */ void DVIReader::cmdPostPost (int) { - _inPostamble = false; uint32_t postOffset = readUnsigned(4); // pointer to begin of postamble uint8_t id = readUnsigned(1); setDVIVersion(DVIVersion(id)); // identification byte @@ -278,16 +204,22 @@ void DVIReader::cmdPop (int) { * @param[in] c character to typeset */ void DVIReader::putVFChar (Font *font, uint32_t c) { if (auto vf = dynamic_cast<VirtualFont*>(font)) { // is current font a virtual font? - if (const vector<uint8_t> *dvi = vf->getDVI(c)) { // try to get DVI snippet that represents character c - FontManager &fm = FontManager::instance(); - DVIState savedState = _dviState; // save current cursor position - _dviState.x = _dviState.y = _dviState.w = _dviState.z = 0; - int savedFontNum = _currFontNum; // save current font number - fm.enterVF(vf); // enter VF font number context - setFont(fm.vfFirstFontNum(vf), SetFontMode::VF_ENTER); - double savedScale = _dvi2bp; + FontManager &fm = FontManager::instance(); + const vector<uint8_t> *dvi = vf->getDVI(c); // try to get DVI snippet that represents character c + Font *firstFont = fm.vfFirstFont(vf); + if (!dvi && (!firstFont || !dynamic_cast<const JFM*>(firstFont->getMetrics()))) + return; + fm.enterVF(vf); // enter VF font number context + int savedFontNum = _currFontNum; // save current font number + setFont(fm.vfFirstFontNum(vf), SetFontMode::VF_ENTER); + if (!dvi) // no definition present for current (Japanese) char? + dviPutChar(c, firstFont); // fallback for JFM-based virtual fonts + else { // DVI units in virtual fonts are multiples of 1^(-20) times the scaled size of the VF + double savedScale = _dvi2bp; _dvi2bp = vf->scaledSize()/(1 << 20); + DVIState savedState = _dviState; // save current cursor position + _dviState.x = _dviState.y = _dviState.w = _dviState.z = 0; VectorInputStream<uint8_t> vis(*dvi); istream &is = replaceStream(vis); try { @@ -296,12 +228,12 @@ void DVIReader::putVFChar (Font *font, uint32_t c) { catch (const DVIException &e) { // Message::estream(true) << "invalid dvi in vf: " << e.getMessage() << endl; // @@ } - replaceStream(is); // restore previous input stream - _dvi2bp = savedScale; // restore previous scale factor - fm.leaveVF(); // restore previous font number context - setFont(savedFontNum, SetFontMode::VF_LEAVE); // restore previous font number + replaceStream(is); // restore previous input stream _dviState = savedState; // restore previous cursor position + _dvi2bp = savedScale; // restore previous scale factor } + fm.leaveVF(); // restore previous font number context + setFont(savedFontNum, SetFontMode::VF_LEAVE); // restore previous font number } } @@ -504,26 +436,64 @@ void DVIReader::cmdFontNum (int len) { } +/** Parses a sequence of font attributes given as key1=val1;key2=val2;...;keyn=valn */ +static map<string,string> parse_font_attribs (const string &str) { + map<string,string> attribs; + if (!str.empty()) { + for (const string &attr : util::split(str, ";")) { + vector<string> keyval = util::split(attr, "="); + if (keyval.size() == 2) + attribs[keyval[0]] = keyval[1]; + } + } + return attribs; +} + + /** Helper function to handle a font definition. * @param[in] fontnum local font number - * @param[in] name font name + * @param[in] name font name (or file path if enclosed in square brackets) * @param[in] cs checksum to be compared with TFM checksum - * @param[in] ds design size in PS point units - * @param[in] ss scaled size in PS point units */ -const Font* DVIReader::defineFont (uint32_t fontnum, const string &name, uint32_t cs, double ds, double ss) { + * @param[in] dsize design size of font in PS point units + * @param[in] ssize scaled size of font in PS point units */ +const Font* DVIReader::defineFont (uint32_t fontnum, const string &name, uint32_t cs, double dsize, double ssize) { FontManager &fm = FontManager::instance(); Font *font = fm.getFont(fontnum); - if (!font) { - int id = fm.registerFont(fontnum, name, cs, ds, ss); - font = fm.getFontById(id); - if (auto vf = dynamic_cast<VirtualFont*>(font)) { - // read vf file, register its font and character definitions - fm.enterVF(vf); - ifstream ifs(vf->path(), ios::binary); - VFReader vfReader(ifs); - vfReader.replaceActions(this); - vfReader.executeAll(); - fm.leaveVF(); + if (!font && !name.empty()) { // font not registered yet? + if (name[0] == '[') { // LuaTeX native font reference? + size_t last = name.rfind(']'); + if (last != string::npos) { + string path = name.substr(1, last-1); + FontStyle style; + int fontIndex=0; + if (name.size() > last && name[last+1] == ':') { // look for font attributes? + auto attribs = parse_font_attribs(name.substr(last+2)); + auto it = attribs.begin(); + if ((it = attribs.find("index")) != attribs.end()) + fontIndex = stoi(it->second); + if ((it = attribs.find("embolden")) != attribs.end()) + style.bold = stoi(it->second)/65536.0; + if ((it = attribs.find("extend")) != attribs.end()) + style.extend = stoi(it->second)/65536.0; + if ((it = attribs.find("slant")) != attribs.end()) + style.slant = stoi(it->second)/65536.0; + } + int id = fm.registerFont(fontnum, path, fontIndex, ssize, style, Color::BLACK); + font = fm.getFontById(id); + } + } + else { // TFM-based font specified by name + int id = fm.registerFont(fontnum, name, cs, dsize, ssize); + font = fm.getFontById(id); + if (auto vf = dynamic_cast<VirtualFont*>(font)) { + // read vf file, register its font and character definitions + fm.enterVF(vf); + ifstream ifs(vf->path(), ios::binary); + VFReader vfReader(ifs); + vfReader.replaceActions(this); + vfReader.executeAll(); + fm.leaveVF(); + } } } return font; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.hpp index fc1424aca31..ff8390f5150 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.hpp @@ -2,7 +2,7 @@ ** DVIReader.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -53,10 +53,7 @@ class DVIReader : public BasicDVIReader, public VFActions { explicit DVIReader (std::istream &is); bool executeDocument (); void executeAll (); - void executePreamble (); - void executePostamble (); bool executePage (unsigned n); - bool inPostamble () const {return _inPostamble;} double getXPos () const override {return _dviState.h;} double getYPos () const override {return _dviState.v;} int stackDepth () const override {return _stateStack.size();} @@ -65,16 +62,13 @@ class DVIReader : public BasicDVIReader, public VFActions { unsigned numberOfPages () const {return _bopOffsets.empty() ? 0 : _bopOffsets.size()-1;} protected: - int executeCommand () override; - void collectBopOffsets (); size_t numberOfPageBytes (int n) const {return _bopOffsets.size() > 1 ? _bopOffsets[n+1]-_bopOffsets[n] : 0;} bool computePageHash (size_t pageno, HashFunction &hashFunc); - void goToPostamble (); virtual void moveRight (double dx, MoveMode mode); virtual void moveDown (double dy, MoveMode mode); void putVFChar (Font *font, uint32_t c); double putGlyphArray (bool xonly, std::vector<double> &dx, std::vector<double> &dy, std::vector<uint16_t> &glyphs); - const Font* defineFont (uint32_t fontnum, const std::string &name, uint32_t cs, double ds, double ss); + const Font* defineFont (uint32_t fontnum, const std::string &name, uint32_t cs, double dsize, double ssize); void setFont (int num, SetFontMode mode); const DVIState& dviState() const {return _dviState;} double dvi2bp () const {return _dvi2bp;} @@ -160,13 +154,12 @@ class DVIReader : public BasicDVIReader, public VFActions { void cmdXTextAndGlyphs (int len) override; private: - bool _inPage; ///< true if stream pointer is between bop and eop - unsigned _currPageNum; ///< current page number (1 is first page) - int _currFontNum; ///< current font number - double _dvi2bp; ///< factor to convert dvi units to PS points - uint32_t _mag; ///< magnification factor * 1000 - bool _inPostamble; ///< true if stream pointer is inside the postamble - DVIState _dviState; ///< current state of the DVI registers + bool _inPage=false; ///< true if stream pointer is between bop and eop + unsigned _currPageNum=0; ///< current page number (1 is first page) + int _currFontNum=0; ///< current font number + double _dvi2bp=0.0; ///< factor to convert dvi units to PS points + uint32_t _mag=1; ///< magnification factor * 1000 + DVIState _dviState; ///< current state of the DVI registers std::stack<DVIState> _stateStack; std::vector<uint32_t> _bopOffsets; }; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp index 7280495e834..c2defd06fe9 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp @@ -2,7 +2,7 @@ ** DVIToSVG.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -169,6 +169,7 @@ void DVIToSVG::convert (const string &rangestr, pair<int,int> *pageinfo) { prescan.executeAllPages(); actions->setDVIReader(*this); SpecialManager::instance().notifyPreprocessingFinished(); + executeFontDefs(); } unique_ptr<HashFunction> hashFunc; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.hpp index 1bafa7cb3d8..45c957e0868 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.hpp @@ -2,7 +2,7 @@ ** DVIToSVG.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp index 6239be3b01b..b44843c6bf3 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.cpp @@ -2,7 +2,7 @@ ** DVIToSVGActions.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -122,7 +122,7 @@ void DVIToSVGActions::setChar (double x, double y, unsigned c, bool vertical, co bbox.transform(getMatrix()); embed(bbox); #if 0 - XMLElement *rect = new XMLElement("rect"); + auto rect = util::make_unique<XMLElement>("rect"); rect->addAttribute("x", x-metrics.wl); rect->addAttribute("y", y-metrics.h); rect->addAttribute("width", metrics.wl+metrics.wr); @@ -130,26 +130,26 @@ void DVIToSVGActions::setChar (double x, double y, unsigned c, bool vertical, co rect->addAttribute("fill", "none"); rect->addAttribute("stroke", "red"); rect->addAttribute("stroke-width", "0.5"); - _svg.appendToPage(rect); + _svg.appendToPage(std::move(rect)); if (metrics.d > 0) { - XMLElement *line = new XMLElement("line"); + auto line = util::make_unique<XMLElement>("line"); line->addAttribute("x1", x-metrics.wl); line->addAttribute("y1", y); line->addAttribute("x2", x+metrics.wr); line->addAttribute("y2", y); line->addAttribute("stroke", "blue"); line->addAttribute("stroke-width", "0.5"); - _svg.appendToPage(line); + _svg.appendToPage(std::move(line)); } if (metrics.wl > 0) { - XMLElement *line = new XMLElement("line"); + auto line = util::make_unique<XMLElement>("line"); line->addAttribute("x1", x); line->addAttribute("y1", y-metrics.h); line->addAttribute("x2", x); line->addAttribute("y2", y+metrics.d); line->addAttribute("stroke", "blue"); line->addAttribute("stroke-width", "0.5"); - _svg.appendToPage(line); + _svg.appendToPage(std::move(line)); } #endif } @@ -227,7 +227,12 @@ void DVIToSVGActions::beginPage (unsigned pageno, const vector<int32_t>&) { /** This method is called when an "end of page (eop)" command was found in the DVI file. */ void DVIToSVGActions::endPage (unsigned pageno) { - SpecialManager::instance().notifyEndPage(pageno, *this); + try { + SpecialManager::instance().notifyEndPage(pageno, *this); + } + catch (const SpecialException &e) { + Message::estream(true) << "error in special: " << e.what() << '\n'; + } Matrix matrix = _dvireader->getPageTransformation(); _svg.transformPage(matrix); if (_bgcolor != Color::TRANSPARENT) { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.hpp index 2ae3fb9a2e2..ed8a5f9c9b5 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVGActions.hpp @@ -2,7 +2,7 @@ ** DVIToSVGActions.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.cpp index e7200a0dc36..224165e2556 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.cpp @@ -2,7 +2,7 @@ ** Directory.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.hpp index d617b4fcbd0..14360a9f670 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Directory.hpp @@ -2,7 +2,7 @@ ** Directory.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp index 1f331659f03..67463a4c597 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp @@ -2,7 +2,7 @@ ** DvisvgmSpecialHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -209,7 +209,9 @@ static void evaluate_expressions (string &str, SpecialActions &actions) { else { try { double val = calc.eval(expr); - str.replace(left, right-left+2, XMLString(val)); + XMLString valstr(val); + str.replace(left, right-left+2, valstr); + right = left+valstr.length()-1; } catch (CalculatorException &e) { throw SpecialException(string(e.what())+" in '{?("+expr+")}'"); @@ -413,8 +415,8 @@ void DvisvgmSpecialHandler::dviPreprocessingFinished () { void DvisvgmSpecialHandler::dviEndPage (unsigned, SpecialActions &actions) { - _defsParser.flush(actions); - _pageParser.flush(actions); + _defsParser.finish(actions); + _pageParser.finish(actions); actions.bbox().unlock(); for (auto &strvecpair : _macros) { StringVector &vec = strvecpair.second; @@ -437,8 +439,8 @@ vector<const char*> DvisvgmSpecialHandler::prefixes() const { /** Parses a fragment of XML code, creates corresponding XML nodes and adds them * to the SVG tree. The code may be split and processed by several calls of this * function. Incomplete chunks that can't be processed yet are stored and picked - * up again together with the next incoming XML fragment. If no further code should - * be appended, parameter 'finish' must be set. + * up again together with the next incoming XML fragment. If a call of this function + * is supposed to finish the parsing of an XML subtree, parameter 'finish' must be set. * @param[in] xml XML fragment to parse * @param[in] actions object providing the SVG tree functions * @param[in] finish if true, no more XML is expected and parsing is finished */ @@ -447,59 +449,65 @@ void DvisvgmSpecialHandler::XMLParser::parse (const string &xml, SpecialActions // incomplete tags are held back _xmlbuf += xml; size_t left=0, right; - while (left != string::npos) { - right = _xmlbuf.find('<', left); - if (left < right && left < _xmlbuf.length()) // plain text found? - (actions.svgTree().*_append)(util::make_unique<XMLText>(_xmlbuf.substr(left, right-left))); - if (right != string::npos) { - left = right; - if (_xmlbuf.compare(left, 9, "<![CDATA[") == 0) { - right = _xmlbuf.find("]]>", left+9); - if (right == string::npos) { - if (finish) throw SpecialException("expected ']]>' at end of CDATA block"); - break; + try { + while (left != string::npos) { + right = _xmlbuf.find('<', left); + if (left < right && left < _xmlbuf.length()) // plain text found? + (actions.svgTree().*_append)(util::make_unique<XMLText>(_xmlbuf.substr(left, right-left))); + if (right != string::npos) { + left = right; + if (_xmlbuf.compare(left, 9, "<![CDATA[") == 0) { + right = _xmlbuf.find("]]>", left+9); + if (right == string::npos) { + if (finish) throw SpecialException("expected ']]>' at end of CDATA block"); + break; + } + (actions.svgTree().*_append)(util::make_unique<XMLCData>(_xmlbuf.substr(left+9, right-left-9))); + right += 2; } - (actions.svgTree().*_append)(util::make_unique<XMLCData>(_xmlbuf.substr(left+9, right-left-9))); - right += 2; - } - else if (_xmlbuf.compare(left, 4, "<!--") == 0) { - right = _xmlbuf.find("-->", left+4); - if (right == string::npos) { - if (finish) throw SpecialException("expected '-->' at end of comment"); - break; + else if (_xmlbuf.compare(left, 4, "<!--") == 0) { + right = _xmlbuf.find("-->", left+4); + if (right == string::npos) { + if (finish) throw SpecialException("expected '-->' at end of comment"); + break; + } + (actions.svgTree().*_append)(util::make_unique<XMLComment>(_xmlbuf.substr(left+4, right-left-4))); + right += 2; } - (actions.svgTree().*_append)(util::make_unique<XMLComment>(_xmlbuf.substr(left+4, right-left-4))); - right += 2; - } - else if (_xmlbuf.compare(left, 2, "<?") == 0) { - right = _xmlbuf.find("?>", left+2); - if (right == string::npos) { - if (finish) throw SpecialException("expected '?>' at end of processing instruction"); - break; + else if (_xmlbuf.compare(left, 2, "<?") == 0) { + right = _xmlbuf.find("?>", left+2); + if (right == string::npos) { + if (finish) throw SpecialException("expected '?>' at end of processing instruction"); + break; + } + (actions.svgTree().*_append)(util::make_unique<XMLText>(_xmlbuf.substr(left, right-left+2))); + right++; } - (actions.svgTree().*_append)(util::make_unique<XMLText>(_xmlbuf.substr(left, right-left+2))); - right++; - } - else if (_xmlbuf.compare(left, 2, "</") == 0) { - right = _xmlbuf.find('>', left+2); - if (right == string::npos) { - if (finish) throw SpecialException("missing '>' at end of closing XML tag"); - break; + else if (_xmlbuf.compare(left, 2, "</") == 0) { + right = _xmlbuf.find('>', left+2); + if (right == string::npos) { + if (finish) throw SpecialException("missing '>' at end of closing XML tag"); + break; + } + closeElement(_xmlbuf.substr(left+2, right-left-2), actions); } - closeElement(_xmlbuf.substr(left+2, right-left-2), actions); - } - else { - right = _xmlbuf.find('>', left+1); - if (right == string::npos) { - if (finish) throw SpecialException("missing '>' or '/>' at end of opening XML tag"); - break; + else { + right = _xmlbuf.find('>', left+1); + if (right == string::npos) { + if (finish) throw SpecialException("missing '>' or '/>' at end of opening XML tag"); + break; + } + openElement(_xmlbuf.substr(left+1, right-left-1), actions); } - openElement(_xmlbuf.substr(left+1, right-left-1), actions); } + left = right; + if (right != string::npos) + left++; } - left = right; - if (right != string::npos) - left++; + } + catch (const SpecialException &e) { + _error = true; + throw; } if (left == string::npos) _xmlbuf.clear(); @@ -545,7 +553,7 @@ void DvisvgmSpecialHandler::XMLParser::closeElement (const string &tag, SpecialA if (_nameStack.empty()) throw SpecialException("spurious closing tag </" + name + ">"); if (_nameStack.back() != name) - throw SpecialException("expected </" + name + "> but found </" + _nameStack.back() + ">"); + throw SpecialException("expected </" + _nameStack.back() + "> but found </" + name + ">"); (actions.svgTree().*_popContext)(); _nameStack.pop_back(); } @@ -553,9 +561,10 @@ void DvisvgmSpecialHandler::XMLParser::closeElement (const string &tag, SpecialA /** Processes any remaining XML fragments, checks for missing closing tags, * and resets the parser state. */ -void DvisvgmSpecialHandler::XMLParser::flush (SpecialActions &actions) { +void DvisvgmSpecialHandler::XMLParser::finish (SpecialActions &actions) { if (!_xmlbuf.empty()) { - parse("", actions, true); + if (!_error) + parse("", actions, true); _xmlbuf.clear(); } string tags; @@ -563,8 +572,8 @@ void DvisvgmSpecialHandler::XMLParser::flush (SpecialActions &actions) { tags += "</"+_nameStack.back()+">, "; _nameStack.pop_back(); } - if (!tags.empty()) { + if (!tags.empty() && !_error) { tags.resize(tags.length()-2); - throw SpecialException("missing closing tags: "+tags); + throw SpecialException("missing closing tag(s): "+tags); } } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.hpp index 0f73c73ecd1..f90c283429c 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.hpp @@ -2,7 +2,7 @@ ** DvisvgmSpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -53,7 +53,7 @@ class DvisvgmSpecialHandler : public SpecialHandler { : _append(append), _pushContext(push), _popContext(pop) {} void parse (const std::string &xml, SpecialActions &actions, bool finish=false); - void flush (SpecialActions &actions); + void finish (SpecialActions &actions); protected: void openElement (const std::string &tag, SpecialActions &actions); @@ -65,6 +65,7 @@ class DvisvgmSpecialHandler : public SpecialHandler { PopFunc _popContext; std::string _xmlbuf; NameStack _nameStack; ///< names of nested elements still missing a closing tag + bool _error=false; }; using StringVector = std::vector<std::string>; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSFile.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSFile.cpp index 1a19c07cc76..2f61f9f07dc 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSFile.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSFile.cpp @@ -2,7 +2,7 @@ ** EPSFile.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSFile.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSFile.hpp index 7b02db95b19..384af7225ee 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSFile.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSFile.hpp @@ -2,7 +2,7 @@ ** EPSFile.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.hpp index 64f5ac604dd..75a574cf38b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.hpp @@ -2,7 +2,7 @@ ** EPSToSVG.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EllipticalArc.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/EllipticalArc.cpp index a151c513070..bfb3dffd7ed 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EllipticalArc.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/EllipticalArc.cpp @@ -2,7 +2,7 @@ ** EllipticalArc.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EllipticalArc.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/EllipticalArc.hpp index 422a40b207e..78785c4ff12 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EllipticalArc.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/EllipticalArc.hpp @@ -2,7 +2,7 @@ ** EllipticalArc.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp index efbd7abef38..95dc58a4ec4 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp @@ -2,7 +2,7 @@ ** EmSpecialHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.hpp index e20339e548a..fc9f14a4689 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.hpp @@ -2,7 +2,7 @@ ** EmSpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EncFile.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/EncFile.cpp index ce0f18d81e5..d08791c03ea 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EncFile.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/EncFile.cpp @@ -2,7 +2,7 @@ ** EncFile.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EncFile.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/EncFile.hpp index 8f2b14c430f..0e5f90bcb34 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EncFile.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/EncFile.hpp @@ -2,7 +2,7 @@ ** EncFile.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp index a52ccd37d3f..3358d5c273c 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp @@ -2,7 +2,7 @@ ** FileFinder.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FileFinder.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FileFinder.hpp index 7218bf6c0b0..5774f8165ce 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FileFinder.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FileFinder.hpp @@ -2,7 +2,7 @@ ** FileFinder.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.cpp index 2150cf31f79..a8e6a258a1e 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.cpp @@ -2,7 +2,7 @@ ** FilePath.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.hpp index e9d55562c5b..af81db66f45 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FilePath.hpp @@ -2,7 +2,7 @@ ** FilePath.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp index a1fafbdeceb..476c0c8e58e 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp @@ -2,7 +2,7 @@ ** FileSystem.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -20,12 +20,14 @@ #include <config.h> #include <algorithm> +#include <chrono> #include <cstdlib> #include <cstring> #include <fstream> #include "FileSystem.hpp" #include "utility.hpp" #include "version.hpp" +#include "XXHashFunction.hpp" #ifdef HAVE_UNISTD_H #include <unistd.h> @@ -51,7 +53,7 @@ using namespace std; string FileSystem::TMPDIR; -const char *FileSystem::TMPSUBDIR = nullptr; +FileSystem::TemporaryDirectory FileSystem::_tmpdir; /** Private wrapper function for mkdir: creates a single folder. @@ -79,13 +81,6 @@ static bool inline s_rmdir (const string &dirname) { } -FileSystem::~FileSystem () { - // remove the subdirectory from the system's temp folder (if empty) - if (TMPSUBDIR) - s_rmdir(tmpdir()); -} - - bool FileSystem::remove (const string &fname) { return unlink(fname.c_str()) == 0; } @@ -192,36 +187,29 @@ const char* FileSystem::userdir () { /** Returns the path of the temporary folder. */ string FileSystem::tmpdir () { - string ret; - if (!TMPDIR.empty()) - ret = TMPDIR; - else { + if (_tmpdir.path().empty()) { + string basedir; + if (!TMPDIR.empty()) + basedir = TMPDIR; + else { #ifdef _WIN32 - char buf[MAX_PATH]; - if (GetTempPath(MAX_PATH, buf)) - ret = ensureForwardSlashes(buf); - else - ret = "."; + char buf[MAX_PATH]; + if (GetTempPath(MAX_PATH, buf)) + basedir = ensureForwardSlashes(buf); + else + basedir = "."; #else - if (const char *path = getenv("TMPDIR")) - ret = path; - else - ret = "/tmp"; + if (const char *path = getenv("TMPDIR")) + basedir = path; + else + basedir = "/tmp"; #endif - if (ret.back() == '/') - ret.pop_back(); - static bool initialized=false; - if (!initialized && ret != ".") { - TMPSUBDIR = PROGRAM_NAME; - s_mkdir(ret + "/" + TMPSUBDIR); - initialized = true; + if (basedir.back() == '/') + basedir.pop_back(); } - if (TMPSUBDIR) - ret += string("/") + TMPSUBDIR; + _tmpdir = TemporaryDirectory(basedir, PROGRAM_NAME); } - if (!ret.empty() && ret.back() != '/') - ret += '/'; - return ret; + return _tmpdir.path(); } @@ -368,3 +356,33 @@ int FileSystem::collect (const std::string &dirname, vector<string> &entries) { #endif return entries.size(); } + + +/** Creates a temporary directory in a given folder. + * @param[in] folder folder path in which the directory is to be created + * @param[in] prefix initial string of the directory name */ +FileSystem::TemporaryDirectory::TemporaryDirectory (const std::string &folder, string prefix) { + using namespace std::chrono; + auto now = system_clock::now().time_since_epoch(); + auto now_ms = duration_cast<milliseconds>(now).count(); + auto hash = XXH64HashFunction(to_string(now_ms)).digestValue(); + if (!prefix.empty() && prefix.back() != '-') + prefix += "-"; + for (int i=0; i < 10 && _path.empty(); i++) { + hash++; + stringstream oss; + oss << folder << '/' << prefix << hex << hash; + if (exists(oss.str())) + continue; + if (s_mkdir(oss.str())) + _path = oss.str() + "/"; + else + break; + } +} + + +FileSystem::TemporaryDirectory::~TemporaryDirectory () { + if (!_path.empty()) + s_rmdir(_path); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FileSystem.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FileSystem.hpp index f82ff1e8709..ad0e70f9737 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FileSystem.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FileSystem.hpp @@ -2,7 +2,7 @@ ** FileSystem.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -25,8 +25,23 @@ #include <vector> class FileSystem { + class TemporaryDirectory { + friend class FileSystem; + public: + TemporaryDirectory (const std::string &folder, std::string prefix); + TemporaryDirectory (TemporaryDirectory &&tmpdir) =default; + ~TemporaryDirectory (); + TemporaryDirectory& operator = (TemporaryDirectory &&tmpdir) =default; + const std::string& path () const {return _path;} + + protected: + TemporaryDirectory () =default; + + private: + std::string _path; + }; + public: - ~FileSystem (); static bool remove (const std::string &fname); static bool rename (const std::string &oldname, const std::string &newname); static bool copy (const std::string &src, const std::string &dest, bool remove_src=false); @@ -48,8 +63,9 @@ class FileSystem { protected: FileSystem () =default; - bool system_tmpdir_available (); - static const char* TMPSUBDIR; ///< subdirectory of the system's temporary folder + + private: + static TemporaryDirectory _tmpdir; }; #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FixWord.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FixWord.hpp index 3414e1ead4b..b6166b15dca 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FixWord.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FixWord.hpp @@ -2,7 +2,7 @@ ** FixWord.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp index e40ad8a3929..ff93c81cd0b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.cpp @@ -2,7 +2,7 @@ ** Font.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -495,7 +495,7 @@ const FontEncoding* PhysicalFontImpl::encoding () const { bool PhysicalFontImpl::findAndAssignBaseFontMap () { const FontEncoding *enc = encoding(); - if (enc && enc->mapsToCharIndex()) { + if (enc && !enc->mapsToUnicode() && enc->mapsToCharIndex()) { // try to find a base font map that maps from character indexes to a suitable // target encoding supported by the font file if (const FontEncoding *bfmap = enc->findCompatibleBaseFontMap(this, _charmapID)) @@ -607,8 +607,13 @@ PhysicalFont::Type NativeFont::type () const { double NativeFont::charWidth (int c) const { FontEngine::instance().setFont(*this); int upem = FontEngine::instance().getUnitsPerEM(); - double w = upem ? (scaledSize()*FontEngine::instance().getAdvance(c)/upem*_style.extend) : 0; - w += abs(_style.slant*charHeight(c)); + return upem ? (scaledSize()*FontEngine::instance().getAdvance(c)/upem*_style.extend) : 0; +} + + +double NativeFont::italicCorr(int c) const { + double w = abs(_style.slant*charHeight(c)); // slant := tan(phi) = dx/height + w *= _style.extend; return w; } @@ -631,7 +636,7 @@ bool NativeFontImpl::findAndAssignBaseFontMap () { FontEngine &fe = FontEngine::instance(); fe.setFont(*this); fe.setUnicodeCharMap(); - fe.buildCharMap(_toUnicodeMap); + fe.buildGidToCharCodeMap(_toUnicodeMap); if (!_toUnicodeMap.addMissingMappings(fe.getNumGlyphs())) Message::wstream(true) << "incomplete Unicode mapping for native font " << name() << " (" << filename() << ")\n"; return true; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.hpp index 59556e7a813..0c341b8e69d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Font.hpp @@ -2,7 +2,7 @@ ** Font.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -266,7 +266,7 @@ class NativeFont : public PhysicalFont { double charWidth (int c) const override; double charDepth (int c) const override; double charHeight (int c) const override; - double italicCorr (int c) const override {return 0;} + double italicCorr (int c) const override; const FontMetrics* getMetrics () const override {return nullptr;} const FontStyle* style () const override {return &_style;} Color color () const override {return _color;} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontCache.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontCache.cpp index e024558913f..09a88a2d2a8 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontCache.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontCache.cpp @@ -2,7 +2,7 @@ ** FontCache.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -160,7 +160,7 @@ bool FontCache::write (const string &fontname, ostream &os) const { XXH32HashFunction hashfunc; sw.writeUnsigned(FORMAT_VERSION, 1, hashfunc); - sw.writeBytes(hashfunc.digestValue()); // space for checksum + sw.writeBytes(hashfunc.digestBytes()); // space for checksum sw.writeString(fontname, hashfunc, true); sw.writeUnsigned(_glyphs.size(), 4, hashfunc); WriteActions actions(sw, hashfunc); @@ -171,7 +171,7 @@ bool FontCache::write (const string &fontname, ostream &os) const { glyph.iterate(actions, false); } os.seekp(1); - auto digest = hashfunc.digestValue(); + auto digest = hashfunc.digestBytes(); sw.writeBytes(digest); // insert checksum os.seekp(0, ios::end); return true; @@ -215,7 +215,7 @@ bool FontCache::read (const string &fontname, istream &is) { auto hashcmp = sr.readBytes(hashfunc.digestSize()); hashfunc.update(is); - if (hashfunc.digestValue() != hashcmp) + if (hashfunc.digestBytes() != hashcmp) return false; is.clear(); @@ -309,7 +309,7 @@ bool FontCache::fontinfo (std::istream &is, FontInfo &info) { info.checksum = sr.readBytes(hashfunc.digestSize()); hashfunc.update(is); - if (hashfunc.digestValue() != info.checksum) + if (hashfunc.digestBytes() != info.checksum) return false; is.clear(); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontCache.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontCache.hpp index 8a6025a3d2c..e7bbf36126f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontCache.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontCache.hpp @@ -2,7 +2,7 @@ ** FontCache.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEncoding.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEncoding.cpp index 8f2673f1231..afc221063e5 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEncoding.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEncoding.cpp @@ -2,7 +2,7 @@ ** FontEncoding.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -72,6 +72,15 @@ bool FontEncodingPair::mapsToCharIndex () const { } +bool FontEncodingPair::mapsToUnicode () const { + if (_enc2) + return _enc2->mapsToUnicode(); + if (_enc1) + return _enc1->mapsToUnicode(); + return false; +} + + const FontEncoding* FontEncodingPair::findCompatibleBaseFontMap (const PhysicalFont *font, CharMapID &charmapID) const { if (_enc2) return _enc2->findCompatibleBaseFontMap(font, charmapID); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEncoding.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEncoding.hpp index 1c4a979aa9a..141f4486fe5 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEncoding.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEncoding.hpp @@ -2,7 +2,7 @@ ** FontEncoding.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -32,6 +32,7 @@ struct FontEncoding { virtual ~FontEncoding () =default; virtual Character decode (uint32_t c) const =0; virtual bool mapsToCharIndex () const =0; + virtual bool mapsToUnicode () const {return false;} virtual const FontEncoding* findCompatibleBaseFontMap (const PhysicalFont *font, CharMapID &charmapID) const {return nullptr;} static FontEncoding* encoding (const std::string &encname); }; @@ -49,6 +50,7 @@ class FontEncodingPair : public FontEncoding { FontEncodingPair (const FontEncoding *enc1, const FontEncoding *enc2) : _enc1(enc1), _enc2(enc2) {} Character decode (uint32_t c) const override; bool mapsToCharIndex () const override; + bool mapsToUnicode () const override; const FontEncoding* findCompatibleBaseFontMap (const PhysicalFont *font, CharMapID &charmapID) const override; const FontEncoding* enc1 () const {return _enc1;} const FontEncoding* enc2 () const {return _enc2;} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.cpp index bee1ca886d8..56ae0a9f78c 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.cpp @@ -2,7 +2,7 @@ ** FontEngine.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -131,37 +131,38 @@ bool FontEngine::setCharMap (const CharMapID &charMapID) { } -/** Returns a character map that maps from character indexes to character codes +/** Returns a character map that maps from glyph indexes to character codes * of the current encoding. * @param[out] charmap the resulting charmap */ -void FontEngine::buildCharMap (RangeMap &charmap) { +void FontEngine::buildGidToCharCodeMap (RangeMap &charmap) { charmap.clear(); - FT_UInt glyph_index; - uint32_t charcode = FT_Get_First_Char(_currentFace, &glyph_index); - while (glyph_index) { - charmap.addRange(glyph_index, glyph_index, charcode); - charcode = FT_Get_Next_Char(_currentFace, charcode, &glyph_index); + FT_UInt gid; // index of current glyph + uint32_t charcode = FT_Get_First_Char(_currentFace, &gid); + while (gid) { + if (!charmap.valueAt(gid)) + charmap.addRange(gid, gid, charcode); + charcode = FT_Get_Next_Char(_currentFace, charcode, &gid); } } -/** Creates a charmap that maps from the custom character encoding to unicode. +/** Creates a charmap that maps from the custom character encoding to Unicode. * @return pointer to charmap if it could be created, 0 otherwise */ unique_ptr<const RangeMap> FontEngine::createCustomToUnicodeMap () { FT_CharMap ftcharmap = _currentFace->charmap; if (FT_Select_Charmap(_currentFace, FT_ENCODING_ADOBE_CUSTOM) != 0) return nullptr; - RangeMap index_to_source_chrcode; - buildCharMap(index_to_source_chrcode); + RangeMap gidToCharCodeMap; + buildGidToCharCodeMap(gidToCharCodeMap); if (FT_Select_Charmap(_currentFace, FT_ENCODING_UNICODE) != 0) return nullptr; auto charmap = util::make_unique<RangeMap>(); - FT_UInt glyph_index; - uint32_t unicode_point = FT_Get_First_Char(_currentFace, &glyph_index); - while (glyph_index) { - uint32_t custom_charcode = index_to_source_chrcode.valueAt(glyph_index); - charmap->addRange(custom_charcode, custom_charcode, unicode_point); - unicode_point = FT_Get_Next_Char(_currentFace, unicode_point, &glyph_index); + FT_UInt gid; // index of current glyph + uint32_t ucCharcode = FT_Get_First_Char(_currentFace, &gid); // Unicode code point + while (gid) { + uint32_t customCharcode = gidToCharCodeMap.valueAt(gid); + charmap->addRange(customCharcode, customCharcode, ucCharcode); + ucCharcode = FT_Get_Next_Char(_currentFace, ucCharcode, &gid); } FT_Set_Charmap(_currentFace, ftcharmap); return std::move(charmap); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.hpp index 5796c2b1b3e..45d9c6d3b63 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.hpp @@ -2,7 +2,7 @@ ** FontEngine.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -64,7 +64,7 @@ class FontEngine { std::string getGlyphName (const Character &c) const; int getCharByGlyphName (const char *name) const; bool setCharMap (const CharMapID &charMapID); - void buildCharMap (RangeMap &charmap); + void buildGidToCharCodeMap (RangeMap &charmap); std::unique_ptr<const RangeMap> createCustomToUnicodeMap (); protected: diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.cpp index 58d2dfc2616..33135135c1b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.cpp @@ -2,7 +2,7 @@ ** FontManager.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -101,8 +101,14 @@ int FontManager::fontnum (int id) const { int FontManager::vfFirstFontNum (const VirtualFont *vf) const { + auto it = _vfFirstFontNumMap.find(vf); + return (it == _vfFirstFontNumMap.end()) ? -1 : (int) it->second; +} + + +Font* FontManager::vfFirstFont (const VirtualFont *vf) const { auto it = _vfFirstFontMap.find(vf); - return (it == _vfFirstFontMap.end()) ? -1 : (int) it->second; + return (it == _vfFirstFontMap.end()) ? nullptr : it->second; } @@ -221,8 +227,10 @@ int FontManager::registerFont (uint32_t fontnum, const string &name, uint32_t ch else { // register font referenced in vf file const VirtualFont *vf = _vfStack.top(); _vfnum2id[vf][fontnum] = newid; - if (_vfFirstFontMap.find(vf) == _vfFirstFontMap.end()) // first fontdef of VF? - _vfFirstFontMap[vf] = fontnum; + if (_vfFirstFontNumMap.find(vf) == _vfFirstFontNumMap.end()) { // first fontdef of VF? + _vfFirstFontNumMap.emplace(vf, fontnum); + _vfFirstFontMap.emplace(vf, _fonts.back().get()); + } } return newid; } @@ -255,8 +263,6 @@ int FontManager::registerFont (uint32_t fontnum, string filename, int fontIndex, if (id >= 0) return id; - if (!filename.empty() && filename[0] == '[' && filename[filename.size()-1] == ']') - filename = filename.substr(1, filename.size()-2); string fontname = NativeFont::uniqueName(filename, style); const char *path = filename.c_str(); unique_ptr<Font> newfont; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.hpp index 2fe88bee38a..413b649169f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontManager.hpp @@ -2,7 +2,7 @@ ** FontManager.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -41,12 +41,12 @@ class VirtualFont; * we need a single list with unique IDs of all physical fonts. Characters of * virtual fonts are completely replaced by their DVI description so they don't * appear anywhere in the output. */ -class FontManager -{ - using Num2IdMap = std::unordered_map<uint32_t,int>; - using Name2IdMap = std::unordered_map<std::string,int>; - using VfNum2IdMap = std::unordered_map<const VirtualFont*,Num2IdMap>; - using VfFirstFontMap = std::unordered_map<const VirtualFont*,uint32_t>; +class FontManager { + using Num2IdMap = std::unordered_map<uint32_t, int>; + using Name2IdMap = std::unordered_map<std::string, int>; + using VfNum2IdMap = std::unordered_map<const VirtualFont*, Num2IdMap>; + using VfFirstFontNumMap = std::unordered_map<const VirtualFont*, uint32_t>; + using VfFirstFontMap = std::unordered_map<const VirtualFont*, Font*>; using VfStack = std::stack<VirtualFont*>; public: @@ -63,6 +63,7 @@ class FontManager int fontID (const std::string &name) const; int fontnum (int id) const; int vfFirstFontNum (const VirtualFont *vf) const; + Font* vfFirstFont (const VirtualFont *vf) const; void enterVF (VirtualFont *vf); void leaveVF (); void assignVFChar (int c, std::vector<uint8_t> &&dvi); @@ -77,7 +78,8 @@ class FontManager Name2IdMap _name2id; ///< fontname -> fontID VfNum2IdMap _vfnum2id; VfStack _vfStack; ///< stack of currently processed virtual fonts - VfFirstFontMap _vfFirstFontMap; ///< VF -> local font number of first font defined in VF + VfFirstFontNumMap _vfFirstFontNumMap; ///< VF -> local font number of first font defined in VF + VfFirstFontMap _vfFirstFontMap; ///< VF -> first font defined }; #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMap.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMap.cpp index 727fdd83ba8..a16d38aa2f0 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMap.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMap.cpp @@ -2,7 +2,7 @@ ** FontMap.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -162,7 +162,7 @@ bool FontMap::append (const MapLine &mapline) { if (!mapline.fontfname().empty() || !mapline.encname().empty()) { vector<Subfont*> subfonts; if (mapline.sfd()) - mapline.sfd()->subfonts(subfonts); + subfonts = mapline.sfd()->subfonts(); else subfonts.push_back(nullptr); for (Subfont *subfont : subfonts) { @@ -191,7 +191,7 @@ bool FontMap::replace (const MapLine &mapline) { vector<Subfont*> subfonts; if (mapline.sfd()) - mapline.sfd()->subfonts(subfonts); + subfonts = mapline.sfd()->subfonts(); else subfonts.push_back(nullptr); for (Subfont *subfont : subfonts) { @@ -215,7 +215,7 @@ bool FontMap::remove (const MapLine &mapline) { if (!mapline.texname().empty()) { vector<Subfont*> subfonts; if (mapline.sfd()) - mapline.sfd()->subfonts(subfonts); + subfonts = mapline.sfd()->subfonts(); else subfonts.push_back(nullptr); for (const Subfont *subfont : subfonts) { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMap.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMap.hpp index f4824aa7f16..8ed65199220 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMap.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMap.hpp @@ -2,7 +2,7 @@ ** FontMap.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMetrics.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMetrics.cpp index 7d858fea90e..b2cba248181 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMetrics.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMetrics.cpp @@ -2,7 +2,7 @@ ** FontMetrics.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMetrics.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMetrics.hpp index 66637e30444..53cafbb827d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMetrics.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontMetrics.hpp @@ -2,7 +2,7 @@ ** FontMetrics.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontStyle.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontStyle.hpp index 79a03dac367..094ba2da1f8 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontStyle.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontStyle.hpp @@ -2,7 +2,7 @@ ** FontStyle.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontWriter.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontWriter.cpp index 4dd4c5c0d8c..ad1a6dd77c0 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontWriter.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontWriter.cpp @@ -2,7 +2,7 @@ ** FontWriter.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontWriter.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontWriter.hpp index e6cad37e885..1fa5dab4db6 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontWriter.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontWriter.hpp @@ -2,7 +2,7 @@ ** FontWriter.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/GFGlyphTracer.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/GFGlyphTracer.cpp index db77ae1dc80..fc900dc6a92 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/GFGlyphTracer.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/GFGlyphTracer.cpp @@ -2,7 +2,7 @@ ** GFGlyphTracer.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/GFGlyphTracer.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/GFGlyphTracer.hpp index d0d45ffd615..2f3ed818143 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/GFGlyphTracer.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/GFGlyphTracer.hpp @@ -2,7 +2,7 @@ ** GFGlyphTracer.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/GFReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/GFReader.cpp index 4712de41d3b..3fdba80d9c2 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/GFReader.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/GFReader.cpp @@ -2,7 +2,7 @@ ** GFReader.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/GFReader.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/GFReader.hpp index e829bf8ffa8..401f89babbb 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/GFReader.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/GFReader.hpp @@ -2,7 +2,7 @@ ** GFReader.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/GFTracer.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/GFTracer.cpp index 4a3fa5e7761..408fb49d0bb 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/GFTracer.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/GFTracer.cpp @@ -2,7 +2,7 @@ ** GFTracer.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/GFTracer.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/GFTracer.hpp index e72848896df..f52ffd6cc82 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/GFTracer.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/GFTracer.hpp @@ -2,7 +2,7 @@ ** GFTracer.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp index 1ff82314ecf..bef8a68b92a 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp @@ -2,7 +2,7 @@ ** Ghostscript.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -239,10 +239,18 @@ int Ghostscript::revision () { string Ghostscript::revisionstr () { string revstr; if (int rev = revision()) { - revstr = to_string(rev/100) + "."; - if (rev % 100 < 10) - revstr += "0"; - revstr += to_string(rev%100); + if (rev < 1000) { // until GS 9.52 + revstr = to_string(rev/100) + "."; + if (rev % 100 < 10) + revstr += "0"; + revstr += to_string(rev%100); + } + else { // as of GS 9.52.1, see ghostpdl/base/gsmisc.c + int major = rev / 1000; + int minor = (rev - major*1000)/10; + int patch = rev % 10; + revstr = to_string(major) + "." + to_string(minor) + "." + to_string(patch); + } } return revstr; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.hpp index 8c9a429798d..883b42d1762 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.hpp @@ -2,7 +2,7 @@ ** Ghostscript.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Glyph.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Glyph.hpp index dfa8cb366ac..37de9bd58cb 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Glyph.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Glyph.hpp @@ -2,7 +2,7 @@ ** Glyph.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/GlyphTracerMessages.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/GlyphTracerMessages.hpp index f291d05ccce..32f4f08955d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/GlyphTracerMessages.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/GlyphTracerMessages.hpp @@ -2,7 +2,7 @@ ** GlyphTracerMessages.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/GraphicsPath.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/GraphicsPath.hpp index 565251c0d06..27d45472524 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/GraphicsPath.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/GraphicsPath.hpp @@ -2,7 +2,7 @@ ** GraphicsPath.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -732,7 +732,7 @@ class GraphicsPath { private: std::deque<CommandVariant> _commands; ///< sequence of path commands - WindingRule _windingRule; + WindingRule _windingRule = WindingRule::NON_ZERO; Point _startPoint; ///< start point of final sub-path Point _finalPoint; ///< final point reached by last command in path }; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/HashFunction.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/HashFunction.cpp index 7f99dacaf0f..bada148b6c7 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/HashFunction.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/HashFunction.cpp @@ -2,7 +2,7 @@ ** HashFunction.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -96,7 +96,7 @@ void HashFunction::update (istream &is) { string HashFunction::digestString () const { ostringstream oss; oss << hex << setfill('0'); - for (int byte : digestValue()) + for (int byte : digestBytes()) oss << setw(2) << byte; return oss.str(); } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/HashFunction.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/HashFunction.hpp index b13ee39a50c..5efbdf84684 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/HashFunction.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/HashFunction.hpp @@ -2,7 +2,7 @@ ** HashFunction.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -35,7 +35,7 @@ class HashFunction { virtual void update (const char *data, size_t length) =0; virtual void update (const std::string &data) =0; virtual void update (const std::vector<uint8_t> &data) =0; - virtual std::vector<uint8_t> digestValue () const =0; + virtual std::vector<uint8_t> digestBytes () const =0; void update (std::istream &is); std::string digestString () const; static std::vector<std::string> supportedAlgorithms (); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.cpp index 01051f9d649..dca8111405d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.cpp @@ -2,7 +2,7 @@ ** HtmlSpecialHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.hpp index e09a6d7b51b..2122ed749d5 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.hpp @@ -2,7 +2,7 @@ ** HtmlSpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.cpp index ef636c5aac0..09b48156307 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.cpp @@ -2,7 +2,7 @@ ** HyperlinkManager.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.hpp index ca8d4fd0efa..4859e0784e7 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.hpp @@ -2,7 +2,7 @@ ** HyperlinkManager.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.cpp index dfb7943a06f..6c52a0b8268 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.cpp @@ -2,7 +2,7 @@ ** ImageToSVG.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.hpp index 92a860949c1..d3da961c0eb 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.hpp @@ -2,7 +2,7 @@ ** ImageToSVG.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/InputBuffer.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/InputBuffer.cpp index b6e85f27e19..6ee562da7d0 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/InputBuffer.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/InputBuffer.cpp @@ -2,7 +2,7 @@ ** InputBuffer.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/InputBuffer.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/InputBuffer.hpp index 1474ce0a528..cc3c593e8f1 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/InputBuffer.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/InputBuffer.hpp @@ -2,7 +2,7 @@ ** InputBuffer.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/InputReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/InputReader.cpp index 074c1848227..6b5a7b70f09 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/InputReader.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/InputReader.cpp @@ -2,7 +2,7 @@ ** InputReader.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/InputReader.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/InputReader.hpp index 9825156c090..d9b697963bf 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/InputReader.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/InputReader.hpp @@ -2,7 +2,7 @@ ** InputReader.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.cpp index 7c749fd34e3..d0dd13c9b96 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.cpp @@ -2,7 +2,7 @@ ** JFM.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.hpp index 8d4a1daf213..9080212b798 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/JFM.hpp @@ -2,7 +2,7 @@ ** JFM.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.cpp index d20af5056c5..d4992c77efe 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.cpp @@ -2,7 +2,7 @@ ** Length.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.hpp index 1b0d35d35f3..f03711ecd28 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Length.hpp @@ -2,7 +2,7 @@ ** Length.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/MD5HashFunction.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/MD5HashFunction.hpp index f0eda874f23..e34db106022 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/MD5HashFunction.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/MD5HashFunction.hpp @@ -2,7 +2,7 @@ ** MD5HashFunction.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -42,7 +42,7 @@ class MD5HashFunction : public HashFunction { void update (const std::string &data) override {update(data.data(), data.length());} void update (const std::vector<uint8_t> &data) override {update(reinterpret_cast<const char*>(data.data()), data.size());} - std::vector<uint8_t> digestValue () const override { + std::vector<uint8_t> digestBytes () const override { std::vector<uint8_t> hash(16); MD5_CTX savedContext = _context; MD5_Final(hash.data(), &_context); // also erases the context structure diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am b/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am index 84ed9930757..c7e7d3e65dc 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am @@ -1,5 +1,5 @@ ## This file is part of dvisvgm -## Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> +## Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ## ## Process this file with automake. diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/MapLine.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/MapLine.cpp index cd3d8ae7ea6..5b43cd448a1 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/MapLine.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/MapLine.cpp @@ -2,7 +2,7 @@ ** MapLine.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/MapLine.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/MapLine.hpp index 9a6fa17648a..2d756653536 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/MapLine.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/MapLine.hpp @@ -2,7 +2,7 @@ ** MapLine.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Matrix.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Matrix.cpp index d0dcb2124d2..f1f2b47721f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Matrix.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Matrix.cpp @@ -2,7 +2,7 @@ ** Matrix.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Matrix.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Matrix.hpp index 154ac8a37b3..76c6e075148 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Matrix.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Matrix.hpp @@ -2,7 +2,7 @@ ** Matrix.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Message.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Message.cpp index caf8051f884..ca465adcc5b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Message.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Message.cpp @@ -2,7 +2,7 @@ ** Message.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Message.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Message.hpp index fd6f0486224..afb93d94326 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Message.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Message.hpp @@ -2,7 +2,7 @@ ** Message.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/MessageException.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/MessageException.hpp index 325e83e403f..1cfcb49e7dc 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/MessageException.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/MessageException.hpp @@ -2,7 +2,7 @@ ** MessageException.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.cpp index 11667fb5e7a..7788bef3d9c 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.cpp @@ -2,7 +2,7 @@ ** MetafontWrapper.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.hpp index 582a146aeed..4ec5afd304c 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/MetafontWrapper.hpp @@ -2,7 +2,7 @@ ** MetafontWrapper.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.cpp index 9cd02edf41f..1bbd40cae61 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.cpp @@ -2,7 +2,7 @@ ** MiKTeXCom.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.hpp index 3da270cea15..b05b26a1322 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.hpp @@ -2,7 +2,7 @@ ** MiKTeXCom.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.cpp index f5b3d7244ee..77af3d9d0c7 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.cpp @@ -2,7 +2,7 @@ ** NoPsSpecialHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.hpp index 9af3d47df5f..b4af33ab6c9 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.hpp @@ -2,7 +2,7 @@ ** NoPsSpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/NumericRanges.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/NumericRanges.hpp index 1669f7ddce2..5102b715b07 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/NumericRanges.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/NumericRanges.hpp @@ -2,7 +2,7 @@ ** NumericRanges.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PDFParser.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PDFParser.cpp index e511d4dc394..aaf50886ec1 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PDFParser.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PDFParser.cpp @@ -2,7 +2,7 @@ ** PDFParser.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PDFParser.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PDFParser.hpp index b261ee9cf7d..a342e740cdb 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PDFParser.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PDFParser.hpp @@ -2,7 +2,7 @@ ** PDFParser.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PDFToSVG.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PDFToSVG.hpp index a6c71f964b4..91792689a20 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PDFToSVG.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PDFToSVG.hpp @@ -2,7 +2,7 @@ ** PDFToSVG.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSFilter.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSFilter.hpp index 87aff89a7c9..59a4565d1de 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSFilter.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSFilter.hpp @@ -2,7 +2,7 @@ ** PSFilter.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.cpp index 038e1326f20..b82cec9b962 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.cpp @@ -2,7 +2,7 @@ ** PSInterpreter.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -256,49 +256,50 @@ void PSInterpreter::callActions (InputReader &in) { void (PSActions::*handler)(vector<double> &p); // operation handler }; static const unordered_map<string, Operator> operators { - {"applyscalevals", { 3, &PSActions::applyscalevals}}, - {"clip", { 0, &PSActions::clip}}, - {"clippath", { 0, &PSActions::clippath}}, - {"closepath", { 0, &PSActions::closepath}}, - {"curveto", { 6, &PSActions::curveto}}, - {"eoclip", { 0, &PSActions::eoclip}}, - {"eofill", { 0, &PSActions::eofill}}, - {"fill", { 0, &PSActions::fill}}, - {"grestore", { 0, &PSActions::grestore}}, - {"grestoreall", { 0, &PSActions::grestoreall}}, - {"gsave", { 0, &PSActions::gsave}}, - {"image", { 3, &PSActions::image}}, - {"initclip", { 0, &PSActions::initclip}}, - {"lineto", { 2, &PSActions::lineto}}, - {"makepattern", {-1, &PSActions::makepattern}}, - {"moveto", { 2, &PSActions::moveto}}, - {"newpath", { 1, &PSActions::newpath}}, - {"querypos", { 2, &PSActions::querypos}}, - {"raw", {-1, nullptr}}, - {"restore", { 1, &PSActions::restore}}, - {"rotate", { 1, &PSActions::rotate}}, - {"save", { 1, &PSActions::save}}, - {"scale", { 2, &PSActions::scale}}, - {"setblendmode", { 1, &PSActions::setblendmode}}, - {"setcolorspace", { 1, &PSActions::setcolorspace}}, - {"setcmykcolor", { 4, &PSActions::setcmykcolor}}, - {"setdash", {-1, &PSActions::setdash}}, - {"setgray", { 1, &PSActions::setgray}}, - {"sethsbcolor", { 3, &PSActions::sethsbcolor}}, - {"setlinecap", { 1, &PSActions::setlinecap}}, - {"setlinejoin", { 1, &PSActions::setlinejoin}}, - {"setlinewidth", { 1, &PSActions::setlinewidth}}, - {"setmatrix", { 6, &PSActions::setmatrix}}, - {"setmiterlimit", { 1, &PSActions::setmiterlimit}}, - {"setnulldevice", { 1, &PSActions::setnulldevice}}, - {"setopacityalpha",{ 1, &PSActions::setopacityalpha}}, - {"setshapealpha", { 1, &PSActions::setshapealpha}}, - {"setpagedevice", { 0, &PSActions::setpagedevice}}, - {"setpattern", {-1, &PSActions::setpattern}}, - {"setrgbcolor", { 3, &PSActions::setrgbcolor}}, - {"shfill", {-1, &PSActions::shfill}}, - {"stroke", { 0, &PSActions::stroke}}, - {"translate", { 2, &PSActions::translate}}, + {"applyscalevals", { 3, &PSActions::applyscalevals}}, + {"clip", { 0, &PSActions::clip}}, + {"clippath", { 0, &PSActions::clippath}}, + {"closepath", { 0, &PSActions::closepath}}, + {"curveto", { 6, &PSActions::curveto}}, + {"eoclip", { 0, &PSActions::eoclip}}, + {"eofill", { 0, &PSActions::eofill}}, + {"fill", { 0, &PSActions::fill}}, + {"grestore", { 0, &PSActions::grestore}}, + {"grestoreall", { 0, &PSActions::grestoreall}}, + {"gsave", { 0, &PSActions::gsave}}, + {"image", { 3, &PSActions::image}}, + {"initclip", { 0, &PSActions::initclip}}, + {"lineto", { 2, &PSActions::lineto}}, + {"makepattern", {-1, &PSActions::makepattern}}, + {"moveto", { 2, &PSActions::moveto}}, + {"newpath", { 1, &PSActions::newpath}}, + {"querypos", { 2, &PSActions::querypos}}, + {"raw", {-1, nullptr}}, + {"restore", { 1, &PSActions::restore}}, + {"rotate", { 1, &PSActions::rotate}}, + {"save", { 1, &PSActions::save}}, + {"scale", { 2, &PSActions::scale}}, + {"setblendmode", { 1, &PSActions::setblendmode}}, + {"setcolorspace", { 1, &PSActions::setcolorspace}}, + {"setcmykcolor", { 4, &PSActions::setcmykcolor}}, + {"setdash", {-1, &PSActions::setdash}}, + {"setfillconstantalpha", { 1, &PSActions::setfillconstantalpha}}, + {"setgray", { 1, &PSActions::setgray}}, + {"sethsbcolor", { 3, &PSActions::sethsbcolor}}, + {"setisshapealpha", { 1, &PSActions::setisshapealpha}}, + {"setlinecap", { 1, &PSActions::setlinecap}}, + {"setlinejoin", { 1, &PSActions::setlinejoin}}, + {"setlinewidth", { 1, &PSActions::setlinewidth}}, + {"setmatrix", { 6, &PSActions::setmatrix}}, + {"setmiterlimit", { 1, &PSActions::setmiterlimit}}, + {"setnulldevice", { 1, &PSActions::setnulldevice}}, + {"setpagedevice", { 0, &PSActions::setpagedevice}}, + {"setpattern", {-1, &PSActions::setpattern}}, + {"setrgbcolor", { 3, &PSActions::setrgbcolor}}, + {"setstrokeconstantalpha", { 1, &PSActions::setstrokeconstantalpha}}, + {"shfill", {-1, &PSActions::shfill}}, + {"stroke", { 0, &PSActions::stroke}}, + {"translate", { 2, &PSActions::translate}}, }; if (_actions) { in.skipSpace(); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.hpp index 138242abb77..71454f696e1 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.hpp @@ -2,7 +2,7 @@ ** PSInterpreter.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -66,19 +66,20 @@ struct PSActions { virtual void setcolorspace (std::vector<double> &p) =0; virtual void setcmykcolor (std::vector<double> &cmyk) =0; virtual void setdash (std::vector<double> &p) =0; + virtual void setfillconstantalpha (std::vector<double> &p) =0; virtual void setgray (std::vector<double> &p) =0; virtual void sethsbcolor (std::vector<double> &hsb) =0; + virtual void setisshapealpha (std::vector<double> &p) =0; virtual void setlinecap (std::vector<double> &p) =0; virtual void setlinejoin (std::vector<double> &p) =0; virtual void setlinewidth (std::vector<double> &p) =0; virtual void setmatrix (std::vector<double> &p) =0; virtual void setmiterlimit (std::vector<double> &p) =0; virtual void setnulldevice (std::vector<double> &p) =0; - virtual void setopacityalpha (std::vector<double> &p) =0; - virtual void setshapealpha (std::vector<double> &p) =0; virtual void setpagedevice (std::vector<double> &p) =0; virtual void setpattern (std::vector<double> &p) =0; virtual void setrgbcolor (std::vector<double> &rgb) =0; + virtual void setstrokeconstantalpha (std::vector<double> &p) =0; virtual void shfill (std::vector<double> &p) =0; virtual void stroke (std::vector<double> &p) =0; virtual void translate (std::vector<double> &p) =0; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.cpp index 4659dc7a849..135965299e6 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.cpp @@ -2,7 +2,7 @@ ** PSPattern.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.hpp index 2c53dd2b3e2..62794317c21 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPattern.hpp @@ -2,7 +2,7 @@ ** PSPattern.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.cpp index 20e8b53643d..312b3eb6def 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.cpp @@ -2,7 +2,7 @@ ** PSPreviewFilter.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.hpp index acadf9f39e8..62860b6932e 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSPreviewFilter.hpp @@ -2,7 +2,7 @@ ** PSPreviewFilter.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PageRanges.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PageRanges.cpp index 2623d2ef468..46f27078214 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PageRanges.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PageRanges.cpp @@ -2,7 +2,7 @@ ** PageRanges.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PageRanges.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PageRanges.hpp index 555338449a2..f03dfc51622 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PageRanges.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PageRanges.hpp @@ -2,7 +2,7 @@ ** PageRanges.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PageSize.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PageSize.cpp index ac8e1c52753..8b5c29445ba 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PageSize.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PageSize.cpp @@ -2,7 +2,7 @@ ** PageSize.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PageSize.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PageSize.hpp index 43c555b9dd5..4eb4e5e201f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PageSize.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PageSize.hpp @@ -2,7 +2,7 @@ ** PageSize.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Pair.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Pair.hpp index 63806c5b6af..466e6fd8f29 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Pair.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Pair.hpp @@ -2,7 +2,7 @@ ** Pair.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp index c2ab96a8a88..864ccbaa123 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp @@ -2,7 +2,7 @@ ** PapersizeSpecialHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.hpp index ed836f37d72..02599d8c32d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.hpp @@ -2,7 +2,7 @@ ** PapersizeSpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PathClipper.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PathClipper.cpp index 4aa4373f463..a36dc5d3dfc 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PathClipper.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PathClipper.cpp @@ -2,7 +2,7 @@ ** PathClipper.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -310,22 +310,37 @@ inline PolyFillType polyFillType (CurvedPath::WindingRule wr) { } -/** Computes the intersection of to curved paths. +/** Combines two curved paths by applying a boolean operation on them. + * @param[in] op operation to perform * @param[in] p1 first curved path * @param[in] p2 second curved path - * @param[out] result intersection of p1 and p2 */ -void PathClipper::intersect (const CurvedPath &p1, const CurvedPath &p2, CurvedPath &result) { - if (p1.size() < 2 || p2.size() < 2) - return; - Clipper clipper; - Polygons polygons; - flatten(p1, polygons); - clipper.AddPaths(polygons, ptSubject, true); - polygons.clear(); - flatten(p2, polygons); - clipper.AddPaths(polygons, ptClip, true); - clipper.ZFillFunction(callback); - Polygons flattenedPath; - clipper.Execute(ctIntersection, flattenedPath, polyFillType(p1.windingRule()), polyFillType(p2.windingRule())); - reconstruct(flattenedPath, result); + * @return intersection of p1 and p2 */ +CurvedPath PathClipper::combine (ClipType op, const CurvedPath &p1, const CurvedPath &p2) { + CurvedPath result; + if (p1.size() > 1 && p2.size() > 1) { + Clipper clipper; + Polygons polygons; + flatten(p1, polygons); + clipper.AddPaths(polygons, ptSubject, true); + polygons.clear(); + flatten(p2, polygons); + clipper.AddPaths(polygons, ptClip, true); + clipper.ZFillFunction(callback); + Polygons flattenedPath; + clipper.Execute(op, flattenedPath, polyFillType(p1.windingRule()), polyFillType(p2.windingRule())); + reconstruct(flattenedPath, result); + } + return result; +} + + +/** Returns the intersection of two curved paths. */ +CurvedPath PathClipper::intersect (const CurvedPath &p1, const CurvedPath &p2) { + return combine(ctIntersection, p1, p2); +} + + +/** Returns the union of two curved paths. */ +CurvedPath PathClipper::unite (const CurvedPath &p1, const CurvedPath &p2) { + return combine(ctUnion, p1, p2); } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PathClipper.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PathClipper.hpp index e3e6bd1681d..8ab9b48c4f0 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PathClipper.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PathClipper.hpp @@ -2,7 +2,7 @@ ** PathClipper.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -36,9 +36,11 @@ class PathClipper { using CurvedPath = GraphicsPath<double>; public: - void intersect (const CurvedPath &p1, const CurvedPath &p2, CurvedPath &result); + CurvedPath intersect (const CurvedPath &p1, const CurvedPath &p2); + CurvedPath unite (const CurvedPath &p1, const CurvedPath &p2); protected: + CurvedPath combine (ClipperLib::ClipType op, const CurvedPath &p1, const CurvedPath &p2); void flatten (const CurvedPath &gp, ClipperLib::Paths &polygons); void reconstruct (const ClipperLib::Path &polygon, CurvedPath &path); void reconstruct (const ClipperLib::Paths &polygons, CurvedPath &path); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.cpp index 3466e44f8ec..6368d979756 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.cpp @@ -2,7 +2,7 @@ ** PdfSpecialHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -48,7 +48,9 @@ void PdfSpecialHandler::preprocess (const string&, istream &is, SpecialActions & {"bannot", &PdfSpecialHandler::preprocessBeginAnn}, {"beginann", &PdfSpecialHandler::preprocessBeginAnn}, {"dest", &PdfSpecialHandler::preprocessDest}, - {"pagesize", &PdfSpecialHandler::preprocessPagesize} + {"pagesize", &PdfSpecialHandler::preprocessPagesize}, + {"mapfile", &PdfSpecialHandler::preprocessMapfile}, + {"mapline", &PdfSpecialHandler::preprocessMapline} }; auto it = commands.find(cmdstr); if (it != commands.end()) @@ -71,8 +73,6 @@ bool PdfSpecialHandler::process (const string&, istream &is, SpecialActions &act {"eannot", &PdfSpecialHandler::processEndAnn}, {"endann", &PdfSpecialHandler::processEndAnn}, {"dest", &PdfSpecialHandler::processDest}, - {"mapfile", &PdfSpecialHandler::processMapfile}, - {"mapline", &PdfSpecialHandler::processMapline} }; auto it = commands.find(cmdstr); if (it != commands.end()) @@ -116,7 +116,7 @@ void PdfSpecialHandler::preprocessPagesize (StreamInputReader &ir, SpecialAction } -void PdfSpecialHandler::processMapfile (StreamInputReader &ir, SpecialActions&) { +void PdfSpecialHandler::preprocessMapfile (StreamInputReader &ir, SpecialActions&) { char modechar = prepare_mode(ir); string fname = ir.getString(); if (!FontMap::instance().read(fname, modechar)) @@ -124,7 +124,7 @@ void PdfSpecialHandler::processMapfile (StreamInputReader &ir, SpecialActions&) } -void PdfSpecialHandler::processMapline (StreamInputReader &ir, SpecialActions&) { +void PdfSpecialHandler::preprocessMapline (StreamInputReader &ir, SpecialActions&) { char modechar = prepare_mode(ir); try { MapLine mapline(ir.getStream()); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.hpp index 67512dd403d..e7a18bacce2 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.hpp @@ -2,7 +2,7 @@ ** PdfSpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -38,11 +38,11 @@ class PdfSpecialHandler : public SpecialHandler { void preprocessBeginAnn (StreamInputReader &ir, SpecialActions &actions); void preprocessDest (StreamInputReader &ir, SpecialActions &actions); void preprocessPagesize (StreamInputReader &ir, SpecialActions &actions); + void preprocessMapfile (StreamInputReader &ir, SpecialActions &actions); + void preprocessMapline (StreamInputReader &ir, SpecialActions &actions); void processBeginAnn (StreamInputReader &ir, SpecialActions &actions); void processEndAnn (StreamInputReader &ir, SpecialActions &actions); void processDest (StreamInputReader &ir, SpecialActions &actions); - void processMapfile (StreamInputReader &ir, SpecialActions &actions); - void processMapline (StreamInputReader &ir, SpecialActions &actions); void dviMovedTo (double x, double y, SpecialActions &actions) override; void dviEndPage (unsigned pageno, SpecialActions &actions) override; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.cpp index 8e255ef088f..ef862f02cc3 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.cpp @@ -2,7 +2,7 @@ ** PreScanDVIReader.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.hpp index 900fd1fc015..a0e5a5fc644 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PreScanDVIReader.hpp @@ -2,7 +2,7 @@ ** PreScanDVIReader.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Process.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Process.cpp index 2e15153b9ec..2010b05db93 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Process.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Process.cpp @@ -2,7 +2,7 @@ ** Process.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Process.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Process.hpp index 53311921c90..3e9417d7bb6 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Process.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Process.hpp @@ -2,7 +2,7 @@ ** Process.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp index 2301eeb571f..fbb43f38fbe 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp @@ -2,7 +2,7 @@ ** PsSpecialHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -81,8 +81,9 @@ void PsSpecialHandler::initgraphics () { _linecap = _linejoin = 0; // butt end caps and miter joins _miterlimit = 4; _xmlnode = _savenode = nullptr; - _opacityalpha = _shapealpha = 1; // fully opaque - _blendmode = 0; // "normal" mode (no blending) + _isshapealpha = false; // opacity operators change constant component by default + _fillalpha = _strokealpha = {1, 1}; // set constant and shape opacity to non-transparent + _blendmode = 0; // "normal" mode (no blending) _sx = _sy = _cos = 1.0; _pattern = nullptr; _patternEnabled = false; @@ -555,8 +556,9 @@ void PsSpecialHandler::setpagedevice (std::vector<double> &p) { _linewidth = 1; _linecap = _linejoin = 0; // butt end caps and miter joins _miterlimit = 4; - _opacityalpha = _shapealpha = 1; // fully opaque - _blendmode = 0; // "normal" mode (no blending) + _isshapealpha = false; // opacity operators change constant component by default + _fillalpha = _strokealpha = {1, 1}; // set constant and shape opacity to non-transparent + _blendmode = 0; // "normal" mode (no blending) _sx = _sy = _cos = 1.0; _pattern = nullptr; _currentcolor = Color::BLACK; @@ -671,8 +673,8 @@ void PsSpecialHandler::stroke (vector<double> &p) { path->addAttribute("stroke-linecap", _linecap == 1 ? "round" : "square"); if (_linejoin > 0) // default value is "miter", no need to set it explicitly path->addAttribute("stroke-linejoin", _linecap == 1 ? "round" : "bevel"); - if (_opacityalpha < 1 || _shapealpha < 1) - path->addAttribute("stroke-opacity", _opacityalpha*_shapealpha); + if (_strokealpha[0] < 1 || _strokealpha[1] < 1) + path->addAttribute("stroke-opacity", _strokealpha[0] * _strokealpha[1]); if (_blendmode > 0 && _blendmode < 16) path->addAttribute("style", "mix-blend-mode:"+css_blendmode_name(_blendmode)); if (!_dashpattern.empty()) { @@ -735,8 +737,8 @@ void PsSpecialHandler::fill (vector<double> &p, bool evenodd) { } if (evenodd) // SVG default fill rule is "nonzero" algorithm path->addAttribute("fill-rule", "evenodd"); - if (_opacityalpha < 1 || _shapealpha < 1) - path->addAttribute("fill-opacity", _opacityalpha*_shapealpha); + if (_fillalpha[0] < 1 || _fillalpha[1] < 1) + path->addAttribute("fill-opacity", _fillalpha[0] * _fillalpha[1]); if (_blendmode > 0 && _blendmode < 16) path->addAttribute("style", "mix-blend-mode:"+css_blendmode_name(_blendmode)); if (_xmlnode) @@ -941,7 +943,7 @@ void PsSpecialHandler::clip (Path path, bool evenodd) { if (!_actions->getMatrix().isIdentity()) path.transform(_actions->getMatrix()); if (_clipStack.prependedPath()) - path.prepend(*_clipStack.prependedPath()); + path = PathClipper().unite(*_clipStack.prependedPath(), path); int oldID = _clipStack.topID(); @@ -954,9 +956,7 @@ void PsSpecialHandler::clip (Path path, bool evenodd) { else { // compute the intersection of the current clipping path with the current graphics path const Path *oldPath = _clipStack.path(); - Path intersectedPath(windingRule); - PathClipper clipper; - clipper.intersect(*oldPath, path, intersectedPath); + Path intersectedPath = PathClipper().intersect(*oldPath, path); pathReplaced = _clipStack.replace(intersectedPath); intersectedPath.writeSVG(oss, SVGTree::RELATIVE_PATH_CMDS); } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.hpp index 9dcbc2d4ce2..efdd5dd238f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.hpp @@ -2,7 +2,7 @@ ** PsSpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -142,19 +142,20 @@ class PsSpecialHandler : public SpecialHandler, protected PSActions { void setcolorspace (std::vector<double> &p) override {_patternEnabled = bool(p[0]);} void setcmykcolor (std::vector<double> &cmyk) override; void setdash (std::vector<double> &p) override; + void setfillconstantalpha (std::vector<double> &p) override {_fillalpha[_isshapealpha ? 1 : 0] = p[0];} void setgray (std::vector<double> &p) override; void sethsbcolor (std::vector<double> &hsb) override; + void setisshapealpha (std::vector<double> &p) override {_isshapealpha = bool(p[0]);} void setlinecap (std::vector<double> &p) override {_linecap = uint8_t(p[0]);} void setlinejoin (std::vector<double> &p) override {_linejoin = uint8_t(p[0]);} void setlinewidth (std::vector<double> &p) override {_linewidth = scale(p[0] ? p[0] : 0.5);} void setmatrix (std::vector<double> &p) override; void setmiterlimit (std::vector<double> &p) override {_miterlimit = p[0];} void setnulldevice (std::vector<double> &p) override; - void setopacityalpha (std::vector<double> &p) override {_opacityalpha = p[0];} - void setshapealpha (std::vector<double> &p) override {_shapealpha = p[0];} void setpagedevice (std::vector<double> &p) override; void setpattern (std::vector<double> &p) override; void setrgbcolor (std::vector<double> &rgb) override; + void setstrokeconstantalpha (std::vector<double> &p) override {_strokealpha[_isshapealpha ? 1 : 0] = p[0];} void shfill (std::vector<double> &p) override; void stroke (std::vector<double> &p) override; void translate (std::vector<double> &p) override; @@ -163,29 +164,30 @@ class PsSpecialHandler : public SpecialHandler, protected PSActions { private: PSInterpreter _psi; SpecialActions *_actions=nullptr; - PSPreviewFilter _previewFilter; ///< filter to extract information generated by the preview package - PsSection _psSection=PS_NONE; ///< current section processed (nothing yet, headers, or body specials) - XMLElement *_xmlnode=nullptr; ///< if != 0, created SVG elements are appended to this node - XMLElement *_savenode=nullptr; ///< pointer to temporaryly store _xmlnode - std::string _headerCode; ///< collected literal PS header code + PSPreviewFilter _previewFilter; ///< filter to extract information generated by the preview package + PsSection _psSection=PS_NONE; ///< current section processed (nothing yet, headers, or body specials) + XMLElement *_xmlnode=nullptr; ///< if != 0, created SVG elements are appended to this node + XMLElement *_savenode=nullptr; ///< pointer to temporaryly store _xmlnode + std::string _headerCode; ///< collected literal PS header code Path _path; - DPair _currentpoint; ///< current PS position in bp units - Color _currentcolor; ///< current stroke/fill color - double _sx, _sy; ///< horizontal and vertical scale factors retrieved by operator "applyscalevals" - double _cos; ///< cosine of angle between (1,0) and transform(1,0) - double _linewidth; ///< current line width in bp units - double _miterlimit; ///< current miter limit in bp units - double _opacityalpha; ///< opacity level (0=fully transparent, ..., 1=opaque) - double _shapealpha; ///< shape opacity level (0=fully transparent, ..., 1=opaque) - int _blendmode; ///< blend mode used when overlaying colored areas - uint8_t _linecap : 2; ///< current line cap (0=butt, 1=round, 2=projecting square) - uint8_t _linejoin : 2; ///< current line join (0=miter, 1=round, 2=bevel) - double _dashoffset; ///< current dash offset + DPair _currentpoint; ///< current PS position in bp units + Color _currentcolor; ///< current stroke/fill color + double _sx, _sy; ///< horizontal and vertical scale factors retrieved by operator "applyscalevals" + double _cos; ///< cosine of angle between (1,0) and transform(1,0) + double _linewidth; ///< current line width in bp units + double _miterlimit; ///< current miter limit in bp units + bool _isshapealpha; ///< if true, opacity operators act on index 1 (shape component), otherwise on index 0 (constant component) + std::array<double,2> _fillalpha; ///< constant and shape opacity used for fill operations (0=fully transparent, ..., 1=opaque) + std::array<double,2> _strokealpha; ///< constant and shape opacity used for stroke operations (0=fully transparent, ..., 1=opaque) + int _blendmode; ///< blend mode used when overlaying colored areas + uint8_t _linecap : 2; ///< current line cap (0=butt, 1=round, 2=projecting square) + uint8_t _linejoin : 2; ///< current line join (0=miter, 1=round, 2=bevel) + double _dashoffset; ///< current dash offset std::vector<double> _dashpattern; ClippingStack _clipStack; std::map<int, std::unique_ptr<PSPattern>> _patterns; - PSTilingPattern *_pattern; ///< current pattern - bool _patternEnabled; ///< true if active color space is a pattern + PSTilingPattern *_pattern; ///< current pattern + bool _patternEnabled; ///< true if active color space is a pattern }; #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/RangeMap.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/RangeMap.cpp index 86190cacf91..3d208c8a8f9 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/RangeMap.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/RangeMap.cpp @@ -2,7 +2,7 @@ ** RangeMap.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/RangeMap.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/RangeMap.hpp index 3e3bff9d4bf..3f5cb7a6e5f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/RangeMap.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/RangeMap.hpp @@ -2,7 +2,7 @@ ** RangeMap.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.cpp index f8d75a28d35..4ba6c88a7d3 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.cpp @@ -2,7 +2,7 @@ ** SVGCharHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.hpp index f75df472156..241b28b7ef8 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandler.hpp @@ -2,7 +2,7 @@ ** SVGCharHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.cpp index 397943ace09..0a4666f5ae7 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.cpp @@ -2,7 +2,7 @@ ** SVGCharHandlerFactory.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.hpp index f37b9977c24..a43257bc158 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharHandlerFactory.hpp @@ -2,7 +2,7 @@ ** SVGCharHandlerFactory.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.cpp index 7a766bae495..02f83e8c999 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.cpp @@ -2,7 +2,7 @@ ** SVGCharPathHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.hpp index c404cbcd5ab..a70bf293465 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharPathHandler.hpp @@ -2,7 +2,7 @@ ** SVGCharPathHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.cpp index 6b89348dc1a..772dee12954 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.cpp @@ -2,7 +2,7 @@ ** SVGCharTspanTextHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.hpp index b847965a1a4..0357387d6c9 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGCharTspanTextHandler.hpp @@ -2,7 +2,7 @@ ** SVGCharTspanTextHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp index 18702be7765..59a26764a7b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp @@ -2,7 +2,7 @@ ** SVGOutput.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.hpp index f29a0326743..96acf807e3e 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.hpp @@ -2,7 +2,7 @@ ** SVGOutput.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.cpp index 89d1c548b03..d61e298a017 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.cpp @@ -2,7 +2,7 @@ ** SVGSingleCharTextHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.hpp index 67fcabd44c8..57f05a4b07d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGSingleCharTextHandler.hpp @@ -2,7 +2,7 @@ ** SVGSingleCharTextHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp index e35a14d9b39..372dd28bf22 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.cpp @@ -2,7 +2,7 @@ ** SVGTree.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.hpp index a441a314a5a..84c9e111580 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGTree.hpp @@ -2,7 +2,7 @@ ** SVGTree.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/ShadingPatch.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/ShadingPatch.cpp index 847dc3aa0c7..a734c4c48b3 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/ShadingPatch.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/ShadingPatch.cpp @@ -2,7 +2,7 @@ ** ShadingPatch.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/ShadingPatch.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/ShadingPatch.hpp index 573188b77b7..2a8103d0443 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/ShadingPatch.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/ShadingPatch.hpp @@ -2,7 +2,7 @@ ** ShadingPatch.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SignalHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SignalHandler.cpp index 14badba0859..129b010d729 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SignalHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SignalHandler.cpp @@ -2,7 +2,7 @@ ** SignalHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SignalHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SignalHandler.hpp index 647a3650fc7..ef6a0a4e556 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SignalHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SignalHandler.hpp @@ -2,7 +2,7 @@ ** SignalHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SourceInput.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SourceInput.cpp index 5cd2e22749c..55196c76ce8 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SourceInput.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SourceInput.cpp @@ -2,7 +2,7 @@ ** SourceInput.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SourceInput.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SourceInput.hpp index 63f4af9b7ab..7d7a08c88fc 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SourceInput.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SourceInput.hpp @@ -2,7 +2,7 @@ ** SourceInput.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialActions.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialActions.hpp index f8eba3fd12e..12e9c90ec12 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialActions.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialActions.hpp @@ -2,7 +2,7 @@ ** SpecialActions.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialHandler.hpp index 6c676a6ba08..382f0e53d12 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialHandler.hpp @@ -2,7 +2,7 @@ ** SpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.cpp index f3b2f3aa50c..68e1c68b515 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.cpp @@ -2,7 +2,7 @@ ** SpecialManager.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.hpp index 4c4ccae2811..76cdb3e2e66 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.hpp @@ -2,7 +2,7 @@ ** SpecialManager.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/StreamReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/StreamReader.cpp index 200b6592d95..8924d885b52 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/StreamReader.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/StreamReader.cpp @@ -2,7 +2,7 @@ ** StreamReader.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/StreamReader.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/StreamReader.hpp index 653b451b698..08a4fd36361 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/StreamReader.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/StreamReader.hpp @@ -2,7 +2,7 @@ ** StreamReader.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/StreamWriter.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/StreamWriter.cpp index c0885c31b1c..21eefd1b9e1 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/StreamWriter.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/StreamWriter.cpp @@ -2,7 +2,7 @@ ** StreamWriter.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/StreamWriter.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/StreamWriter.hpp index 16a54b10501..5128bbf7365 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/StreamWriter.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/StreamWriter.hpp @@ -2,7 +2,7 @@ ** StreamWriter.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Subfont.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Subfont.cpp index eb7f244cdb6..44f3bcaeb24 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Subfont.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Subfont.cpp @@ -2,7 +2,7 @@ ** Subfont.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -97,10 +97,11 @@ Subfont* SubfontDefinition::subfont (const string &id) const { /** Returns all subfonts defined in this SFD. */ -int SubfontDefinition::subfonts (vector<Subfont*> &sfs) const { +vector<Subfont*> SubfontDefinition::subfonts () const { + vector<Subfont*> subfonts; for (const auto &strsfpair : _subfonts) - sfs.push_back(strsfpair.second.get()); - return int(sfs.size()); + subfonts.push_back(strsfpair.second.get()); + return subfonts; } ////////////////////////////////////////////////////////////////////// diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Subfont.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Subfont.hpp index 5125194e9d0..961720a99cb 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Subfont.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Subfont.hpp @@ -2,7 +2,7 @@ ** Subfont.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -43,7 +43,7 @@ class SubfontDefinition { const std::string& name() const {return _sfname;} std::string filename() const {return _sfname+".sfd";} Subfont* subfont (const std::string &id) const; - int subfonts (std::vector<Subfont*> &sfs) const; + std::vector<Subfont*> subfonts () const; const char* path () const; protected: diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/System.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/System.cpp index ed14df68211..4f8b0a139cb 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/System.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/System.cpp @@ -2,7 +2,7 @@ ** System.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/System.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/System.hpp index 72a0cb3da82..fb698d303bd 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/System.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/System.hpp @@ -2,7 +2,7 @@ ** System.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.cpp index ea6f2ecbe4e..011e659dc93 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.cpp @@ -2,7 +2,7 @@ ** TFM.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.hpp index 261a5ce736a..0bb881df8f2 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TFM.hpp @@ -2,7 +2,7 @@ ** TFM.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TTFAutohint.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/TTFAutohint.cpp index ad1b03f21a0..6e8fbefd48d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TTFAutohint.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TTFAutohint.cpp @@ -2,7 +2,7 @@ ** TTFAutohint.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TTFAutohint.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/TTFAutohint.hpp index d23ceb2be0d..3d774984c70 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TTFAutohint.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TTFAutohint.hpp @@ -2,7 +2,7 @@ ** TTFAutohint.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.cpp index dcd31e275db..8c5d7448966 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.cpp @@ -2,7 +2,7 @@ ** TensorProductPatch.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.hpp index e53604cf529..654271b90df 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TensorProductPatch.hpp @@ -2,7 +2,7 @@ ** TensorProductPatch.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.cpp index 3b2ff2b8713..274426443a1 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.cpp @@ -2,7 +2,7 @@ ** Terminal.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.hpp index fd7a920c16a..f84d47b707a 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Terminal.hpp @@ -2,7 +2,7 @@ ** Terminal.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/ToUnicodeMap.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/ToUnicodeMap.cpp index 6ab99a248eb..0a0b069e965 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/ToUnicodeMap.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/ToUnicodeMap.cpp @@ -2,7 +2,7 @@ ** ToUnicodeMap.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/ToUnicodeMap.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/ToUnicodeMap.hpp index 74d6dcb648b..806233e12f8 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/ToUnicodeMap.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/ToUnicodeMap.hpp @@ -2,7 +2,7 @@ ** ToUnicodeMap.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp index 47d3e469889..54034126db0 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp @@ -2,7 +2,7 @@ ** TpicSpecialHandler.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.hpp index f6ec271994c..8a9b458056f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.hpp @@ -2,7 +2,7 @@ ** TpicSpecialHandler.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.cpp index fadeb725ff0..76f58618396 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.cpp @@ -2,7 +2,7 @@ ** TriangularPatch.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.hpp index 797068bacd1..8d4453e5dbe 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TriangularPatch.hpp @@ -2,7 +2,7 @@ ** TriangularPatch.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TrueTypeFont.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/TrueTypeFont.cpp index 2921af59ea2..945c20bd403 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TrueTypeFont.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TrueTypeFont.cpp @@ -2,7 +2,7 @@ ** TrueTypeFont.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TrueTypeFont.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/TrueTypeFont.hpp index 0ae155c52c2..a287f305faa 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TrueTypeFont.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TrueTypeFont.hpp @@ -2,7 +2,7 @@ ** TrueTypeFont.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Unicode.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Unicode.cpp index 950209bda01..5b7fb3d2388 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Unicode.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Unicode.cpp @@ -2,7 +2,7 @@ ** Unicode.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -113,6 +113,41 @@ string Unicode::utf8 (int32_t cp) { return utf8; } + +/** Converts a surrogate pair to its code point. + * @param[in] high high-surrogate value (upper 16 bits) + * @param[in] low low-surrogate value (lower 16 bits) + * @return corresponding code point or 0 if the surrogate is invalid */ +uint32_t Unicode::fromSurrogate (uint32_t high, uint32_t low) { + if (high < 0xD800 || high > 0xDBff || low < 0xDC00 || low > 0xDFFF) + return 0; + // http://www.unicode.org/versions/Unicode3.0.0/ch03.pdf, p. 45 + return (high-0xD800)*0x400 + low-0xDC00 + 0x10000; +} + + +/** Converts a surrogate value to its code point. + * @param[in] surrogate combined high and low surrogate value + * @return corresponding code point or 0 if the surrogate is invalid */ +uint32_t Unicode::fromSurrogate (uint32_t surrogate) { + return fromSurrogate(surrogate >> 16, surrogate & 0xFFFF); +} + + +/** Converts a code point of the surrogate range (0x10000--0x10FFFF) + * to its surrogate value. + * @param[in] cp code point to convert + * @return 32-bit surrogate (combined high and low values) */ +uint32_t Unicode::toSurrogate (uint32_t cp) { + if (cp < 0x10000 || cp > 0x10FFFF) + return 0; + // http://www.unicode.org/versions/Unicode3.0.0/ch03.pdf, p. 45 + uint32_t high = (cp-0x10000)/0x400 + 0xD800; + uint32_t low = (cp-0x10000)%0x400 + 0xDC00; + return (high << 16) | low; +} + + #include "AGLTable.hpp" /** Tries to extract the codepoint from AGL character names like "uni1234" or "u1234". diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Unicode.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Unicode.hpp index bc9db7e731d..1547e3f7d40 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Unicode.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Unicode.hpp @@ -2,7 +2,7 @@ ** Unicode.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -23,11 +23,13 @@ #include <string> -struct Unicode -{ +struct Unicode { static bool isValidCodepoint (uint32_t code); static uint32_t charToCodepoint (uint32_t c); static std::string utf8 (int32_t c); + static uint32_t fromSurrogate (uint32_t high, uint32_t low); + static uint32_t fromSurrogate (uint32_t cp); + static uint32_t toSurrogate (uint32_t cp); static int32_t aglNameToCodepoint (const std::string &name); }; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/VFActions.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/VFActions.hpp index 2d4a2a2c5f5..6939d8e710e 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/VFActions.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/VFActions.hpp @@ -2,7 +2,7 @@ ** VFActions.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/VFReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/VFReader.cpp index eb1193ddaac..6533333b5ea 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/VFReader.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/VFReader.cpp @@ -2,7 +2,7 @@ ** VFReader.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/VFReader.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/VFReader.hpp index bbf4986d7f7..dabad674608 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/VFReader.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/VFReader.hpp @@ -2,7 +2,7 @@ ** VFReader.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/VectorIterator.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/VectorIterator.hpp index 0fb53d78e47..9663490a196 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/VectorIterator.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/VectorIterator.hpp @@ -2,7 +2,7 @@ ** VectorIterator.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/VectorStream.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/VectorStream.hpp index 0372d368d0e..22709803ca5 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/VectorStream.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/VectorStream.hpp @@ -2,7 +2,7 @@ ** VectorStream.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLDocument.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLDocument.cpp index ffe23b1f806..992b01f3cf0 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLDocument.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLDocument.cpp @@ -2,7 +2,7 @@ ** XMLDocument.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLDocument.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLDocument.hpp index 2eaaee4a281..c6b56452264 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLDocument.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLDocument.hpp @@ -2,7 +2,7 @@ ** XMLDocument.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp index db07d95dd2d..b71ac7e8074 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.cpp @@ -2,7 +2,7 @@ ** XMLNode.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -259,7 +259,7 @@ XMLElement* XMLElement::wrap (XMLNode *first, XMLNode *last, const string &name) XMLNode *child = first; while (child && child != last) { XMLNode *next = child->next(); - wrapper->insertLast(remove(child)); + wrapper->insertLast(detach(child)); child = next; } XMLElement *ret = wrapper.get(); @@ -277,44 +277,41 @@ XMLElement* XMLElement::wrap (XMLNode *first, XMLNode *last, const string &name) * Example: unwrap a child element b of a: * <a>text1<b><c/>text2<d/></b></a> => <a>text1<c/>text2<d/></a> * @param[in] child child element to unwrap - * @return raw pointer to the first node C1 of the unwrapped sequence */ -XMLNode* XMLElement::unwrap (XMLElement *child) { - if (!child || !child->parent()) + * @return raw pointer to the first node C1 of the unwrapped sequence or nullptr if element was empty */ +XMLNode* XMLElement::unwrap (XMLElement *element) { + if (!element || !element->parent()) return nullptr; - XMLElement *parent = child->parent()->toElement(); - auto removedChild = remove(child); - if (child->empty()) - return child->next(); - XMLNode *firstGrandchild = child->firstChild(); - XMLNode *prev = child->prev(); - unique_ptr<XMLNode> grandchild = std::move(child->_firstChild); - while (grandchild) { - prev = parent->insertAfter(std::move(grandchild), prev); - grandchild = std::move(prev->_next); - } - return firstGrandchild; -} - - -/** Removes a child node from the element. - * @param[in] child pointer to child to remove - * @return pointer to removed child or nullptr if given child doesn't belong to this element */ -unique_ptr<XMLNode> XMLElement::remove (XMLNode *child) { - unique_ptr<XMLNode> node; - if (child && child->parent()) { - XMLElement *parent = child->parent()->toElement(); - if (child == parent->_lastChild) - parent->_lastChild = child->prev(); - if (child != parent->firstChild()) - node = child->prev()->removeNext(); + XMLElement *parent = element->parent()->toElement(); + XMLNode *prev = element->prev(); + auto detachedElement = util::static_unique_ptr_cast<XMLElement>(detach(element)); + if (detachedElement->empty()) + return nullptr; + XMLNode *firstChild = detachedElement->firstChild(); + while (auto child = detach(detachedElement->firstChild())) + prev = parent->insertAfter(std::move(child), prev); + return firstChild; +} + + +/** Isolates a node and its descendants from a subtree. + * @param[in] node raw pointer to node to be detached + * @return unique pointer to the detached node. */ +unique_ptr<XMLNode> XMLElement::detach (XMLNode *node) { + unique_ptr<XMLNode> uniqueNode; + if (node && node->parent()) { + XMLElement *parent = node->parent()->toElement(); + if (node == parent->_lastChild) + parent->_lastChild = node->prev(); + if (node != parent->firstChild()) + uniqueNode = node->prev()->removeNext(); else { - node = std::move(parent->_firstChild); - if ((parent->_firstChild = std::move(node->_next))) + uniqueNode = std::move(parent->_firstChild); + if ((parent->_firstChild = std::move(uniqueNode->_next))) parent->_firstChild->prev(nullptr); } - child->parent(nullptr); + node->parent(nullptr); } - return node; + return uniqueNode; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.hpp index 534ae87bd72..ba9f68ad549 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLNode.hpp @@ -2,7 +2,7 @@ ** XMLNode.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -157,7 +157,7 @@ class XMLElement : public XMLNode { const XMLElement* toElement () const override {return this;} const Attribute* getAttribute (const std::string &name) const; - static std::unique_ptr<XMLNode> remove (XMLNode *child); + static std::unique_ptr<XMLNode> detach (XMLNode *node); static XMLElement* wrap (XMLNode *first, XMLNode *last, const std::string &name); static XMLNode* unwrap (XMLElement *child); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLString.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLString.cpp index 31de6a7b338..72026bdd767 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLString.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLString.cpp @@ -2,7 +2,7 @@ ** XMLString.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLString.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLString.hpp index 52c227ae8a4..36ef2bee55c 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLString.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/XMLString.hpp @@ -2,7 +2,7 @@ ** XMLString.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/XXHashFunction.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/XXHashFunction.hpp index e44083f1821..4478a2204cf 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/XXHashFunction.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/XXHashFunction.hpp @@ -2,7 +2,7 @@ ** XXHashFunction.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -36,6 +36,7 @@ struct XXHInterface { template<> struct XXHInterface<4> { using State = XXH32_state_t; + using Digest = XXH32_hash_t; static constexpr auto createState = &XXH32_createState; static constexpr auto freeState = &XXH32_freeState; static constexpr auto reset = &XXH32_reset; @@ -46,6 +47,7 @@ struct XXHInterface<4> { template<> struct XXHInterface<8> { using State = XXH64_state_t; + using Digest = XXH64_hash_t; static constexpr auto createState = &XXH64_createState; static constexpr auto freeState = &XXH64_freeState; static constexpr auto reset = &XXH64_reset; @@ -57,6 +59,7 @@ struct XXHInterface<8> { template<> struct XXHInterface<16> { using State = XXH3_state_t; + using Digest = XXH128_hash_t; static constexpr auto createState = &XXH3_createState; static constexpr auto freeState = &XXH3_freeState; static constexpr auto reset = &XXH3_128bits_reset_withSeed; @@ -71,7 +74,7 @@ class XXHashFunction : public HashFunction { using Interface = XXHInterface<HASH_BYTES>; public: XXHashFunction () : _state(Interface::createState()) {Interface::reset(_state, 0);} - XXHashFunction(const char *data, size_t length) : XXHashFunction() {update(data, length);} + XXHashFunction (const char *data, size_t length) : XXHashFunction() {update(data, length);} explicit XXHashFunction(const std::string &data) : XXHashFunction() {update(data);} explicit XXHashFunction(const std::vector<uint8_t> &data) : XXHashFunction() {update(data);} ~XXHashFunction () override {Interface::freeState(_state);} @@ -83,10 +86,11 @@ class XXHashFunction : public HashFunction { using HashFunction::update; // unhide update(istream &is) defined in base class - std::vector<uint8_t> digestValue () const override { + std::vector<uint8_t> digestBytes () const override { return util::bytes(Interface::digest(_state), HASH_BYTES); } + typename Interface::Digest digestValue () const {return Interface::digest(_state);} static unsigned version () {return XXH_versionNumber();} private: @@ -100,7 +104,7 @@ using XXH64HashFunction = XXHashFunction<8>; using XXH128HashFunction = XXHashFunction<16>; template<> -inline std::vector<uint8_t> XXHashFunction<16>::digestValue () const { +inline std::vector<uint8_t> XXHashFunction<16>::digestBytes () const { std::vector<uint8_t> hash; auto digest = Interface::digest(_state); for (auto chunk : {digest.high64, digest.low64}) { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/ZLibOutputStream.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/ZLibOutputStream.hpp index c1c065e3574..a995dbf01e9 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/ZLibOutputStream.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/ZLibOutputStream.hpp @@ -2,7 +2,7 @@ ** ZLibOutputStream.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp index 74a8e83abcc..15f15958353 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp @@ -2,7 +2,7 @@ ** dvisvgm.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -480,16 +480,20 @@ int main (int argc, char *argv[]) { } catch (DVIException &e) { Message::estream() << "\nDVI error: " << e.what() << '\n'; + return -1; } catch (PSException &e) { Message::estream() << "\nPostScript error: " << e.what() << '\n'; + return -2; } catch (SignalException &e) { Message::wstream().clearline(); Message::wstream(true) << "execution interrupted by user\n"; + return -3; } catch (exception &e) { Message::estream(true) << e.what() << '\n'; + return -4; } return 0; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/ffwrapper.c b/Build/source/texk/dvisvgm/dvisvgm-src/src/ffwrapper.c index 61f17fdc6dc..4f89c2b6d19 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/ffwrapper.c +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/ffwrapper.c @@ -2,7 +2,7 @@ ** ffwrapper.c ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/ffwrapper.h b/Build/source/texk/dvisvgm/dvisvgm-src/src/ffwrapper.h index e3e2f988329..6474d854a2c 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/ffwrapper.h +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/ffwrapper.h @@ -2,7 +2,7 @@ ** ffwrapper.h ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/macros.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/macros.hpp index 0a037760572..907e402c8c9 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/macros.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/macros.hpp @@ -2,7 +2,7 @@ ** macros.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.cpp index 28046e45a2e..e5f3b955367 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.cpp @@ -2,7 +2,7 @@ ** AttributeExtractor.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.hpp index b4c6f2775c3..c8ab6bd61a1 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/AttributeExtractor.hpp @@ -2,7 +2,7 @@ ** AttributeExtractor.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/DependencyGraph.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/DependencyGraph.hpp index 98d2a8d699e..912d4a91107 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/DependencyGraph.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/DependencyGraph.hpp @@ -2,7 +2,7 @@ ** DependencyGraph.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/GroupCollapser.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/GroupCollapser.cpp index b8a32786c18..47c0ac44ee5 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/GroupCollapser.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/GroupCollapser.cpp @@ -2,7 +2,7 @@ ** GroupCollapser.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -61,7 +61,7 @@ static void remove_ws_nodes (XMLElement *elem) { node = node->next(); else { XMLNode *next = node->next(); - XMLElement::remove(node); + XMLElement::detach(node); node = next; } } @@ -69,29 +69,31 @@ static void remove_ws_nodes (XMLElement *elem) { /** Recursively removes all redundant group elements from the given context element - * and moves their attributes to the corresponding parent element. + * and moves their attributes to the corresponding parent elements. * @param[in] context root of the subtree to process */ void GroupCollapser::execute (XMLElement *context) { if (!context) return; - XMLNode *node=context->firstChild(); - while (node) { - XMLNode *next = node->next(); // keep safe pointer to next node - if (XMLElement *elem = node->toElement()) - execute(elem); - node = next; - } - if (context->name() == "g" && context->attributes().empty()) { - // unwrap group without attributes - remove_ws_nodes(context); - XMLElement::unwrap(context); + + XMLNode *child=context->firstChild(); + while (child) { + XMLNode *next=child->next(); + if (XMLElement *childElement = child->toElement()) { + execute(childElement); + // check for groups without attributes and remove them + if (childElement->name() == "g" && childElement->attributes().empty()) { + remove_ws_nodes(childElement); + if (XMLNode *firstUnwrappedNode = XMLElement::unwrap(childElement)) + next = firstUnwrappedNode; + } + } + child = next; } - else { - XMLElement *child = only_child_element(context); - if (child && collapsible(*context)) { - if (child->name() == "g" && unwrappable(*child, *context) && moveAttributes(*child, *context)) { + if (XMLElement *childElement = only_child_element(context)) { + if (collapsible(*context)) { + if (childElement->name() == "g" && unwrappable(*childElement, *context) && moveAttributes(*childElement, *context)) { remove_ws_nodes(context); - XMLElement::unwrap(child); + XMLElement::unwrap(childElement); } } } @@ -147,12 +149,15 @@ bool GroupCollapser::collapsible (const XMLElement &element) { * @param[in] source element whose children and attributes should be moved * @param[in] dest element that should receive the children and attributes */ bool GroupCollapser::unwrappable (const XMLElement &source, const XMLElement &dest) { - // check for colliding clip-path attributes - if (const char *cp1 = source.getAttributeValue("clip-path")) { - if (const char *cp2 = dest.getAttributeValue("clip-path")) { - if (string(cp1) != cp2) - return false; - } + const char *cp1 = source.getAttributeValue("clip-path"); + const char *cp2 = dest.getAttributeValue("clip-path"); + if (cp2) { + // check for colliding clip-path attributes + if (cp1 && string(cp1) != string(cp2)) + return false; + // don't apply inner transformations to outer clipping paths + if (source.hasAttribute("transform")) + return false; } // these attributes prevent a group from being unwrapped static const char *attribs[] = { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/GroupCollapser.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/GroupCollapser.hpp index 08db518a90c..2694c4f3558 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/GroupCollapser.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/GroupCollapser.hpp @@ -2,7 +2,7 @@ ** GroupCollapser.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/OptimizerModule.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/OptimizerModule.hpp index 276cfa55783..91f0263bb86 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/OptimizerModule.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/OptimizerModule.hpp @@ -2,7 +2,7 @@ ** OptimizerModule.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/RedundantElementRemover.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/RedundantElementRemover.cpp index 906ccc2d144..f8d040a3299 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/RedundantElementRemover.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/RedundantElementRemover.cpp @@ -2,7 +2,7 @@ ** RedundantElementRemover.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -64,6 +64,6 @@ void RedundantElementRemover::execute (XMLElement *defs, XMLElement *context) { descendants.clear(); for (const string &str : idTree.getKeys()) { XMLElement *node = defs->getFirstDescendant("clipPath", "id", str.c_str()); - XMLElement::remove(node); + XMLElement::detach(node); } } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/RedundantElementRemover.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/RedundantElementRemover.hpp index 8d5a6b689fb..52ce905c8eb 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/RedundantElementRemover.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/RedundantElementRemover.hpp @@ -2,7 +2,7 @@ ** RedundantElementRemover.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/SVGOptimizer.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/SVGOptimizer.cpp index b2d45176e72..8f9635a8365 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/SVGOptimizer.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/SVGOptimizer.cpp @@ -2,7 +2,7 @@ ** SVGOptimizer.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -39,9 +39,9 @@ SVGOptimizer::SVGOptimizer (SVGTree *svg) : _svg(svg) { // optimizer modules available to the user; must be listed in default order // _moduleEntries.emplace_back(ModuleEntry("remove-ws", util::make_unique<WSNodeRemover>())); _moduleEntries.emplace_back(ModuleEntry("simplify-text", util::make_unique<TextSimplifier>())); + _moduleEntries.emplace_back(ModuleEntry("simplify-transform", util::make_unique<TransformSimplifier>())); _moduleEntries.emplace_back(ModuleEntry("group-attributes", util::make_unique<AttributeExtractor>())); _moduleEntries.emplace_back(ModuleEntry("collapse-groups", util::make_unique<GroupCollapser>())); - _moduleEntries.emplace_back(ModuleEntry("simplify-transform", util::make_unique<TransformSimplifier>())); _moduleEntries.emplace_back(ModuleEntry("remove-clippath", util::make_unique<RedundantElementRemover>())); } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/SVGOptimizer.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/SVGOptimizer.hpp index 0da157fbbbe..b15723d9ea4 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/SVGOptimizer.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/SVGOptimizer.hpp @@ -2,7 +2,7 @@ ** SVGOptimizer.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TextSimplifier.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TextSimplifier.cpp index b94ab9458eb..72cb0c5bb5e 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TextSimplifier.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TextSimplifier.cpp @@ -2,7 +2,7 @@ ** TextSimplifier.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TextSimplifier.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TextSimplifier.hpp index cfdd548e872..9ad3e0edb04 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TextSimplifier.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TextSimplifier.hpp @@ -2,7 +2,7 @@ ** TextSimplifier.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.cpp index 461698b62ab..ce0a6d8d7ae 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.cpp @@ -2,7 +2,7 @@ ** TransformSimplifier.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -79,8 +79,9 @@ bool TransformSimplifier::incorporateTransform (XMLElement *elem, const Matrix & if (const char *ystr = elem->getAttributeValue("y")) y = strtod(ystr, nullptr); // width and height attributes must not become negative. Hence, only apply the scaling - // values if they are non-negative. Otherwise, keep a scaling matrix - if (sx < 0 || sy < 0) { + // values if they are non-negative. Otherwise, keep a scaling matrix. Also retain scaling + // transformations in image elements to avoid the need of attribute 'preseveAspectRatio'. + if (sx < 0 || sy < 0 || elem->name() == "image") { x += (sx == 0 ? 0 : tx/sx); y += (sy == 0 ? 0 : ty/sy); elem->addAttribute("transform", "scale("+XMLString(sx)+","+XMLString(sy)+")"); @@ -120,7 +121,7 @@ static string scale_cmd (double sx, double sy) { XMLString sxstr(sx), systr(sy); if (sxstr != "1" || systr != "1") { ret = "scale("+sxstr; - if (systr != "1") + if (systr != sxstr) ret += " "+systr; ret += ')'; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.hpp index 5d503635ba2..10591dc271f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.hpp @@ -2,7 +2,7 @@ ** TransformSimplifier.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/WSNodeRemover.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/WSNodeRemover.cpp index be58bf70fde..09de2f19bbf 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/WSNodeRemover.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/WSNodeRemover.cpp @@ -2,7 +2,7 @@ ** WSNodeRemover.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -34,7 +34,7 @@ void WSNodeRemover::execute (XMLElement *context) { while (child) { if (removeWS && child->toWSNode()) { XMLNode *next = child->next(); - XMLElement::remove(child); + XMLElement::detach(child); child = next; continue; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/WSNodeRemover.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/WSNodeRemover.hpp index 8c21ce2b6e4..438c21c8fdd 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/WSNodeRemover.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/WSNodeRemover.hpp @@ -2,7 +2,7 @@ ** WSNodeRemover.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/options.dtd b/Build/source/texk/dvisvgm/dvisvgm-src/src/options.dtd index d2806badced..21c33a168a2 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/options.dtd +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/options.dtd @@ -3,7 +3,7 @@ ** options.dtd ** ** ** ** This file is part of dvisvgm - a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/options.xml b/Build/source/texk/dvisvgm/dvisvgm-src/src/options.xml index b1911694ddd..1d0d09e3d6d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/options.xml +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/options.xml @@ -3,7 +3,7 @@ ** options.xml ** ** ** ** This file is part of dvisvgm - a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -26,7 +26,7 @@ <usage>--eps [options] epsfile</usage> <usage>--pdf [options] pdffile</usage> <description>This program converts DVI files, as created by TeX/LaTeX, as well as\nEPS and PDF files to the XML-based scalable vector graphics format SVG.</description> - <copyright>Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de></copyright> + <copyright>Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de></copyright> </program> <options> <section title="Input options"> diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/psdefs.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/psdefs.cpp index 9c5991217d6..40de4677d14 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/psdefs.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/psdefs.cpp @@ -2,7 +2,7 @@ ** psdefs.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -66,88 +66,96 @@ const char *PSInterpreter::PSDEFS = "felse}put @SD/fill{@dodraw @GD/@nulldev get not and{prcolor 0 1(newpath)prcmd " "prpath 0(fill)prcmd :newpath}{:fill}ifelse}put @SD/eofill{@dodraw @GD/@nulldev" " get not and{prcolor 0 1(newpath)prcmd prpath 0(eofill)prcmd :newpath}{:eofill" -"}ifelse}put @SD/clip{:clip @GD/@nulldev get not{0 1(newpath)prcmd prpath 0(cli" -"p)prcmd}if}put @SD/eoclip{:eoclip @GD/@nulldev get not{0 1(newpath)prcmd prpat" -"h 0(eoclip)prcmd}}put @SD/shfill{begin currentdict/ShadingType known currentdi" -"ct/ColorSpace known and currentdict/DataSource known and currentdict/Function " -"known not and ShadingType 4 ge{DataSource type/arraytype eq{<</DeviceGray 1/De" -"viceRGB 3/DeviceCMYK 4/bgknown currentdict/Background known/bbknown currentdic" -"t/BBox known>>begin currentdict ColorSpace known{ShadingType ColorSpace load b" -"gknown{1 Background aload pop}{0}ifelse bbknown{1 BBox aload pop}{0}ifelse Sha" -"dingType 5 eq{VerticesPerRow}if DataSource aload length 4 add bgknown{ColorSpa" -"ce load add}if bbknown{4 add}if ShadingType 5 eq{1 add}if(shfill)prcmd}if end}" -"if}if end}put @SD/image{dup type/dicttype eq{dup}{<</Width 6 index/Height 7 in" -"dex/colorimg false>>}ifelse @execimg}put @SD/colorimage{<<2 index{/Width 2 ind" -"ex 8 add index/Height 4 index 9 add index}{/Width 8 index/Height 9 index}ifels" -"e/colorimg true>>@execimg}put/@imgbase(./)def/@imgdevice(jpeg)def/@execimg{@GD" -"/@imgcnt 2 copy .knownget{1 add}{1}ifelse put begin<</imgdev null/imgid @GD/@i" -"mgcnt get/ispng @imgdevice 0 3 getinterval(png)eq dup/suffix exch{(.png)}{(.jp" -"g)}ifelse/colorimg currentdict/colorimg .knownget dup{pop}if/colordev 1 index " -"currentcolorspace dup length 1 ne exch 0 get/DeviceGray ne or or>>begin @imgde" -"vice(png)ne @imgdevice(jpeg)ne and{@imgdevice cvn}{colordev{ispng{/png16m}{/jp" -"eg}ifelse}{ispng{/pnggray}{/jpeggray}ifelse}ifelse}ifelse dup devicedict exch " -"known{:gsave/imgdev exch finddevice def mark/OutputFile @imgbase imgid 20 stri" -"ng cvs strconcat suffix strconcat/PageSize[Width Height]/UseFastColor true isp" -"ng{@imgdevice(pngmonod)eq{/MinFeatureSize where{pop/MinFeatureSize MinFeatureS" -"ize}if}if}{/JPEGQ where{pop/JPEGQ JPEGQ}if}ifelse imgdev putdeviceprops setdev" -"ice[Width 0 0 Height neg 0 Height]/setmatrix sysexec colorimg{:colorimage}{:im" -"age}ifelse/copypage sysexec mark/OutputFile()imgdev putdeviceprops pop :gresto" -"re imgid Width Height 3(image)prcmd}{pop colorimg{:colorimage}{:image}ifelse}i" -"felse end end}def/@rect{4 -2 roll moveto exch dup 0 rlineto exch 0 exch rlinet" -"o neg 0 rlineto closepath}bind def/@rectcc{4 -2 roll moveto 2 copy 0 lt exch 0" -" lt xor{dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto}{exch dup 0 rline" -"to exch 0 exch rlineto neg 0 rlineto}ifelse closepath}bind def @SD/rectclip{:n" -"ewpath dup type/arraytype eq{aload length 4 idiv{@rectcc}repeat}{@rectcc}ifels" -"e clip :newpath}put @SD/rectfill{:gsave :newpath dup type/arraytype eq{aload l" -"ength 4 idiv{@rectcc}repeat}{@rectcc}ifelse fill :grestore}put @SD/rectstroke{" -"gsave :newpath dup type/arraytype eq{aload length 4 idiv{@rect}repeat}{@rect}i" -"felse stroke grestore}put false setglobal @SD readonly pop/initclip 0 defpr/cl" -"ippath 0 defpr/sysexec{@SD exch get exec}def/adddot{dup length 1 add string du" -"p 0 46 put dup 3 -1 roll 1 exch putinterval}def/setlinewidth{dup/setlinewidth " -"sysexec 1(setlinewidth)prcmd}def/setlinecap 1 defpr/setlinejoin 1 defpr/setmit" -"erlimit 1 defpr/setdash{mark 3 1 roll 2 copy/setdash sysexec exch aload length" -" 1 add -1 roll counttomark(setdash)prcmd pop}def/@setpagedevice{pop<<>>/setpag" -"edevice sysexec matrix setmatrix newpath 0(setpagedevice)prcmd}def/@checknulld" -"ev{@GD/@nulldev get{currentpagedevice maxlength 0 ne{@GD/@nulldev false put 0 " -"1(setnulldevice)prcmd}if}if}def/prcolor{currentcolorspace @setcolorspace curre" -"ntrgbcolor 3(setrgbcolor)prcmd}def/printgstate{@dodraw @GD/@nulldev get not an" -"d{matrix currentmatrix aload pop 6(setmatrix)prcmd applyscalevals currentlinew" -"idth 1(setlinewidth)prcmd currentlinecap 1(setlinecap)prcmd currentlinejoin 1(" -"setlinejoin)prcmd currentmiterlimit 1(setmiterlimit)prcmd prcolor currentdash " -"mark 3 1 roll exch aload length 1 add -1 roll counttomark(setdash)prcmd pop}if" -"}def/strconcat{exch dup length 2 index length add string dup dup 4 2 roll copy" -" length 4 -1 roll putinterval}def/setgstate{/setgstate sysexec printgstate}def" -"/save{@UD begin/@saveID vmstatus pop pop def end :save @saveID 1(save)prcmd}de" -"f/restore{:restore @checknulldev printgstate @UD/@saveID known{@UD begin @save" -"ID end}{0}ifelse 1(restore)prcmd}def/gsave 0 defpr/grestore{:grestore @checknu" -"lldev printgstate 0(grestore)prcmd}def/grestoreall{:grestoreall @checknulldev " -"setstate 0(grestoreall)prcmd}def/rotate{dup type/arraytype ne @dodraw and{dup " -"1(rotate)prcmd}if/rotate sysexec applyscalevals}def/scale{dup type/arraytype n" -"e @dodraw and{2 copy 2(scale)prcmd}if/scale sysexec applyscalevals}def/transla" -"te{dup type/arraytype ne @dodraw and{2 copy 2(translate)prcmd}if/translate sys" -"exec}def/setmatrix{dup/setmatrix sysexec @dodraw{aload pop 6(setmatrix)prcmd a" -"pplyscalevals}{pop}ifelse}def/initmatrix{matrix setmatrix}def/concat{matrix cu" -"rrentmatrix matrix concatmatrix setmatrix}def/makepattern{gsave<</mx 3 -1 roll" -">>begin<</XUID[1000000 @patcnt]>>copy mx/makepattern sysexec dup begin Pattern" -"Type 2 lt{PatternType @patcnt BBox aload pop XStep YStep PaintType mx aload po" -"p 15(makepattern)prcmd :newpath matrix setmatrix dup PaintProc 0 1(makepattern" -")prcmd @GD/@patcnt @patcnt 1 add put}if end end grestore}def/setpattern{begin " -"PatternType 1 eq{PaintType 1 eq{XUID aload pop exch pop 1}{:gsave[currentcolor" -"space aload length -1 roll pop]/setcolorspace sysexec/setcolor sysexec XUID al" -"oad pop exch pop currentrgbcolor :grestore 4}ifelse(setpattern)prcmd currentco" -"lorspace 0 get/Pattern ne{[/Pattern currentcolorspace]/setcolorspace sysexec}i" -"f currentcolorspace @setcolorspace}{/setpattern sysexec}ifelse end}def/setcolo" -"r{dup type/dicttype eq{setpattern}{/setcolor sysexec/currentrgbcolor sysexec s" -"etrgbcolor}ifelse}def/setcolorspace{dup/setcolorspace sysexec @setcolorspace}d" -"ef/@setcolorspace{dup type/arraytype eq{0 get}if/Pattern eq{1}{0}ifelse 1(setc" -"olorspace)prcmd}def/setgray 1 defpr/setcmykcolor 4 defpr/sethsbcolor 3 defpr/s" -"etrgbcolor 3 defpr/.setopacityalpha{dup/.setopacityalpha sysexec 1(setopacitya" -"lpha)prcmd}def/.setshapealpha{dup/.setshapealpha sysexec 1(setshapealpha)prcmd" -"}def/.setblendmode{dup/.setblendmode sysexec<</Normal 0/Compatible 0/Multiply " -"1/Screen 2/Overlay 3/SoftLight 4/HardLight 5/ColorDodge 6/ColorBurn 7/Darken 8" -"/Lighten 9/Difference 10/Exclusion 11/Hue 12/Saturation 13/Color 14/Luminosity" -" 15/CompatibleOverprint 16>>exch get 1(setblendmode)prcmd}def/@pdfpagecount{(r" -")file runpdfbegin pdfpagecount runpdfend}def/@pdfpagebox{(r)file runpdfbegin d" -"up dup 1 lt exch pdfpagecount gt or{pop}{pdfgetpage/MediaBox pget pop aload po" -"p}ifelse runpdfend}def DELAYBIND{.bindnow}if "; +"}ifelse}put/.fillstroke{:gsave fill :grestore .swapcolors stroke .swapcolors}b" +"ind def/.eofillstroke{:gsave eofill :grestore .swapcolors stroke .swapcolors}b" +"ind def @SD/clip{:clip @GD/@nulldev get not{0 1(newpath)prcmd prpath 0(clip)pr" +"cmd}if}put @SD/eoclip{:eoclip @GD/@nulldev get not{0 1(newpath)prcmd prpath 0(" +"eoclip)prcmd}if}put @SD/shfill{begin currentdict/ShadingType known currentdict" +"/ColorSpace known and currentdict/DataSource known and currentdict/Function kn" +"own not and ShadingType 4 ge{DataSource type/arraytype eq{<</DeviceGray 1/Devi" +"ceRGB 3/DeviceCMYK 4/bgknown currentdict/Background known/bbknown currentdict/" +"BBox known>>begin currentdict ColorSpace known{ShadingType ColorSpace load bgk" +"nown{1 Background aload pop}{0}ifelse bbknown{1 BBox aload pop}{0}ifelse Shadi" +"ngType 5 eq{VerticesPerRow}if DataSource aload length 4 add bgknown{ColorSpace" +" load add}if bbknown{4 add}if ShadingType 5 eq{1 add}if(shfill)prcmd}if end}if" +"}if end}put @SD/image{dup type/dicttype eq{dup}{<</Width 6 index/Height 7 inde" +"x/colorimg false>>}ifelse @execimg}put @SD/colorimage{<<2 index{/Width 2 index" +" 8 add index/Height 4 index 9 add index}{/Width 8 index/Height 9 index}ifelse/" +"colorimg true>>@execimg}put/@imgbase(./)def/@imgdevice(jpeg)def/@execimg{@GD/@" +"imgcnt 2 copy .knownget{1 add}{1}ifelse put begin<</imgdev null/imgid @GD/@img" +"cnt get/ispng @imgdevice 0 3 getinterval(png)eq dup/suffix exch{(.png)}{(.jpg)" +"}ifelse/colorimg currentdict/colorimg .knownget dup{pop}if/colordev 1 index cu" +"rrentcolorspace dup length 1 ne exch 0 get/DeviceGray ne or or>>begin @imgdevi" +"ce(png)ne @imgdevice(jpeg)ne and{@imgdevice cvn}{colordev{ispng{/png16m}{/jpeg" +"}ifelse}{ispng{/pnggray}{/jpeggray}ifelse}ifelse}ifelse dup devicedict exch kn" +"own{:gsave/imgdev exch finddevice def mark/OutputFile @imgbase imgid 20 string" +" cvs strconcat suffix strconcat/PageSize[Width Height]/UseFastColor true ispng" +"{@imgdevice(pngmonod)eq{/MinFeatureSize where{pop/MinFeatureSize MinFeatureSiz" +"e}if}if}{/JPEGQ where{pop/JPEGQ JPEGQ}if}ifelse imgdev putdeviceprops setdevic" +"e[Width 0 0 Height neg 0 Height]/setmatrix sysexec colorimg{:colorimage}{:imag" +"e}ifelse/copypage sysexec mark/OutputFile()imgdev putdeviceprops pop :grestore" +" imgid Width Height 3(image)prcmd}{pop colorimg{:colorimage}{:image}ifelse}ife" +"lse end end}def/@rect{4 -2 roll moveto exch dup 0 rlineto exch 0 exch rlineto " +"neg 0 rlineto closepath}bind def/@rectcc{4 -2 roll moveto 2 copy 0 lt exch 0 l" +"t xor{dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto}{exch dup 0 rlineto" +" exch 0 exch rlineto neg 0 rlineto}ifelse closepath}bind def @SD/rectclip{:new" +"path dup type/arraytype eq{aload length 4 idiv{@rectcc}repeat}{@rectcc}ifelse " +"clip :newpath}put @SD/rectfill{:gsave :newpath dup type/arraytype eq{aload len" +"gth 4 idiv{@rectcc}repeat}{@rectcc}ifelse fill :grestore}put @SD/rectstroke{gs" +"ave :newpath dup type/arraytype eq{aload length 4 idiv{@rect}repeat}{@rect}ife" +"lse stroke grestore}put false setglobal @SD readonly pop/initclip 0 defpr/clip" +"path 0 defpr/sysexec{@SD exch get exec}def/adddot{dup length 1 add string dup " +"0 46 put dup 3 -1 roll 1 exch putinterval}def/setlinewidth{dup/setlinewidth sy" +"sexec 1(setlinewidth)prcmd}def/setlinecap 1 defpr/setlinejoin 1 defpr/setmiter" +"limit 1 defpr/setdash{mark 3 1 roll 2 copy/setdash sysexec exch aload length 1" +" add -1 roll counttomark(setdash)prcmd pop}def/@setpagedevice{pop<<>>/setpaged" +"evice sysexec matrix setmatrix newpath 0(setpagedevice)prcmd}def/@checknulldev" +"{@GD/@nulldev get{currentpagedevice maxlength 0 ne{@GD/@nulldev false put 0 1(" +"setnulldevice)prcmd}if}if}def/prcolor{currentcolorspace @setcolorspace current" +"rgbcolor 3(setrgbcolor)prcmd}def/printgstate{@dodraw @GD/@nulldev get not and{" +"matrix currentmatrix aload pop 6(setmatrix)prcmd applyscalevals currentlinewid" +"th 1(setlinewidth)prcmd currentlinecap 1(setlinecap)prcmd currentlinejoin 1(se" +"tlinejoin)prcmd currentmiterlimit 1(setmiterlimit)prcmd prcolor currentdash ma" +"rk 3 1 roll exch aload length 1 add -1 roll counttomark(setdash)prcmd pop}if}d" +"ef/strconcat{exch dup length 2 index length add string dup dup 4 2 roll copy l" +"ength 4 -1 roll putinterval}def/setgstate{/setgstate sysexec printgstate}def/s" +"ave{@UD begin/@saveID vmstatus pop pop def end :save @saveID 1(save)prcmd}def/" +"restore{:restore @checknulldev printgstate @UD/@saveID known{@UD begin @saveID" +" end}{0}ifelse 1(restore)prcmd}def/gsave 0 defpr/grestore{:grestore @checknull" +"dev printgstate 0(grestore)prcmd}def/grestoreall{:grestoreall @checknulldev se" +"tstate 0(grestoreall)prcmd}def/rotate{dup type/arraytype ne @dodraw and{dup 1(" +"rotate)prcmd}if/rotate sysexec applyscalevals}def/scale{dup type/arraytype ne " +"@dodraw and{2 copy 2(scale)prcmd}if/scale sysexec applyscalevals}def/translate" +"{dup type/arraytype ne @dodraw and{2 copy 2(translate)prcmd}if/translate sysex" +"ec}def/setmatrix{dup/setmatrix sysexec @dodraw{aload pop 6(setmatrix)prcmd app" +"lyscalevals}{pop}ifelse}def/initmatrix{matrix setmatrix}def/concat{matrix curr" +"entmatrix matrix concatmatrix setmatrix}def/makepattern{gsave<</mx 3 -1 roll>>" +"begin<</XUID[1000000 @patcnt]>>copy mx/makepattern sysexec dup begin PatternTy" +"pe 2 lt{PatternType @patcnt BBox aload pop XStep YStep PaintType mx aload pop " +"15(makepattern)prcmd :newpath matrix setmatrix dup PaintProc 0 1(makepattern)p" +"rcmd @GD/@patcnt @patcnt 1 add put}if end end grestore}def/setpattern{begin Pa" +"tternType 1 eq{PaintType 1 eq{XUID aload pop exch pop 1}{:gsave[currentcolorsp" +"ace aload length -1 roll pop]/setcolorspace sysexec/setcolor sysexec XUID aloa" +"d pop exch pop currentrgbcolor :grestore 4}ifelse(setpattern)prcmd currentcolo" +"rspace 0 get/Pattern ne{[/Pattern currentcolorspace]/setcolorspace sysexec}if " +"currentcolorspace @setcolorspace}{/setpattern sysexec}ifelse end}def/setcolor{" +"dup type/dicttype eq{setpattern}{/setcolor sysexec/currentrgbcolor sysexec set" +"rgbcolor}ifelse}def/setcolorspace{dup/setcolorspace sysexec @setcolorspace}def" +"/@setcolorspace{dup type/arraytype eq{0 get}if/Pattern eq{1}{0}ifelse 1(setcol" +"orspace)prcmd}def/setgray 1 defpr/setcmykcolor 4 defpr/sethsbcolor 3 defpr/set" +"rgbcolor 3 defpr/.setalphaisshape{@SD/.setalphaisshape known{dup/.setalphaissh" +"ape sysexec}if{1}{0}ifelse 1(setisshapealpha)prcmd}bind def/.setfillconstantal" +"pha{@SD/.setfillconstantalpha known{dup/.setfillconstantalpha sysexec}if 1(set" +"fillconstantalpha)prcmd}bind def/.setstrokeconstantalpha{@SD/.setstrokeconstan" +"talpha known{dup/.setstrokeconstantalpha sysexec}if 1(setstrokeconstantalpha)p" +"rcmd}bind def/.setopacityalpha{false .setalphaisshape dup .setfillconstantalph" +"a .setstrokeconstantalpha}bind def/.setshapealpha{true .setalphaisshape dup .s" +"etfillconstantalpha .setstrokeconstantalpha}bind def/.setblendmode{dup/.setble" +"ndmode sysexec<</Normal 0/Compatible 0/Multiply 1/Screen 2/Overlay 3/SoftLight" +" 4/HardLight 5/ColorDodge 6/ColorBurn 7/Darken 8/Lighten 9/Difference 10/Exclu" +"sion 11/Hue 12/Saturation 13/Color 14/Luminosity 15/CompatibleOverprint 16>>ex" +"ch get 1(setblendmode)prcmd}def/@pdfpagecount{(r)file runpdfbegin pdfpagecount" +" runpdfend}def/@pdfpagebox{(r)file runpdfbegin dup dup 1 lt exch pdfpagecount " +"gt or{pop}{pdfgetpage/MediaBox pget pop aload pop}ifelse runpdfend}def DELAYBI" +"ND{.bindnow}if "; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/utility.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/utility.cpp index 8fe31fcf2dc..f702d67ce54 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/utility.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/utility.cpp @@ -2,7 +2,7 @@ ** utility.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/utility.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/utility.hpp index 7ad3bc8d690..ff8387a4190 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/utility.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/utility.hpp @@ -2,7 +2,7 @@ ** utility.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/version.hpp.in b/Build/source/texk/dvisvgm/dvisvgm-src/src/version.hpp.in index 20ba32bbd58..70d27f6e48d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/version.hpp.in +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/version.hpp.in @@ -2,7 +2,7 @@ ** version.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/windows.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/windows.hpp index 114420c3d51..5f71bbed1e4 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/windows.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/windows.hpp @@ -2,7 +2,7 @@ ** windows.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/BezierTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/BezierTest.cpp index e03e4670fe6..aa86660d840 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/BezierTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/BezierTest.cpp @@ -2,7 +2,7 @@ ** BezierTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/BitmapTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/BitmapTest.cpp index 7c12d80b353..547988bf579 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/BitmapTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/BitmapTest.cpp @@ -2,7 +2,7 @@ ** BitmapTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/BoundingBoxTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/BoundingBoxTest.cpp index 417080b5be0..15c9ae0e00c 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/BoundingBoxTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/BoundingBoxTest.cpp @@ -2,7 +2,7 @@ ** BoundingBoxTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/CMapManagerTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/CMapManagerTest.cpp index 5e4a98b9e74..2456780e4ff 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/CMapManagerTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/CMapManagerTest.cpp @@ -2,7 +2,7 @@ ** CMapManagerTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/CMapReaderTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/CMapReaderTest.cpp index 28df86bb41b..e890562f56a 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/CMapReaderTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/CMapReaderTest.cpp @@ -2,7 +2,7 @@ ** CMapReaderTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/CMapTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/CMapTest.cpp index 68a216a8988..1b95e31cce4 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/CMapTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/CMapTest.cpp @@ -2,7 +2,7 @@ ** CMapTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/CalculatorTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/CalculatorTest.cpp index af79a4c8e1c..09945222d43 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/CalculatorTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/CalculatorTest.cpp @@ -2,7 +2,7 @@ ** CalculatorTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -25,7 +25,10 @@ TEST(CalculatorTest, eval) { Calculator calc; + EXPECT_EQ(calc.eval("2"), 2); + EXPECT_EQ(calc.eval("-2"), -2); EXPECT_EQ(calc.eval("2+3+4"), 9); + EXPECT_EQ(calc.eval(" 2 + 3+ 4 "), 9); EXPECT_EQ(calc.eval("2*3+4"), 10); EXPECT_EQ(calc.eval("2+3*4"), 14); EXPECT_EQ(calc.eval("(2+3)*4"), 20); @@ -36,7 +39,11 @@ TEST(CalculatorTest, eval) { EXPECT_EQ(calc.eval("(1+2)-(3+4)"), -4); EXPECT_EQ(calc.eval("-2+3+4"), 5); EXPECT_EQ(calc.eval("3/2"), 1.5); + EXPECT_EQ(calc.eval("1+3/2"), 2.5); + EXPECT_EQ(calc.eval("3/2+1"), 2.5); EXPECT_EQ(calc.eval("3%2"), 1); + EXPECT_EQ(calc.eval("1+3%2"), 2); + EXPECT_EQ(calc.eval("3%2+1"), 2); EXPECT_EQ(calc.eval("-(4)"), -4); } @@ -51,6 +58,8 @@ TEST(CalculatorTest, variables) { calc.setVariable("b", 3); EXPECT_EQ(calc.eval("a+b"), 5); + EXPECT_EQ(calc.eval("a+a*b"), 8); + EXPECT_EQ(calc.eval("a*a+b"), 7); EXPECT_EQ(calc.eval("2a+2b"), 10); EXPECT_EQ(calc.eval("2a(1+2b)"), 28); } @@ -64,6 +73,8 @@ TEST(CalculatorTest, exceptions) { ASSERT_THROW(calc.eval("1%0"), CalculatorException); ASSERT_THROW(calc.eval("2*(3+4"), CalculatorException); ASSERT_THROW(calc.eval("2*(3+4))"), CalculatorException); + ASSERT_THROW(calc.eval("2*3+4)"), CalculatorException); + ASSERT_THROW(calc.eval("2(3+4"), CalculatorException); } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/ColorSpecialTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/ColorSpecialTest.cpp index f05393a61ab..453ba09a207 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/ColorSpecialTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/ColorSpecialTest.cpp @@ -2,7 +2,7 @@ ** ColorSpecialTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/ColorTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/ColorTest.cpp index c82d384fae2..116400ef917 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/ColorTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/ColorTest.cpp @@ -2,7 +2,7 @@ ** ColorTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/CommandLineTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/CommandLineTest.cpp index ad7b0768c20..e9149ffeb60 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/CommandLineTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/CommandLineTest.cpp @@ -2,7 +2,7 @@ ** CommandLineTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/DVIReaderTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/DVIReaderTest.cpp index e5b0ef8dc08..9998ccfbccd 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/DVIReaderTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/DVIReaderTest.cpp @@ -2,7 +2,7 @@ ** DVIReaderTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/DependencyGraphTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/DependencyGraphTest.cpp index 866d505864d..6246e357384 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/DependencyGraphTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/DependencyGraphTest.cpp @@ -2,7 +2,7 @@ ** DependencyGraphTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/DirectoryTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/DirectoryTest.cpp index b610737930a..7534cc498ca 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/DirectoryTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/DirectoryTest.cpp @@ -2,7 +2,7 @@ ** DirectoryTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/DvisvgmSpecialTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/DvisvgmSpecialTest.cpp index b8e67403aeb..c7963b290c0 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/DvisvgmSpecialTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/DvisvgmSpecialTest.cpp @@ -2,7 +2,7 @@ ** DvisvgmSpecialTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -92,10 +92,10 @@ TEST_F(DvisvgmSpecialTest, rawText) { EXPECT_TRUE(recorder.defsEquals("")); EXPECT_TRUE(recorder.pageEquals("<g id='page1'>first\n-42,14</g>")) << recorder.pageString(); - iss.clear(); iss.str("raw \t ;{?(-x+2*y-5)}second {?bbox dummy} \t"); + iss.clear(); iss.str("raw \t ;{?(-x+2*y-5)}{?(-y+2*x-5)}second {?bbox dummy} \t"); handler.process("", iss, recorder); EXPECT_TRUE(recorder.defsEquals("")); - EXPECT_TRUE(recorder.pageEquals("<g id='page1'>first\n-42,14;65second 0 0 0 0</g>")) << recorder.pageString(); + EXPECT_TRUE(recorder.pageEquals("<g id='page1'>first\n-42,14;65-103second 0 0 0 0</g>")) << recorder.pageString(); } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/EllipticalArcTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/EllipticalArcTest.cpp index 4bf4977ccaf..4e367a48044 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/EllipticalArcTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/EllipticalArcTest.cpp @@ -2,7 +2,7 @@ ** EllipticalArcTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/EmSpecialTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/EmSpecialTest.cpp index 00cc10f73c2..bfd3635b6db 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/EmSpecialTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/EmSpecialTest.cpp @@ -2,7 +2,7 @@ ** EmSpecialTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/FileFinderTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/FileFinderTest.cpp index 7ea9bce627c..a19bbb3341c 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/FileFinderTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/FileFinderTest.cpp @@ -2,7 +2,7 @@ ** FileFinderTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/FilePathTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/FilePathTest.cpp index d5b6f67d4b2..5232016f452 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/FilePathTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/FilePathTest.cpp @@ -2,7 +2,7 @@ ** FilePathTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/FileSystemTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/FileSystemTest.cpp index e5acd22b73e..93fa58c2929 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/FileSystemTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/FileSystemTest.cpp @@ -2,7 +2,7 @@ ** FileSystemTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/FontCacheTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/FontCacheTest.cpp index d0e05be49a8..ab7d20ad972 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/FontCacheTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/FontCacheTest.cpp @@ -2,7 +2,7 @@ ** FontCacheTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/FontManagerTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/FontManagerTest.cpp index 2ddb5b1064c..f2ea9b248a4 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/FontManagerTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/FontManagerTest.cpp @@ -2,7 +2,7 @@ ** FontManagerTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/FontMapTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/FontMapTest.cpp index f73dfe39bd5..8f3e512feaa 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/FontMapTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/FontMapTest.cpp @@ -2,7 +2,7 @@ ** FontMapTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/GFGlyphTracerTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/GFGlyphTracerTest.cpp index 71c08ee8e59..071bccf5c64 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/GFGlyphTracerTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/GFGlyphTracerTest.cpp @@ -2,7 +2,7 @@ ** GFGlyphTracerTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/GFReaderTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/GFReaderTest.cpp index ac582dcb29b..82c11e9eecd 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/GFReaderTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/GFReaderTest.cpp @@ -2,7 +2,7 @@ ** GFReaderTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/GhostscriptTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/GhostscriptTest.cpp index 909fc80f6ac..359d99a8bf0 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/GhostscriptTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/GhostscriptTest.cpp @@ -2,7 +2,7 @@ ** GhostscriptTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/GraphicsPathTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/GraphicsPathTest.cpp index a6af6cdc77c..625314c08d5 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/GraphicsPathTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/GraphicsPathTest.cpp @@ -2,7 +2,7 @@ ** GraphicsPathTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/HashFunctionTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/HashFunctionTest.cpp index 6b287014df3..bf56ebda2d0 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/HashFunctionTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/HashFunctionTest.cpp @@ -2,7 +2,7 @@ ** HashFunctionTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -36,7 +36,7 @@ TEST(HashFunctionTest, md5) { md5.update("0123456789"); EXPECT_EQ(md5.digestString(), "781e5e245d69b566979b86e28d23f2c7"); vector<uint8_t> bytes = {0x78, 0x1e, 0x5e, 0x24, 0x5d, 0x69, 0xb5, 0x66, 0x97, 0x9b, 0x86, 0xe2, 0x8d, 0x23, 0xf2, 0xc7}; - EXPECT_EQ(md5.digestValue(), bytes); + EXPECT_EQ(md5.digestBytes(), bytes); } @@ -51,7 +51,7 @@ TEST(HashFunctionTest, xxh32) { xxh32.update("0123456789"); EXPECT_EQ(xxh32.digestString(), "950c9c0a"); vector<uint8_t> bytes = {0x95, 0x0c, 0x9c, 0x0a}; - EXPECT_EQ(xxh32.digestValue(), bytes); + EXPECT_EQ(xxh32.digestBytes(), bytes); } @@ -66,7 +66,7 @@ TEST(HashFunctionTest, xxh64) { xxh64.update("0123456789"); EXPECT_EQ(xxh64.digestString(), "3f5fc178a81867e7"); vector<uint8_t> bytes = {0x3f, 0x5f, 0xc1, 0x78, 0xa8, 0x18, 0x67, 0xe7}; - EXPECT_EQ(xxh64.digestValue(), bytes); + EXPECT_EQ(xxh64.digestBytes(), bytes); } @@ -82,7 +82,7 @@ TEST(HashFunctionTest, xxh128) { xxh128.update("0123456789"); EXPECT_EQ(xxh128.digestString(), "e353667619ec664b49655fc9692165fb"); vector<uint8_t> bytes = {0xe3, 0x53, 0x66, 0x76, 0x19, 0xec, 0x66, 0x4b, 0x49, 0x65, 0x5F, 0xc9, 0x69, 0x21, 0x65, 0xfb}; - EXPECT_EQ(xxh128.digestValue(), bytes); + EXPECT_EQ(xxh128.digestBytes(), bytes); } #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/JFMReaderTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/JFMReaderTest.cpp index b82d00febf3..db6cb012f4b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/JFMReaderTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/JFMReaderTest.cpp @@ -2,7 +2,7 @@ ** JFMReaderTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/LengthTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/LengthTest.cpp index f6a5bca5733..4db8fe15d91 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/LengthTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/LengthTest.cpp @@ -2,7 +2,7 @@ ** LengthTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/Makefile.am b/Build/source/texk/dvisvgm/dvisvgm-src/tests/Makefile.am index 438a06b02b4..ac841563f39 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/Makefile.am +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/Makefile.am @@ -1,5 +1,5 @@ ## This file is part of dvisvgm -## Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> +## Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ## ## Process this file with automake. diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/Makefile.in b/Build/source/texk/dvisvgm/dvisvgm-src/tests/Makefile.in index e6fd46d52aa..61c6b3458e3 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/Makefile.in +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.2 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/MapLineTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/MapLineTest.cpp index 2d25c914f6c..155d133e453 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/MapLineTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/MapLineTest.cpp @@ -2,7 +2,7 @@ ** MapLineTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/MatrixTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/MatrixTest.cpp index 2858c66aa6a..8c7cb421ab1 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/MatrixTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/MatrixTest.cpp @@ -2,7 +2,7 @@ ** MatrixTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/MessageExceptionTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/MessageExceptionTest.cpp index 706921c2236..396af63ad73 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/MessageExceptionTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/MessageExceptionTest.cpp @@ -2,7 +2,7 @@ ** MessageExceptionTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/PDFParserTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/PDFParserTest.cpp index 868b04de974..39ca9ca27a4 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/PDFParserTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/PDFParserTest.cpp @@ -2,7 +2,7 @@ ** PDFParserTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/PSInterpreterTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/PSInterpreterTest.cpp index cf8f772e062..09a014c98cc 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/PSInterpreterTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/PSInterpreterTest.cpp @@ -2,7 +2,7 @@ ** PSInterpreterTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -28,48 +28,49 @@ using namespace std; class PSTestActions : public PSActions { public: - void applyscalevals (vector<double> &p) override {print("applyscalevals", p);} - void clip (vector<double> &p) override {print("clip", p);} - void clippath (vector<double> &p) override {print("clippath", p);} - void closepath (vector<double> &p) override {print("closepath", p);} - void curveto (vector<double> &p) override {print("curveto", p);} - void eoclip (vector<double> &p) override {print("eoclip", p);} - void eofill (vector<double> &p) override {print("eofill", p);} - void fill (vector<double> &p) override {print("fill", p);} - void gsave (vector<double> &p) override {print("gsave", p);} - void grestore (vector<double> &p) override {print("grestore", p);} - void grestoreall (std::vector<double> &p) override{print("grestoreall", p);} - void image (std::vector<double> &p) override {print("image", p);} - void initclip (vector<double> &p) override {print("initclip", p);} - void lineto (vector<double> &p) override {print("lineto", p);} - void moveto (vector<double> &p) override {print("moveto", p);} - void makepattern (vector<double> &p) override {print("makepattern", p);} - void setpattern (vector<double> &p) override {print("setpattern", p);} - void setpagedevice (vector<double> &p) override {print("setpagedevice", p);} - void newpath (vector<double> &p) override {print("newpath", p);} - void querypos (vector<double> &p) override {print("querypos", p);} - void restore(std::vector<double> &p) override {print("restore", p);} - void rotate (vector<double> &p) override {print("rotate", p);} - void save(std::vector<double> &p) override {print("save", p);} - void scale (vector<double> &p) override {print("scale", p);} - void setblendmode (vector<double> &p) override {print("setblendmode", p);} - void setcolorspace (vector<double> &p) override {print("setcolorspace", p);} - void setcmykcolor (vector<double> &p) override {print("setcmykcolor", p);} - void setdash (vector<double> &p) override {print("setdash", p);} - void setgray (vector<double> &p) override {print("setgray", p);} - void sethsbcolor (vector<double> &p) override {print("sethsbcolor", p);} - void setlinecap (vector<double> &p) override {print("setlinecap", p);} - void setlinejoin (vector<double> &p) override {print("setlinejoin", p);} - void setlinewidth (vector<double> &p) override {print("setlinewidth", p);} - void setmatrix (vector<double> &p) override {print("setmatrix", p);} - void setmiterlimit (vector<double> &p) override {print("setmiterlimit", p);} - void setnulldevice (vector<double> &p) override {print("setnulldevice", p);} - void setopacityalpha (vector<double> &p) override {print("setopacityalpha", p);} - void setshapealpha (vector<double> &p) override {print("setshapealpha", p);} - void setrgbcolor (vector<double> &p) override {print("setrgbcolor", p);} - void shfill (vector<double> &p) override {print("shfill", p);} - void stroke (vector<double> &p) override {print("stroke", p);} - void translate (vector<double> &p) override {print("translate", p);} + void applyscalevals (vector<double> &p) override {print("applyscalevals", p);} + void clip (vector<double> &p) override {print("clip", p);} + void clippath (vector<double> &p) override {print("clippath", p);} + void closepath (vector<double> &p) override {print("closepath", p);} + void curveto (vector<double> &p) override {print("curveto", p);} + void eoclip (vector<double> &p) override {print("eoclip", p);} + void eofill (vector<double> &p) override {print("eofill", p);} + void fill (vector<double> &p) override {print("fill", p);} + void gsave (vector<double> &p) override {print("gsave", p);} + void grestore (vector<double> &p) override {print("grestore", p);} + void grestoreall (std::vector<double> &p) override {print("grestoreall", p);} + void image (std::vector<double> &p) override {print("image", p);} + void initclip (vector<double> &p) override {print("initclip", p);} + void lineto (vector<double> &p) override {print("lineto", p);} + void moveto (vector<double> &p) override {print("moveto", p);} + void makepattern (vector<double> &p) override {print("makepattern", p);} + void setpattern (vector<double> &p) override {print("setpattern", p);} + void setpagedevice (vector<double> &p) override {print("setpagedevice", p);} + void newpath (vector<double> &p) override {print("newpath", p);} + void querypos (vector<double> &p) override {print("querypos", p);} + void restore(std::vector<double> &p) override {print("restore", p);} + void rotate (vector<double> &p) override {print("rotate", p);} + void save(std::vector<double> &p) override {print("save", p);} + void scale (vector<double> &p) override {print("scale", p);} + void setblendmode (vector<double> &p) override {print("setblendmode", p);} + void setcolorspace (vector<double> &p) override {print("setcolorspace", p);} + void setcmykcolor (vector<double> &p) override {print("setcmykcolor", p);} + void setdash (vector<double> &p) override {print("setdash", p);} + void setfillconstantalpha (vector<double> &p) override {print("setfillconstantalpha", p);} + void setgray (vector<double> &p) override {print("setgray", p);} + void sethsbcolor (vector<double> &p) override {print("sethsbcolor", p);} + void setisshapealpha (vector<double> &p) override {print("setisshapealpha", p);} + void setlinecap (vector<double> &p) override {print("setlinecap", p);} + void setlinejoin (vector<double> &p) override {print("setlinejoin", p);} + void setlinewidth (vector<double> &p) override {print("setlinewidth", p);} + void setmatrix (vector<double> &p) override {print("setmatrix", p);} + void setmiterlimit (vector<double> &p) override {print("setmiterlimit", p);} + void setnulldevice (vector<double> &p) override {print("setnulldevice", p);} + void setrgbcolor (vector<double> &p) override {print("setrgbcolor", p);} + void setstrokeconstantalpha (vector<double> &p) override {print("setstrokeconstantalpha", p);} + void shfill (vector<double> &p) override {print("shfill", p);} + void stroke (vector<double> &p) override {print("stroke", p);} + void translate (vector<double> &p) override {print("translate", p);} string result () const {return _oss.str();} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/PageRagesTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/PageRagesTest.cpp index 60b6eb77ab1..8f7effc9f88 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/PageRagesTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/PageRagesTest.cpp @@ -2,7 +2,7 @@ ** PageRagesTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/PageSizeTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/PageSizeTest.cpp index be9a25ec16d..ed997951b70 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/PageSizeTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/PageSizeTest.cpp @@ -2,7 +2,7 @@ ** PageSizeTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/PairTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/PairTest.cpp index bbff66b2f79..e5f502cdbc8 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/PairTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/PairTest.cpp @@ -2,7 +2,7 @@ ** PairTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/PapersizeSpecialTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/PapersizeSpecialTest.cpp index a4a155e8bc9..7cba1c18649 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/PapersizeSpecialTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/PapersizeSpecialTest.cpp @@ -2,7 +2,7 @@ ** PapersizeSpecialTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/RangeMapTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/RangeMapTest.cpp index 1d9f46b82f3..e9ca516d9cd 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/RangeMapTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/RangeMapTest.cpp @@ -2,7 +2,7 @@ ** RangeMapTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/SVGOutputTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/SVGOutputTest.cpp index a20dfd63cba..79f89728e16 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/SVGOutputTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/SVGOutputTest.cpp @@ -2,7 +2,7 @@ ** SVGOutputTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/ShadingPatchTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/ShadingPatchTest.cpp index 3cf6b1096b5..15e643f9773 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/ShadingPatchTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/ShadingPatchTest.cpp @@ -2,7 +2,7 @@ ** ShadingPatchTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/SpecialManagerTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/SpecialManagerTest.cpp index 156dd14f2f4..0ccaf5a1724 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/SpecialManagerTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/SpecialManagerTest.cpp @@ -2,7 +2,7 @@ ** SpecialManagerTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/SplittedCharInputBufferTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/SplittedCharInputBufferTest.cpp index 6ca61d53ed3..093b4c652ef 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/SplittedCharInputBufferTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/SplittedCharInputBufferTest.cpp @@ -2,7 +2,7 @@ ** SplittedCharInputBufferTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/StreamInputBufferTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/StreamInputBufferTest.cpp index 10124341e81..845c5f22bab 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/StreamInputBufferTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/StreamInputBufferTest.cpp @@ -2,7 +2,7 @@ ** StreamInputBufferTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/StreamReaderTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/StreamReaderTest.cpp index 864efab3b40..8a517be03c0 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/StreamReaderTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/StreamReaderTest.cpp @@ -2,7 +2,7 @@ ** StreamReaderTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/StreamWriterTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/StreamWriterTest.cpp index 05d5da2e3fa..afddcfdfc27 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/StreamWriterTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/StreamWriterTest.cpp @@ -2,7 +2,7 @@ ** StreamWriterTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/StringMatcherTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/StringMatcherTest.cpp index 89ee78fa8bd..ca3072c7d34 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/StringMatcherTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/StringMatcherTest.cpp @@ -2,7 +2,7 @@ ** StringMatcherTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/SubfontTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/SubfontTest.cpp index 609a0efe996..95a4476ef73 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/SubfontTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/SubfontTest.cpp @@ -2,7 +2,7 @@ ** SubfontTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -27,11 +27,11 @@ using namespace std; TEST(SubfontTest, collect_subfonts) { try { if (SubfontDefinition *sfd = SubfontDefinition::lookup("sample")) { - vector<Subfont*> subfonts; + vector<Subfont*> subfonts = sfd->subfonts(); const char *ids_cmp[] = {"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "x1"}; - int size = sizeof(ids_cmp)/sizeof(Subfont*); - EXPECT_EQ(sfd->subfonts(subfonts), size); - for (int i=0; i < size; i++) { + size_t size = sizeof(ids_cmp)/sizeof(Subfont*); + EXPECT_EQ(subfonts.size(), size); + for (size_t i=0; i < size; i++) { EXPECT_EQ(subfonts[i]->id(), ids_cmp[i]); } } @@ -44,7 +44,7 @@ TEST(SubfontTest, collect_subfonts) { TEST(SubfontTest, read_table) { try { - if (SubfontDefinition *sfd = SubfontDefinition::lookup("sampl")) { + if (SubfontDefinition *sfd = SubfontDefinition::lookup("sample")) { // check scanning of single value entries Subfont *subfont = sfd->subfont("02"); ASSERT_NE(subfont, nullptr); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/TFMReaderTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/TFMReaderTest.cpp index fa701f036dc..8f8da092cbe 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/TFMReaderTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/TFMReaderTest.cpp @@ -2,7 +2,7 @@ ** TFMReaderTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/TensorProductPatchTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/TensorProductPatchTest.cpp index 576ce581a8c..c31ab1a0258 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/TensorProductPatchTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/TensorProductPatchTest.cpp @@ -2,7 +2,7 @@ ** TensorProductPatchTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/ToUnicodeMapTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/ToUnicodeMapTest.cpp index a0a5ee98689..97ae10c07ea 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/ToUnicodeMapTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/ToUnicodeMapTest.cpp @@ -2,7 +2,7 @@ ** ToUnicodeMapTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/TpicSpecialTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/TpicSpecialTest.cpp index 9f88b134123..809b9a5d41c 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/TpicSpecialTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/TpicSpecialTest.cpp @@ -2,7 +2,7 @@ ** TpicSpecialTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/TriangularPatchTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/TriangularPatchTest.cpp index 86ef13fb36e..29fa437ad2e 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/TriangularPatchTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/TriangularPatchTest.cpp @@ -2,7 +2,7 @@ ** TriangularPatchTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/UnicodeTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/UnicodeTest.cpp index dc4e77d165c..4b39ec2bcea 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/UnicodeTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/UnicodeTest.cpp @@ -2,7 +2,7 @@ ** UnicodeTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -64,6 +64,40 @@ TEST(UnicodeTest, utf8) { } +TEST(UnicodeTest, fromSurrogate1) { + EXPECT_EQ(Unicode::fromSurrogate(0xd800dc00), 0x10000u); + EXPECT_EQ(Unicode::fromSurrogate(0xd83cdd10), 0x1f110u); + + // invalid surrogates + EXPECT_EQ(Unicode::fromSurrogate(0xd7ffdc00), 0u); + EXPECT_EQ(Unicode::fromSurrogate(0xdc00dc00), 0u); + EXPECT_EQ(Unicode::fromSurrogate(0xd800dbff), 0u); + EXPECT_EQ(Unicode::fromSurrogate(0xd800e000), 0u); +} + + +TEST(UnicodeTest, fromSurrogate2) { + EXPECT_EQ(Unicode::fromSurrogate(0xd800, 0xdc00), 0x10000u); + EXPECT_EQ(Unicode::fromSurrogate(0xd83c, 0xdd10), 0x1f110u); + + // invalid surrogates + EXPECT_EQ(Unicode::fromSurrogate(0xd7ff, 0xdc00), 0u); + EXPECT_EQ(Unicode::fromSurrogate(0xdc00, 0xdc00), 0u); + EXPECT_EQ(Unicode::fromSurrogate(0xd800, 0xdbff), 0u); + EXPECT_EQ(Unicode::fromSurrogate(0xd800, 0xe000), 0u); +} + + +TEST(UnicodeTest, toSurrogate) { + EXPECT_EQ(Unicode::toSurrogate(0x10000), 0xd800dc00u); + EXPECT_EQ(Unicode::toSurrogate(0x1f110), 0xd83cdd10u); + + // invalid code points + EXPECT_EQ(Unicode::toSurrogate(0xffff), 0u); + EXPECT_EQ(Unicode::toSurrogate(0x110000), 0u); +} + + TEST(UnicodeTest, aglNameToCodepoint1) { EXPECT_EQ(Unicode::aglNameToCodepoint("does not exist"), 0); EXPECT_EQ(Unicode::aglNameToCodepoint("Eogonek"), 0x118); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/UtilityTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/UtilityTest.cpp index 4ca490379f7..2e8ae696b7d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/UtilityTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/UtilityTest.cpp @@ -2,7 +2,7 @@ ** UtilityTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/VectorIteratorTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/VectorIteratorTest.cpp index 905a6fa743d..8476c9a9cc1 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/VectorIteratorTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/VectorIteratorTest.cpp @@ -2,7 +2,7 @@ ** VectorIteratorTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/VectorStreamTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/VectorStreamTest.cpp index 022b1c1fdcc..4d767bb425f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/VectorStreamTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/VectorStreamTest.cpp @@ -2,7 +2,7 @@ ** VectorStreamTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/XMLNodeTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/XMLNodeTest.cpp index 8108d88db81..d7d4159970d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/XMLNodeTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/XMLNodeTest.cpp @@ -2,7 +2,7 @@ ** XMLNodeTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/XMLStringTest.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/XMLStringTest.cpp index 18c129c4ccc..2ebe8cb0f82 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/XMLStringTest.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/XMLStringTest.cpp @@ -2,7 +2,7 @@ ** XMLStringTest.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/check-conv b/Build/source/texk/dvisvgm/dvisvgm-src/tests/check-conv index f87496762c0..a68e88e888e 100755 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/check-conv +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/check-conv @@ -2,7 +2,7 @@ # This file is part of the dvisvgm package and published under the # terms of the GNU General Public License version 3 or later. # See file COPYING for further details. -# Copyright (C) 2009-2020 Martin Gieseking <martin.gieseking@uos.de> +# Copyright (C) 2009-2021 Martin Gieseking <martin.gieseking@uos.de> files=(sample frktest) diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/data/Makefile.am b/Build/source/texk/dvisvgm/dvisvgm-src/tests/data/Makefile.am index 55818cc0c60..731b0a19c6d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/data/Makefile.am +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/data/Makefile.am @@ -1,5 +1,5 @@ ## This file is part of dvisvgm -## Copyright (C) 2016-2020 Martin Gieseking <martin.gieseking@uos.de> +## Copyright (C) 2016-2021 Martin Gieseking <martin.gieseking@uos.de> ## ## Process this file with automake. diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/data/Makefile.in b/Build/source/texk/dvisvgm/dvisvgm-src/tests/data/Makefile.in index 95c19a197ab..78c73d04c72 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/data/Makefile.in +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/data/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.2 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/genhashcheck.py b/Build/source/texk/dvisvgm/dvisvgm-src/tests/genhashcheck.py index 5f3495128ca..88a08ab671b 100755 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/genhashcheck.py +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/genhashcheck.py @@ -2,7 +2,7 @@ # This file is part of the dvisvgm package and published under the # terms of the GNU General Public License version 3 or later. # See file COPYING for further details. -# Copyright (C) 2016-2020 Martin Gieseking <martin.gieseking@uos.de> +# Copyright (C) 2016-2021 Martin Gieseking <martin.gieseking@uos.de> import re import sys diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/normalize.xsl b/Build/source/texk/dvisvgm/dvisvgm-src/tests/normalize.xsl index 2b39eba9f72..d2315118359 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/normalize.xsl +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/normalize.xsl @@ -2,7 +2,7 @@ <!-- ********************************************************************* ** Stylesheet to rearrange font-/path-elements in an SVG file. ** ** It's part of the dvisvgm package. ** -** Copyright (C) 2009-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2009-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/tests/testmain.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/tests/testmain.cpp index ce75cb56648..323b6c39159 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/tests/testmain.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/tests/testmain.cpp @@ -2,7 +2,7 @@ ** testmain.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** diff --git a/Build/source/texk/dvisvgm/version.ac b/Build/source/texk/dvisvgm/version.ac index b3c2057f1ee..4b3e400f99b 100644 --- a/Build/source/texk/dvisvgm/version.ac +++ b/Build/source/texk/dvisvgm/version.ac @@ -9,4 +9,4 @@ dnl dnl -------------------------------------------------------- dnl dnl m4-include this file to define the current dvisvgm version -m4_define([dvisvgm_version], [2.9.1]) +m4_define([dvisvgm_version], [2.11.1]) |